레이블이 MVC인 게시물을 표시합니다. 모든 게시물 표시
레이블이 MVC인 게시물을 표시합니다. 모든 게시물 표시

2018년 11월 19일 월요일

사이트코어의 새로운 MVC Route 적용하기

이번 블로그에서는 새로운 MVC Route를 사이트코어에 적용하는 방법을 알아보자.
사이트코어의 기본 MVC Route는 "/api/sitecore/{controller}/{action}"으로써 Sitecore 9 이상의 버전에서는 Sitecore.Mvc.config, 그리고 Sitecore 9 하위 버전에서는 Sitecore.Speak.Mvc.Config 파일에서 확인할 수가 있다.
Sitecore의 자체적인 MVC Application의 컨트롤는 "/sitecore/layout/controllers" 아이템 트리에 등록되어진 Application 렌더링 아이템을 작동시키지만, 간혹 아이템의 등록없이 새로운 API를 만들어 외부 소스를 Ajax Call로 불러들여 원하는 기능을 작동시킬수가 있다.

이를 위하여, 새로운 MVC Route를 만듬으로써 기본 API 경로에 구애받지 않고 사이트코어 내에 다른 어플리케이션을 독립적으로 수행할수가 있다. 지금부터 어플리케이션을 만들고 적용시키는 방법을 알아보자.

  1. Visual Studio에서 새로운 Empty MVC 프로젝트를 만든다.

  2. App_Start 폴더에 RouteConfig.cs을 새로운 Route를 레지스터하기 위하여 수정한다.

     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
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace SitecoreSpaceNewRoute
    {
        public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
            {
                //// 
                //// 기본 MVC Route
                ////
                //routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
                //routes.MapRoute(
                //    name: "Default",
                //    url: "{controller}/{action}/{id}",
                //    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                //);
    
    
                ////
                //// 사이트코어 스페이스의 새로운 MVC Route
                ////
                routes.MapRoute(
                    name: "SitecpreSpaceRouting",
                    url: "new/sitecore/space/routing/{controller}/{action}/{id}",
                    defaults: new { controller = "SitecoreSpace", action = "MyView", id = UrlParameter.Optional }
                );
            }
        }
    }
    


  3. 새로운 폴더 "CustomRouting" 이라는 폴더를 만들고, Sitecore.Kernel assembly를 Reference에 추가하고 사이트코어의 Bin 폴더의 System.Web.Mvc를 사용하도록 프로젝트에 업데이트한다. 레지스터한 Route를 Sitecore.Pipeline의 프로세스에 적용을 시킨다.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    using System.Web.Routing;
    using Sitecore.Pipelines;
    
    namespace SitecoreSpaceNewRoute.CustomRouting
    {
        public class InitializeRoutes
        {
            /// <summary>
            /// 새로 등록한 Route는 Sitecore Pipeline에 적용시킨다.
            /// </summary>
            /// <param name="args"></param>
            public void Process(PipelineArgs args)
            {
                RouteConfig.RegisterRoutes(RouteTable.Routes);
            }
        }
    }
    


  4. 간단하게 새로운 Route의 레지스트를 마쳤으며, 이젠 Simple MVC을 만들자.

    Controller (SitecoreSpaceController.cs)

     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
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    
    namespace SitecoreSpaceNewRoute.Controllers
    {
        public class SitecoreSpaceController : Controller
        {
            // GET: SitecoreSpace
            public ActionResult MyView()
            {
                Models.SitecoreSpace ssnr = new Models.SitecoreSpace();
    
                // Valuable 값을 다른 소스 (예, 데이타베이스)에서 불러들일수 있지만,
                // 이번은 예제이므로, Static 값을 메뉴얼로 적용하겠다.
                ssnr.Subject = "사이트코어의 새로운 MVC Routing";
                
                ssnr.Description = "사이트코어 스페이스의 새로운 MVC Routing으로써, 기존 (Default)의 Routing 제한을 받지않고, 임의의 새로운 Route를 적용시켜 독립적인 MVC 어플리케이션을 Sitecore XP내에서 작동시킬수 있다.";
                ssnr.CurrentDateTime = DateTime.UtcNow;
    
                return View(ssnr);
            }
    
            // Redirect가 아니 다른 View rendering으로 사용할수가 있다.
            public ActionResult RedirectToBlog()
            {
                Models.SitecoreSpace ssnr = new Models.SitecoreSpace();
                ssnr.BlogUrl = "https://SitecoreSpace.Blogspot.com";
    
                return Redirect(ssnr.BlogUrl);
            }
        }
    }
    


    Model (SitecoreSpace.cs)
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    using System;
    namespace SitecoreSpaceNewRoute.Models
    {
        public class SitecoreSpace
        {
            public string FullBlogName { get; set; }
            public string BlogUrl { get; set; }
            public string Subject { get; set; }
            public string Description { get; set; }
            public DateTime CurrentDateTime { get; set; }
        }
    }
    


    View (MyView.cshtml)

     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
    @model SitecoreSpaceNewRoute.Models.SitecoreSpace
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>MyView</title>
    </head>
    <body>
        <div class="form-horizontal">
            <h4>SitecoreSpace</h4>
            <hr />
            <div class="col-md-10">
                @Html.DisplayTextFor(model => model.Subject)
            </div>
            <br />
            <div class="col-md-10">
                @Html.DisplayTextFor(model => model.FullBlogName)
            </div>
            <br />
            <div class="col-md-10">
                @Html.DisplayTextFor(model => model.Description)
            </div>
            <br />
            <div class="col-md-10">
                링크: @Html.ActionLink("Sitecore Space Blog", "RedirectToBlog", null, new { target = "_blank" })
            </div>
            <br />
            <div class="col-md-10">
                현재시간: @Model.CurrentDateTime.ToString("yyyy-MM-dd h:mm:ss tt")
            </div>
        </div>
    </body>
    </html>
    


    View (RedirectToBlog.cshtml)

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    <!DOCTYPE html>
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>RedirectToBlog</title>
    </head>
    <body>
        <div> 
            추가 extra 페이지
        </div>
    </body>
    </html>
    


  5. 새로운 패치파일을 만들어 사이트코어 파일시스템의 "/App_config/Include/" 폴더에 z.Sitecore.Space.Route.config을 만든다.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    <?xml version="1.0" encoding="utf-8"?>
    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
      <sitecore>
        <pipelines>
          <initialize>
            <processor type="SitecoreSpaceNewRoute.CustomRouting.InitializeRoutes, SitecoreSpaceNewRoute" 
                       patch:after="processor[@type='Sitecore.Pipelines.Loader.EnsureAnonymousUsers, Sitecore.Kernel']" />
          </initialize>
        </pipelines>
      </sitecore>
    </configuration>
    


이젠 브라우저에서 패치되어진 API 경로를 이동을 해본다.








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년 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년 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" })