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라고 할수있다.