Custom CreatePublishingPageDialog v SharePointu? Ni problema!

Predstavljajmo si, da imamo na našem SharePoint portalu izdelanih več tipov novic (Article Content Types) z več postavitvami strani (Page Layouts). Mi pa bi radi klicali Add a page dialog za vsakega od njih.

Problem se nahaja v OOTB SharePointovi CreatePublishingPageDialog.aspx strani, ki se kliče ob kliku na gumb Add a page znotraj Site Actions menija. Z njim namreč lahko kreiramo samo en tip novice s specifično postavitvijo strani. To je definirano na Site Settings strani pod Page layouts and site templates znotraj Look and Feel kategorije.

Ena izmed rešitev je, da izdelamo CreatePublishingPageDialog.aspx stran po naši meri.

Pa začnimo. Znotraj našega WSPja kreirajmo nov Application Page in ga poimenujmo CreatePublishingPageDialog.aspx.

Nato pojdimo v HIVE na našem razvojnem SharePoint strežniku in poiščimo OOTB CreatePublishingPage.aspx datoteko znotraj TEMPLATE\LAYOUTS\ podmapo (npr. 16\TEMPLATE\LAYOUTS\CreatePublishingPageDialog.aspx).
Prekopirajmo vsebino datoteke v vaš novo ustvarjen Application Page.

Dodajmo spodnjo vrstico kot prvo vrstico naše CreatePublishingPageDialog.aspx datoteke:

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>

In zamenjajmo to vrstico …

<%@ Page Language="C#" DynamicMasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.Publishing.Internal.CodeBehind.CreatePublishingPageDialog15" %>

… z naslednjo:

<%@ Page Language="C#" DynamicMasterPageFile="~masterurl/default.master" CodeBehind="CreatePublishingPageDialog.aspx.cs" Inherits="Xnet.SP.Test.Layouts.Xnet.SP.Test.CreatePublishingPageDialog" %>

Nato pojditmo v PlaceHolderMain in dodajtmo spodnjo kodo pod TextBox z Idjem nameInput:

<div class="ms-core-form-line">
    <table border="0">
        <tr>
            <td>
                <span class="ms-metadata ms-floatLeft ms-displayInlineBlock ms-verticalAlignBaseline">
                    <SharePoint:EncodedLiteral runat="server" text="News type" EncodeMethod='HtmlEncode'/>
                </span>
            </td>
            <td>
                <asp:DropDownList ID="ddlNewsType" runat="server"></asp:DropDownList>
            </td>
        </tr>
    </table>
</div> 

Pojdimo v code-behind Application Page (CreatePublishingPageDialog.aspx.cs datoteka) in zamenjajmo dedovan razred LayoutsPageBase z Microsoft.SharePoint.Publishing.Internal.CodeBehind.CreatePublishingPageDialog15.

Nato zamenjajmo podpis OnLoad metode z override nastavitvijo:

protected override void OnLoad(EventArgs e) 

In vanjo dodajmo spodnjo kodo:

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

    folderUrl = SPRequestParameterUtility.GetValue<string>(base.Request, "RootFolder", SPRequestParameterSource.QueryStringValues);

    SPWeb web = SPContext.Current.Web;
    SPFieldChoice field = (SPFieldChoice)web.Fields.GetFieldByInternalName("NewsType");

    if (!Page.IsPostBack)
    {
        ddlNewsType.Items.Clear();
        field.Choices.Cast<string>().ToList().ForEach(x => ddlNewsType.Items.Add(x));
    }
    else
    {
        originalRequestedName = nameInput.Text;
        if (originalRequestedName.EndsWith(".aspx", StringComparison.OrdinalIgnoreCase))
        {
            originalRequestedName = originalRequestedName.Remove(checked(originalRequestedName.Length - ".aspx".Length));
        }

        nameInput.Text = nameInput.Text.Replace(' ', '-');
    }
} 

Kot lahko vidimo v zgornji kodi, je drop down zapolnjen z opcijami iz NewsType choice polja. Hkrati pa (v post back času) modificiramo nameInput TextBox polje.

Nato moramo skriti dedovano CreateButton_Click metodo z novo:

protected new void CreateButton_Click(object sender, EventArgs e)
{
    if (Page.IsValid)
    {
        SPLongOperation.Begin(delegate (SPLongOperation longOperation)
        {
            SPWeb web = SPContext.Current.Web;
            PublishingWeb currentPublishingWeb = PublishingWeb.GetPublishingWeb(web);
            PublishingPage publishingPage = null;
            SPFolder sPFolder = null;
            if (!string.IsNullOrEmpty(folderUrl))
            {
                sPFolder = currentPublishingWeb.Web.GetFolder(folderUrl);
                if (!sPFolder.Exists)
                {
                    string url = Helper.ConcatUrls(folderUrl, nameInput.Text);
                    SPUtility.CreateParentFoldersForFile(currentPublishingWeb.PagesList, url, false);
                    sPFolder = currentPublishingWeb.Web.GetFolder(folderUrl);
                }
            }
            PageLayout pageLayout = null;
            string text = base.Request.QueryString.Get("PLUrl");
            if (string.IsNullOrEmpty(text))
            {
                pageLayout = currentPublishingWeb.DefaultPageLayout;
            }
            else
            {
                try
                {
                    pageLayout = new PageLayout(base.Web.GetListItem(text));
                }
                catch (Exception)
                {
                    Logger.ToLog(new Exception(string.Format("Unable to create PageLayout from listitem of path : {0}", text)));
                    pageLayout = currentPublishingWeb.DefaultPageLayout;
                }
            }
            publishingPage = SPHelper.CreatePublishingPage(currentPublishingWeb, nameInput.Text, pageLayout, sPFolder, false);
            if (publishingPage != null && originalRequestedName != null)
            {
                publishingPage.Title = originalRequestedName;
                publishingPage.ListItem["NewsType"] = ddlNewsType.SelectedValue;
                publishingPage.Update();
            }

            string text2 = SPHttpUtility.UrlPathEncode(publishingPage.ListItem.File.ServerRelativeUrl, false);
            string FinishUrl = SPHelper.DesignModeUrl(text2);

            if (!string.IsNullOrEmpty(base.Request.QueryString.Get("IsDlg")))
            {
                if (base.Request.QueryString["shouldRedirectPage"] == "0")
                {
                    string scriptLiteralToEncode = SPHelper.ConvertToAbsoluteUrl(FinishUrl, currentPublishingWeb.Web.Site, true);
                    longOperation.EndScript("window.frameElement.commitPopup('" + SPHttpUtility.EcmaScriptStringLiteralEncode(scriptLiteralToEncode) + "');");
                }
                else
                {
                    longOperation.EndScript("window.frameElement.navigateParent('" + SPHttpUtility.EcmaScriptStringLiteralEncode(FinishUrl) + "');");
                }
            }
            else
            {
                longOperation.End(FinishUrl);
            }
        });
    }
}

Kot lahko vidimo v kodi zgoraj, dobimo specifičen Page Layout iz PLUrl query string parametra. Če želimo, lahko isto naredimo za Content Type. Po drugi strani pa lahko uporabnikom omogočimo izbiro specifičnega Page Layouta ali Content Typea iz spustnega seznama.

Ko imamo page layout, lahko naredimo nov Publishing Page s CreatePublishingPage metodo iz SPHelper static classa (SPHelper in Helper static classe si oglejte na mojem GitHubu preko povezave na koncu tega prispevka).

Na koncu zapolnimo NewsType polje našega Publishing Pageaz izbrano vrednostjo iz ddlNewsType spustnega menija.

Zadnja stvar, ki jo moramo narediti, je da ustvarimo Site Actions menu iteme. To lahko naredimo s pomočjo MenuItemTemplate preko Master Pagea ali s CustomAction preko modula.

Spodaj je primer s pomočjo MenuItemTemplate:

<SharePoint:MenuItemTemplate runat="server" ID="MenuItem_CreateNews"
   Text="Create News"
   Description="Create News"
   ClientOnClickNavigateUrl="javascript: SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', { url: 'http://test/_layouts/15/Xnet.SP.Test/CreatePublishingPageDialog.aspx?IsDlg=1&PLUrl=http://test/_catalogs/masterpage/NewsPL.aspx' });"
   MenuGroupId="400"
   Sequence="100"
   PermissionsString="AddAndCustomizePages"
   PermissionMode="All" />

In primer s CustomAction:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
    Id="CreateNewsCA"
    GroupId="SiteActions"
    Location="Microsoft.SharePoint.StandardMenu"
    Title="Create News"
    Rights="AddAndCustomizePages"
    Sequence="0">
    <UrlAction Url="javascript: SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', { url: 'http://test/_layouts/15/Xnet.SP.Test/CreatePublishingPageDialog.aspx?IsDlg=1&PLUrl=http://test/_catalogs/masterpage/NewsPL.aspx' });"/>
  </CustomAction>
</Elements>

Dodaj odgovor

Vaš e-naslov ne bo objavljen. * označuje zahtevana polja