2015년 7월 30일 목요일

MVC Field Update in Page Editor (xEditor)

#HowTo #MVC #Ajax

 Sitecore CMS에는 Page Editor (xEditor) 그리고 Content Editor가 있다. CMS 사용자는 Page Editor에서 해당 페이지의 컨텐츠를 수정하며, 필요한 Rendering또는 Sublayout을 추가하는데, 사용자의 편의에 따라 Page Editor에서 해당 페이지의 템플릿 필드항목을 수정할때가 있다.

Sitecore는 XSLT extensions은 RenderField Pipeline를 기반으로 적용되지만, MVC에서는 "Sitecore.Web.UI.WebControls.FieldRenderer" 에서 "Render" 메써드를 지원하여, 이 메써드를 통하여, 템플릿을 Data Type을 내부적으로 캐치한다.

그러므로, MVC에서는 굳이 XSLT에서의 <sc:text ../>, <sc:image .../> 등등 Element를 선언할 필요가 없다.

아래의 코드는 Page Editor에 해당 Rendering Component의 체크박스 필드를  Droplist (Enabled/Disable options)로 구현하였으며, DropList에서 Enable이 선택되면 컴포넌트 아이템의 해당 체크박스 필드가 자동으로 체크가 되며, 반대로 Disable경우 해당 필드의 체크가 없어진다.

Model


public class ComponentModel : IRenderingModel
{
    public string Title { get; set; }
    public Item Item { get; set; }
    public Item PageItem { get; set; }
    public Sitecore.Data.Fields.CheckboxField chBox { get; set; }
    ... some other declared data types based on templates if you want ...

    public void Initialize(Sitecore.Mvc.Presentation.Rendering rendering)
    {
        Rendering = rendering;
        Item = rendering.Item;
        PageItem = Sitecore.Mvc.Presentation.PageContext.Current.Item;

        Title = FieldRenderer.Render(Item, "Title");
        ... more if you want ...
    }
}

Controller


public class Components : Controller
{
    //
    // POST: /Components/

    public ActionResult ComponentView(string changedValue, string fieldName)
    {

        ComponentModel ss = new ComponentModel();
        ss.Initialize(RenderingContext.Current.Rendering);
        Item item = ss.Item;

        if (!String.IsNullOrEmpty(changedValue) && !String.IsNullOrEmpty(fieldName))
        {
            ss.Item.Editing.BeginEdit();
            using (new SecurityDisabler())
            {
                switch (fieldName)
                {
                    ... conditions ...
                }
            }
            ss.Item.Editing.EndEdit();
        }
        return PartialView(ss);
    }
}

View


@model yournamespace.ComponentModel
@using Sitecore.Mvc

@if (Sitecore.Context.PageMode.IsPageEditor)
{  
    if (!@Sitecore.Data.ID.IsID(Model.Rendering.DataSource))
    {
        <div>No Associated Datasource.<br />Please Create New Datasource</div><br />
    }
    else
    {
        <div class="newdata">
            <h3>This is page editor</h3>
            Title: @Html.Raw(Model.Title) <br />

            DropList: <select name="list" id="fieldName" onclick="javascript:dlOnChangeUpdate('fieldName');">
                <option value="True" @Html.Raw((Model.chBox.Checked) ? "selected" : "")>Enable</option>
                <option value="False" @Html.Raw((!Model.chBox.Checked) ? "selected" : "")>Disable</option>
            </select><br />

            <script type="text/javascript">
                function dlOnChangeUpdate(fieldName)
                {
                    $("#" + fieldName).on('change', function () {
                        var changedValue = $("#" + fieldName).val();

                        $.ajax({
                            url: '@Url.Action("ComponentModel","Components")',
                            type: "POST",
                            data: { "changedValue": changedValue, "fieldName": fieldName },
                            context: this,
                            success: function (data) {
                                Sitecore.PageModes.PageEditor.postRequest('webedit:save()');
                                console.log("success", data);
                            },
                            error: function (data) {
                                alert('error: ' + data);
                                console.log("error", data);
                            }
                        });
                    });
                }
            </script>
        </div>
    }
}
else
{
    <div id="info">
        <h3>This is preview</h3>
    </div>
}

2015년 7월 28일 화요일

템플릿 필드 업데이트 ItemEditing

#HowTo #Template

 사이트코어를 사용하다 보면은 프로그램상으로 해당 페이지 또는 Sublayout/Rendering component의 템플릿 필드 값을 업데이트 해야하는 경우가 있다.

Sitecore.Data.Items.ItemEditing


아래의 코드는:

  • 아이템 저장
  • 업데이트 아이템 정보 (수정날짜, 에디터 및 통계정보)
  • 아이템 저장과 관련된 이벤트를 실행한다


Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
Sitecore.Data.Items.Item path = master.GetItem("/sitecore/content/the/path/you/want/to/get");

//Begin Editing Sitecore Item
path.Editing.BeginEdit();
try
{
    path["fieldName"] = "This is updated value";

    // This will commit the field value
    path.Editing.EndEdit();
}
catch (Exception)
{
    //Revert the Changes
    path.Editing.CancelEdit();
}


Sitecore.Data.Items.EditContext


아래의 코드는 윗 코드와 달리, 선택적으로 통계정보를 업데이트할수있으며, 또한 파라미터를 전달하는데 있어서 보안체크 또한 가능하다.


Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
Sitecore.Data.Items.Item path = master.GetItem("/sitecore/content/the/path/you/want/to/get");

//Enable or disable statistics information
bool updateStatistics = false;  

//Temporary enable or disable events
bool silent = true;

//Begin Editing Sitecore Item
path.Editing.BeginEdit();
using (new EditContext(path, updateStatistics, silent))
{
    path["fieldName"] = "This is updated value";
}
path.Editing.EndEdit();


Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
Sitecore.Data.Items.Item path = master.GetItem("/sitecore/content/the/path/you/want/to/get");

// Disable security check
path.Editing.BeginEdit();
using (new EditContext(path, SecurityCheck.Disable))  
{  
    path["fieldName"] = "This is updated value";  
}  
path.Editing.EndEdit();