2015년 12월 18일 금요일

Telerik에 새로운 명령어 추가하기

#HowTo #Javascript #RichTextCommands #Telerik

 Telerik은 자바스크립트를 이용하여 에디터의 커맨드를 불러온다.
먼저 자바스크립트의 경로는 "\sitecore\shell\Controls\Rich Text Editor\RichText Commands.js"이며, 커맨드 리스트를 통하여 새로운 버튼을 추가할수가 있다.

첫번째로, Core DB에서 "/setting/HTML Editor Profile"에서 새로운 Profile을 만든 후 버턴 아이템을 만들어준다. "Click" 값은 반드시 Unique한 값을 지정하며, 커맨드 리스트에 추가될 값과 일치하여야한다.
















다음 단계로 "RichText Command.js" 파일에 리스트를 추가한다.

1
2
3
4
5
6
7
8
9
RadEditorCommandList["Button Generator"] = function (commandName, editor, args) {
    var d = Telerik.Web.UI.Editor.CommandList._getLinkArgument(editor);
    Telerik.Web.UI.Editor.CommandList._getDialogArguments(d, "A", editor, "DocumentManager");

    //Retrieve the html selected in the editor
    var html = editor.getSelectionHtml();
    scEditor = editor;
    scEditor.pasteHtml("버턴을 클릭하면 메세지가 출력된다.");
};

Telerik's RichText Editor

#FYI #RichTextEditorProfile

 Sitecore는 Telerik 플랫폼을 통하여 RichTextEditor를 제공하한다. 템플릿에 Rich Text 데이터 타입을 선택하면 에디터를 사용할수있으며, Core 데이타베이스의 HtmlEditor Profile을 통하여 에디터의 HTML 기능을 추가할수가있다.

추가적으로, source경로가 비어있다면 기본값은 RTE Default로 적용되면, 이는 web.config 파일에서 설정할수가 있다.


1
<setting name="HtmlEditor.DefaultProfile" value="/sitecore/system/Settings/Html Editor Profiles/Rich Text Default" />


Screenshot of template with source filled in rich text field.
Fig 1. Data field in template and set source location (HTML Profile Location)




Fig 2. RTE Default





Fig 3. RTE Medium






Fig 4. RTE Full

2015년 10월 26일 월요일

SPEAK UI는 무엇인가?

#FYI #SPEAK #XSLT

 SPEAK UI는 무엇인가?

Sitecore는 버전 6.6부터 SPEAK(Sitecore Process Enablement and Acceleration Kit) UI를 CMS 추가하기 시작하였다. 부분적으로, 기존에 사용하고있던 Sheer UI의 약점(?)을 보완하기 위하여 시작하였으며, 개발자에게 있어서 어플리케이션을 만드는데 더 유연하게 사용할수있도록 설계가 되어있다.

기존의 Sheer UI는 XSLT기기반으로 코드는 aspx/ascx/xml 등으로 만들어져있으며, 부분적으로 플래쉬 파일(.swf)을 렌더링하여 유저에게 인터페이스를 제공한다. 다시 말하면, Sheer UI를 업데이트하는데 있어서, 많은 리소스가 필요할뿐더러 개발자로써도 수정을 많은 어려움을 있을수있다. 하지만 SPEAK UI는 MVC기반으로 만들어졌으며, 인터페이스는 Javascript를 이용하여 유저의 Request를 실행한다. 추가적으로 /App_Config/Inlcue/ 폴더에서 "Sitecore.Speak.Applications.config" 파일을 수정하여 SPEAK UI를 Disable 할수가 있다.

2015년 10월 14일 수요일

미디어 아이템 렌더링

#FYI #HowTo #.NET

 먼저, 렌더링 아이템의 미디어 정보를 가져오는 중, 아주 유용한 정보를 찾았다. 아래는 Muhammad Jameel 블로그에서 가져온것이다.

Create an object for the target item in the database- replace itempath with the relative path to the item in the Content Tree, such as “home/about/item1” or start the path with a backslash (/) to indicate an absolute path, such as “/sitecore/content/home/about/item1”– a null value will be set in either case if the item does not exist - Sitecore does compare case when evaluating item paths.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Sitecore.Data.Database db = Sitecore.Context.Database;
Sitecore.Data.Items.Item item = db.GetItem("itempath");
Sitecore.Data.Fields.ImageField image = item.Fields["imagefield"];
if (image!=null && image.MediaItem!=null)
{
      Sitecore.Data.Items.MediaItem image = new Sitecore.Data.Items.MediaItem(imageField.MediaItem);
      string src = Sitecore.StringUtil.EnsurePrefix('/', Sitecore.Resources.Media.MediaManager.GetMediaUrl(image));
      if (!string.IsNullOrEmpty(src))
      {
             string imgTag = String.Format(@"<img src=""{0}"" alt=""{1}"" />", src, image.Alt);
      }
}

2015년 9월 29일 화요일

자바스크립트를 통하여 Item 업데이트 하기

#HowTo #Javascript #WebEdit

 Sitecore에서는 자바스크립트를 통하여 Sitecore.Client 또는 Sitecore.Kernel에 포함되어진 Class의 Method를 실행할 수 가 있다.

Sitecore Website폴더에서 /Website/App_Config/ 폴더를 보면 Command.config 파일이 있는데, 해당 파일을 열어보면 각각 커맨드에 해당되는 Assembly와 네임스페이스를 포함하고 있다. 해당 컨맨드 목록을 여기를 참고한다. https://github.com/udt1106/Sitecore-Item-Buckets/blob/master/Sitecore.ItemBucket.Tests/App_Config/Commands.config

먼저 내가 자주 사용하고 Command는 save, new, delete 등등이 있는데, 기본적인 사용법은:


1
2
3
<a href="#" onclick="javascript:Sitecore.PageModes.PageEditor.postRequest('webedit:save()')">Save current item</a>
<a href="#" onclick="javascript:Sitecore.PageModes.PageEditor.postRequest('webedit:delete()')">Delete current item</a>
<a href="#"  onclick="javascript:Sitecore.PageModes.PageEditor.postRequest('webedit:fieldeditor(command={11111111-1111-1111-1111-111111111111},fields=Field Name 1|Field Name 2,id={item-id-to-edit-with-braces})')">Edit Fields</a>

자바스크립트를 통하여 페이지 감지

#HowTo #DetectMode

 Sitecore에서는 자바스크립트를 통하여 Code-behind에서 선언할수있는 클래스의 method들을 실행할수가 있다. 기본적으로 code-behind에서 현재 페이지가 Page Editor인지 아니면 Preview mode인지 확인하는 방법은,


1
2
3
4
5
if (Sitecore.Context.PageMode.IsPageEditor) {
    // this is page page editor
} else if (Sitecore.Context.PageMode.IsPreview) {
    // this is preview
}


이것과 같은 방법으로 자바스크립트를 통하여 현재 페이지를 Detect할 수 가있다.


1
2
3
4
5
6
7
var isPageEditor = function(){
    return !!(Sitecore && Sitecore.PageModes && Sitecore.PageModes.PageEditor);
};

if(isPageEditor()) {
    // this is PageEditor
}

2015년 9월 2일 수요일

Sitecore PowerShell Script

#HowTo #PowerShell

 이번에는 Sitecore PowerShell Script에 관한여 소개해보겠다.

페이지 템플릿 또는 아이템의 필드 템플릿 값을 변경해야할경우, 간혹 많이 아이템을 하나하나씩 들어가 업데이트 해야하는 경우가 있다. 이럴경우 많은 시간이 소비될 뿐아니라 페이지를 만들고 업데이트하는 과정에서 Best Practice라고 할수가 없다.

이럴경우, 두가지 옵션이 있는데, 첫번째는 템플릿의 Standard Value를 리셋하는 것이고, 두번째는 Sitecore PowerShell의 스크립트를 통하여 변경하고 싶은 아이템의 값을 모두 업데이트하는것이다. 첫번째의 경우 가장 간편하고 안전한 업데이트라고 할수있으나, 만약 템들릿이 많은 필드 타입을 가지고 있고, __Standard Value를 통하여 만들어진 아이템이 아니라면 곤란하다.

이럴경우 두번째 옵션을 선택하는데, 아래는 선택되어진 Context 아이템에 Workflow 필드를 없데이트 하는것이다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
######################################################################
##  1. 먼저 default workflow state 세팅한다                          ##
##  2. 스크립트를 실행하기전 반드시 아이템의 아이디가 정확한지 확인하다  ##
######################################################################

function SetWorkflow($item)
{
    ## Update only items assigned __Default workflow
    if ($item."__Default workflow" -eq "{A5BC37E7-ED96-4C1E-8590-A26E64DB55EA}") {
        $item.__Workflow = "{A5BC37E7-ED96-4C1E-8590-A26E64DB55EA}";
        $item."__Workflow state" = "{190B1C84-F1BE-47ED-AA41-F42193D9C8FC}";
    }
}

## Update correct workflow information.
get-item . -Language * | foreach-object { SetWorkFlow($_) }
get-childitem . -recurse -Language * | foreach-object { SetWorkFlow($_) }

## Show Updated Result
get-item . -Language * | Format-Table Id, Name, Language, __Workflow, "__Workflow state", "__Default workflow"
get-childitem . -recurse -Language * | Format-Table Id, Name, Language, __Workflow, "__Workflow state", "__Default workflow"


아래는 이런문제때문에 StackworkFlow에 질문하여 답변한 링크이다.
http://stackoverflow.com/questions/29263398/sitecore-workflow-is-not-working/29286256#29286256

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(); 

2015년 6월 30일 화요일

MVC 아이템 필드 정보 가져오기

#FYI #Html.Sitecore #MVC

 사이트코어는 현재 새로운 버전을 업데이트하면서 MVC Concept을 많이 보완하고 있으면 추가적인 기능을 (Class) 업데이트 하고 있다.

사이트코어에서 기본적으로 제공하는 라이브러리를 사용함으로써, 현재 아이템에 대한 정보를 가져올수있다.

Model.Item 은 현재 Context 아이템의 정보를 데이터소스로써 가져올수가 있다.

@Html.Sitecore().Field("필드명", 데이타소스 정보, 추가적인 오브젝트 })

예: @Html.Sitecore().Field("__Updated", Model.Item, new { format = "dd/mm/yyyy" })

2015년 5월 27일 수요일

페이지 에디터 (xEditor)에 버전정보 생성하기

#FYI #Version

 사이트코어는 해당 아이템에 Workflow를 세팅했다면, 버전 트랙 및 이전에 수정하였던 정보를 복구시킬수가 있다.
하지만, 해당된 아이템의 버전정보는 "Content Editor"에서는 쉽게 찾을수 있지만, "Page Editor" 혹은 "xEditor"에서는 버전정보를 볼수가 없다.

이럴 경우, "Content Editor" 페이지에 있는 버전 정보를 "Page Editor"의 Ribbon 버전으로 만들수가 있다.


  1. CMS 데스크탑 모드에서 "Core" 데이타베이스로 이동을 한다.
  2. "/sitecore/content/Applications/WebEdit/Ribbons/WebEdit/Experience/" 이동
  3. "Versions" 라는 새로운 아이뎀을 만든다.  (이미지에 보여진 템플릿을 적용시킬것)

  4. "Compare" 이라는 새로운 아이템을 새로 만든 "Versions" 아이템의 Child 아이템으로 만든다. (이미지에 보여진 템플릿을 적용시킬것)

  5. 결과




"Page Editor"에서 Compare 기능을 통하여, 버전정보와 업데이트된 정보를 확인할수 있다.

2015년 4월 28일 화요일

Workflow Related Item 업데이트 하기

#HowTo #Workflow #FYI

 이번에 회사에서 사이트코어 workflow세팅을 재수정하기로 하였다. 사이트코어의 유저권한에 따라, 에디터는 컨테츠를 수정하고 제출할수 있으며, 검증자는 승인을 하고, 마지막 관리자 또는 등록자는 해당 업데이트된 페이지를 Publish 할 수있도록 하는것이다.

여기서 하나의 문제점은, 아래의 사진처럼 content item에 페이지를 구성하는 많은 sublayout들이 존재할수가 있다. 각각 다른 템플릿이 적용된 관계로 페이지를 등록하고, 승인한다고 하더래도 해당 선택되어진 content item만 workflow에 적용될뿐이다. 다른 child Related Item은 그대로 initial state에 존재할수가 있다.



이런 경우를 보완하기 위하여, content item의 Workflow state이 업데이트 되면, 페이지에 등록되어진 sublayout역시 모두 똑같은 workflow state 으로 바뀌게 된다.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class UpdateWorkflowState
{
    // List all controls in page item
    public RenderingReference[] GetListOfSublayouts(string itemId, Item targetItem)
    {
        RenderingReference[] renderings = null;

        if (Sitecore.Data.ID.IsID(itemId))
        {
            renderings = targetItem.Visualization.GetRenderings(Sitecore.Context.Device, true);
        }

        return renderings;
    }

    // Return all datasource defined on one item
    public IEnumerable<string> GetDatasourceValue(WorkflowPipelineArgs args, Item targetItem)
    {
        List<string> uniqueDatasourceValues = new List<string>();
        Sitecore.Layouts.RenderingReference[] renderings = GetListOfSublayouts(targetItem.ID.ToString(), targetItem);
        foreach (var rendering in renderings)
        {
            if (!uniqueDatasourceValues.Contains(rendering.Settings.DataSource))
                uniqueDatasourceValues.Add(rendering.Settings.DataSource);
        }

        return uniqueDatasourceValues;
    }

    // Check workflow state and update state
    public WorkflowResult ChangeWorkflowState(Item item, ID workflowStateId)
    {
        using (new EditContext(item))
        {
            item[FieldIDs.WorkflowState] = workflowStateId.ToString();
        }
        return new WorkflowResult(true, "OK", workflowStateId);
    }

    // Verify workflow state
    public WorkflowResult ChangeWorkflowState(Item item, string workflowStateName)
    {
        IWorkflow workflow = item.Database.WorkflowProvider.GetWorkflow(item);

        if (workflow == null)
        {
            return new WorkflowResult(false, "No workflow assigned to item");
        }

        WorkflowState newState = workflow.GetStates().FirstOrDefault(state => state.DisplayName == workflowStateName);

        if (newState == null)
        {
            return new WorkflowResult(false, "Cannot find workflow state " + workflowStateName);
        }

        return ChangeWorkflowState(item, ID.Parse(newState.StateID));
    }
}



여기는 해당 모든 sublayout을 불러오고, 현재 workflow state의 그 다은 state로 적용시키는 것이다.


1
2
3
4
5
6
7
8
9
// Find all controls on item
foreach (string controls in GetDatasourceValue(args, args.DataItem))
{
    if (!String.IsNullOrEmpty(controls))
    {
        Item listControls = args.DataItem.Database.GetItem(controls);
        ChangeWorkflowState(listControls, "Awaiting Approval");
    }
}

2015년 4월 24일 금요일

Item에 적용되어진 Sublayout 리스트 출력

#HowTo #.NET #Rendering #렌더링 #

 현재 이 코드는 컨텐트 페이지에 적용된 컨트롤 리스트 들을 보여주는 것이다. 간혹, 프리젠테이션 디테일에 적용된 sublayout리스트 들을 불러야 할 경우가 생기는데, 이럴 경우 아래의 코드를 이용하여 적용되어진 컨트롤 리스트들을 출력할수가 있다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 디바이스에 적용된 모든 sublayout 리스트 출력
public RenderingReference[] GetListOfSublayouts(string itemId, Item targetItem)
{
    RenderingReference[] renderings = null;

    if (Sitecore.Data.ID.IsID(itemId))
    {
        renderings = targetItem.Visualization.GetRenderings(Sitecore.Context.Device, true);
    }

    return renderings;
}

// 프리젠테이션 디테일에 적용되어진 렌더링 정보를 가져옴
public List<RenderingItem> GetListOfDataSource(RenderingReference[] renderings)
{
    List<RenderingItem> ListOfDataSource = new List<RenderingItem>();
    foreach (RenderingReference rendering in renderings)
    {
        if (!String.IsNullOrEmpty(rendering.Settings.DataSource))
        {
            ListOfDataSource.Add(rendering.RenderingItem);
        }
    }
    return ListOfDataSource;
}

RenderingReference[] renderings = GetListOfSublayouts(targetItem.ID.ToString(), targetItem);
List<RenderingItem> ListOfDataSource = GetListOfDataSource(renderings);

2015년 4월 7일 화요일

Sitecore 아이템 정보 가져오기 (Code)

#FYI #ItemInformation

 해당 코드들은 새로운 프로젝트에서 sublayout을 만들때 유용하다.
Sitecore class를 쓰기위해서는 반드는 Sitecore.Kernel.dll 레퍼런스를 프로젝트에 추가하여야 한다.


현재 page editor (xEditor)에서 선택되어진 아이템의 정보 가져오기:

Sitecore.Data.Items.Item contextItem = Sitecore.Context.Item;


선택되어진 아이뎀 정보 가져오기:
만약 해당 아이템이 존재하지 않던지, 또는 현재 유저가 선택되어진 아이템에 접근 권한이 없을시에는 Null값 또는 throw exception이 리턴된다.

Sitecore Content Item Class: Sitecore.Data.Items.Item
Sitecore.Data.Database master = Sitecore.Configuration.Factory.GetDatabase("master");
Sitecore.Data.Items.Item myItem = master.GetItem("/sitecore/content/Home/myItem");


템플릿 아이템 정보 가져오기:
­
Sitecore Template Item Class: Sitecore.Data.Items.TemplateItem 

// 템플릿 폴더 정보 가져옴
Sitecore.Data.Items.TemplateItem item = master.GetTemplate(Sitecore.TemplateIDs.Folder);


시스템 아이템 정보 가져오기:

Sitecore Item Class: Sitecore.Data.Items.Item 

// 레이아웃 정보가져옴
Sitecore.Data.Items.Item layoutsItem = master.GetItem(Sitecore.ItemIDs.Layouts);


미디어 아이템 정보 가져오기:
­
Sitecore Media Item Class: Sitecore.Data.Items.MediaItem 

// 선택되어진 경로의 미디어 파일정보 가져오기
Sitecore.Data.Items.Item myItem = master.GetItem("/sitecore/content/Media Library/Images/Logo.png");

2015년 4월 1일 수요일

Sitecore Database

#FYI #Database

 사이트코어의 데이타베이스는 3개로 (Core, Master, Web) 나누어진다.

  • Core DB
    Core 데이타베이스는 사이트코어의 세팅 및 .Net Membership Provider를 포함하는 테이블에 대한 정보를 가지고 있다. 이전의 포스팅 (Publish 버튼 숨기기)처럼, 기본적인 사이트코어 관리자페이지의 UI 또는 Permission 수정이 Core 데이타베이스에서 가능하다.

  • Master DB
    마스터 DB는 데이터가 Publish 되기 전 저장되어진 모든 버전의 정보를 가지고 있다.

  • Web DB
    웹 DB는 Master DB에서 Publish 되어진 정보가 그대로 Web DB로 전달된다. 고로, Web DB가 Live DB라고 할수있다.

2015년 3월 19일 목요일

Sitecore 관리자 페이지

#FYI #관리자 #Admin

 사이트코어는 관리자를 위하여 특정한 시스템 정보를 제공한다.
  • Cache: ~/admin/cache.aspx
    이 페이지는 캐시정보 및 캐시설정에 관한 정보를 제공하며, 또한 데이타베이스 prefetch, 데이타 캐시, 아이템 캐시, HTML 캐시등의 정보도 포함하고 있다.
  • Database Browser: ~/admin/dbbrowser.aspx
    이 페이지는 사이트코어의 데이타베이스 정보는 보여준다. Content Tree와 비슷한 정보를 가지고 있지만, 선택된 특정한 Parent아아이템의 상속되어진 정보만 보여주므로, 조금 더 가벼운(?) 인터페이스를 가지고 있다.
  • Serialization: ~/admin/serialization.aspx
    이 페이지는 Serialize 된 데이타베이스 컨턴츠를 XML기반으로 보여준다. 이것은 데이타베이스 컨텐츠를 백업할때, 버전 컨트롤 및 다른 버전과 비교하때 유용하다.
  • Show Config: ~/admin/showconfig.aspx
    이 페이지는 web.config의 Sitecore 섹션의 마지막 렌더링된 버전을 보여준다. 사이트코어는 ~/App_Config/Include/ 폴더를 제공하여 개발자들이 custom .config 파일을 저장할수 있으며, 이 정보들은 Sitecore 섹션에 final 렌더링 버전으로 불러진다.
  • Size Status: ~/admin/sizestatus.aspx
    이 페이지는 데이타베이스 사이즈에 대한 다양한 정보를 제공한다.
  • Stats: ~/admin/stats.aspx
    이 페이지는 Cache정보 페이지와 비슷하나, 얼마나 많이 컴포넌트가 캐시에서 로드되었는지에 대한 정보도 함께 제공한다. (내가 자주 사용하는 페이지이다.)
  • Unlock Admin: ~/admin/unlock_admin.aspx
    이 페이지는 Admin관지라로 잠겨진 아이템을 풀수있는 되이지다.
  • Update Installation Wizard: ~/admin/UpdateInstallationWizard.aspx
    이 페이지는 기존의 설치된 패키지를 업데이트할때 사용된다. 새로운 버전 세팅없이 자동으로 새 버전이 등록된다.

2015년 3월 17일 화요일

Sublayout을 Item에 적용시키기 (Coding)

이 소스코드는 새로운 sublayout을 현재 페이지 아이뎀의 레이아웃에 적용시키는 코드이다.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public void AddSublayoutToItem(string sublayoutId, string datasourcePath)
{
    using (new Sitecore.SecurityModel.SecurityDisabler())
    {
        if (Sitecore.Data.ID.IsID(itemId) && Sitecore.Data.ID.IsID(sublayoutId))
        {
            // 마스터 데이타베이스를 선택한다음, 현재 아이템 아이디를 불러온다
            Database masterDatabase = Database.GetDatabase("master");
            Item item = masterDatabase.GetItem(Sitecore.Data.ID.Parse(itemId));
                
            // 이미 마스터 데이타베이스가 불러졌다면, 간단하게 현재 아이템을 불러올수가 있다.
            //Item item = Sitecore.Context.Database.GetItem(Sitecore.Data.ID.Parse(itemId));

            if (item != null)
            {
                // 레이아웃과 디바이스 정보를 가져온다.
                LayoutField layoutField = new LayoutField(item.Fields[Sitecore.FieldIDs.LayoutField]);
                LayoutDefinition layoutDefinition = LayoutDefinition.Parse(layoutField.Value);
                DeviceDefinition deviceDefinition = layoutDefinition.GetDevice(Sitecore.Context.Device.ID.ToString());

                //새로운 렌더링 Definition을 만들고, Sublayout 또는 렌더링의 레퍼런스를 추가한다.
                RenderingDefinition renderingDefinition = new RenderingDefinition();
                renderingDefinition.ItemID = sublayoutId;

                // 새로 추가될 Sublayout의 Placeholder값을 정한다.
                renderingDefinition.Placeholder = "content";

                // 새로 추가된 Sublayout의 Datasource 값을 정한다. 값은 DataSource의 경로로 대체할수도 있다.
                renderingDefinition.Datasource = "{24240FF2-B4AA-4EB2-B0A4-63E027934C38}";
                // renderingDefinition.Datasource = "/sitecore/content/Home/Books";

                // 렌더링 레퍼런스를 선택되어진 디바이스에 추가한다.
                deviceDefinition.AddRendering(renderingDefinition);

                // 변경된 레이아웃을 저장한다.
                item.Editing.BeginEdit();
                layoutField.Value = layoutDefinition.ToXml(); ;
                item.Editing.EndEdit();
            }
        }
    }
}

Publish 버튼 숨기기

사이트코어는 유저의 Role의 따라 특정 아이템 접근권한을 설정할수가 있다. 만약 유저가 Limited Content Role에 포함이 되어있다면 Publish 옵션이 자동으로 숨겨져있으나, 그보다 높은 Level에 있다면, Publish 버튼이 툴바에 보인다. 이런 경우, "Publish Site" 옵션도 포함이 되어있어, Sitecore에 능숙하지 않는 유저는 실수로 사이트 전체를 "Publish" 하는 경우가 생긴다.

이런 문제를 보안하며, 적용되어진 Role (유저 그룹)을 수정하여 Publish 버튼을 숨길수가 있으며, "Publish" 버튼은 컨텐트 모드와 페이지모드 두곳에 포함이 되어있다.



컨텐트 에디터의 "Publish" 버튼 숨기기

  1. 데스크탑 관리자로 로그인 후, 데이타 베이스를 Core DB로 바꿔준다. (데스크탑 모드 제일 오른쪽 아래에 보면 데이타베이스 아이콘이 있다.)
  2. 상단 둘 박스의 유저 관리자 (User Manager)에서 역할 (Role)을 선택한다
  3. 보안 수정 (Security Editor)를 선택한다
  4. 컨텐트 에디터 (Content Editor)에서 스크린샷처럼 해당 경로로 이동한다. (Application -> Content Editor -> Menu -> Publish) 






페이지 에디터의 "Publish" 버튼 숨기기
(Sitecore 7.5이상부터는 페이지 에디터가 "Experience Editor" 또는" xEditor"로 이름이 바뀌었다.)

  1. 데스크탑 관리자로 로그인 후, 데이타 베이스를 Core DB로 바꿔준다. (데스크탑 모드 제일 오른쪽 아래에 보면 데이타베이스 아이콘이 있다.)
  2. 상단 둘 박스의 유저 관리자 (User Manager)에서 역할 (Role)을 선택한다
  3. 보안 수정 (Security Editor)를 선택한다
  4. 컨텐트 에디터 (Content Editor)에서 스크린샷처럼 해당 경로로 이동한다. (Application -> WebEdit -> Ribbons -> WebEdit -> Page Editor -> Publish) 


2015년 3월 13일 금요일

Sitecore Publish하는 방법

Sitecore의 "Content Editor" 모드로 접속을 하면, 두가지의 Publish 옵션이 있다.
Public Site는 해당 사이트의 모든 아이템을 Publish 하는것이며,
Public Item은 선택되어진 아이템과 Sub-Items을 Publish 할수있다.


각각의 옵션에는 Incremental Publish, Smart Publish, Republish 옵션이 있는데,


  • Incremental Publish는 Publish Site를 선택하였을때만 나오는 옵션이며, 오직 수정된 아이템만 Publish 한다.
  • Smart Publish는 소스 데이타베이스와 타깃 데이타베이스를 비교하여, 변경된 아이템만 Publish 한다.
  • Republish는 선택된 모든 아이템을 Publish 한다.


하나 알아두어야 할것은, 하나의 아이템만 Publish되어있더라도, 해당 사이트의 Cache정보를 모두 소멸이 된다. 이 부분은 web.config파일을 수정하여 특정한 시간또는 사이트에만 Cache를 소멸시킬수가 있다.



1
2
3
4
5
6
7
<event name="publish:end">
    <handler type="Sitecore.Publishing.HtmlCacheClearer, Sitecore.Kernel" method="ClearCache">
      <sites hint="list">
        <site>website</site>
      </sites>
    </handler>
</event>