Akumina Developer Documentation

Akumina Developer Documentation

  • API
  • Docs
  • Blog

›Site Creator

Akumina

  • Quickstart

Yo Akumina

  • Yo Akumina
  • Start with Yeoman
  • React
  • Simple template

Widget Builder

  • Widget Builder Structure
  • Akumina Widget Builder
  • Skipping instances
  • Token replacement for widget properties

Widget Development Quickstart

  • Setting up the Project
  • Configuring .env file
  • Configuring - akumina.sitedployer.config.json file
  • Configuring - akumina.config.json file
  • Extras

Widget Info

  • Akumina Widgets Overview
  • Building a New Widget Instance
  • Widget Views
  • Widget Properties
  • Global vs Local widgets (Widget Scoping)
  • Akumina React Widgets
  • Callbacks
  • RenderChildWidgets
  • Vendor Package List

Virtual Page Builder

  • Akumina Virtual Page Builder
  • Using Virtual Page Layouts
  • Creating a Custom Layout

Stream Card Builder

  • Installation
  • Stream Card Builder
  • Custom Cards
  • Activity Comments Config
  • Akumina Activity Stream PUSH Subscription using PowerAutomate to connect to ServiceNow
  • Akumina Activity Stream PUSH Subscription using PowerAutomate to connect to Dynamic 365

Site Deployer

  • Overview
  • Version 6.0
  • List Attribute Deployments
  • NPM Commands
  • SPA Updates and Deploying to multiple sites

Authoring

  • Content Action Event
  • Publish Validation Integration
  • Field Event Integration
  • CK Editor external plugins

Headless

  • Quickstart
  • Headless Teams support
  • Headless Troubleshooting

Modern

  • Overview
  • FAQ
  • Single Page Application
  • Modern Web Part Library
  • Google Analytics for Modern Pages

Site Creator

  • Overview
  • Adding A Custom Site Definition
  • Core Step Classes
  • Custom Site Definition Components
  • Custom Site Definition XML
  • Custom Subsite Definitions
  • Sample Step Code
  • Supported Tokens

Azure DevOps

  • CI/CD using Azure DevOps
  • Setting up a build to deploy a site package
  • Setting up a build to deploy file to App Manager hosted in an app service

Configuration

  • Configuration Context Overview
  • Edit the Redis cache timeout
  • Using a key vault for the client id and client secret

Debugging

  • Debugging in Akumina

Advanced

  • Central Site Collection Support
  • Eventing OOB Digital Workplace Events
  • Working with custom JSX Views
  • Page Indexing

Service Hub

  • Quickstart

Patch Notes

  • Patch Notes

Custom Subsite Definitions

Applies to

Akumina Foundation 3.3.0.0 and above

Download

You can download the code the for SampleSite project here

Overview

The Deployment Manager SDK allows us to define custom site definitions to subsites as well as root sites. A subsite definition is essentially the same as a root site definition with the following differences:

  • Subsite Definitions require User Input for the Title, Url, and whether or not to Inherit Permissions
  • Subsite Definitions require a step that creates a new Subsite from user inputs
  • Subsite Definitions do not need to provision branding files
  • Subsite Definitions do not need to provision page layout files
  • Subsite Definitions do not need to provision Master Page files

The following article will go through the elements of a basic subsite definition

The C# class inheriting the SiteProvisionerSiteBase class

This file inherits the SiteProvisionerSiteBase class and assembles our step classes into a list of steps which is seen in the Deployment Manager App UI. We will cover the differences between a root site definition and the subsite definition here. A sample subsite instance, SampleSubSite.cs, is shown below.

public class SampleSubSite : SiteProvisionerSiteBase
    {
        public override string AssetDirectory => "SampleSubSite";

        public override string Javascript => "~/SiteDefinitions/SampleSubSite/ProvisionerFiles/js/samplesubsite.js";

        public override string FriendlyName => "Sample Sub-site";

        public override string ClassName => "SiteCreator.SampleSubSite";

        public override bool IsVisible => true;

        public override List<ISiteProvisionerStep> Steps
        {
            get
            {
                var _steps = new List<ISiteProvisionerStep>
                {
                    new ValidateUserSettings(),
                    new CreateSiteFromUserSettings(),
                    new SetSecurityOnSite(),
                    new ProvisionLists(),
                    new UploadFiles(),
                    new AddPages(),
                    new AddControlsToPages(),
                    new SetHomePage(),
                    new ResetMasterPageInheritance()
                };
                return _steps;
            }
        }

        public override List<SiteProvisionerSettingsField> UserSettings
        {
            get
            {
                var userSettings = new List<SiteProvisionerSettingsField>
                {
                    new SiteProvisionerSettingsField
                    {
                        Name = "SubSite",
                        Description = "SubSite",
                        DefaultValue = new List<SiteProvisionerSettingsListItem> {},
                        Type = typeof(List<>)
                    },
                    new SiteProvisionerSettingsField
                    {
                        Name = "Title",
                        Description = "The Title of the site to be created",
                        DefaultValue = "",
                        Required = true
                    },
                    new SiteProvisionerSettingsField
                    {
                        Name = "URL",
                        Description = "The URL of the site to be created",
                        DefaultValue = "",
                        Required = true
                    },
                    new SiteProvisionerSettingsField
                    {
                        Name = "InheritPermissions",
                        Description = "Inherit permissions from the parent site",
                        DefaultValue = true,
                        Type = typeof(bool)
                    }                   
                };

                return userSettings;
            }
        }

    }

Key Differences from the Root Site Definition

IsVisible => true

We always want our subsite definition to be visible.

UserSettings

We include user inputs for our Subsite Deployment.

SubSite

This allows the user to choose a previously deployed Subsite so individual steps can be rerun on it.

Title

The Title of the Subsite, this is a required text field for subsite deployment.

URL

The URL of the Subsite, this is a required text field for subsite deployment.

InheritPermissions

The Permissions of the subsite, this is a required boolean field for subsite deployment. When checked the subsite owners group will be the parent owners group. When unchecked the subsite owners group will be unique.

Steps specific to Subsite Definitions

The following steps are required for Subsite Definitions

CreateSiteFromUserSettings

Retrieves the Title and URL user inputs and creates a site. This step is included with our SiteProvisioning.SampleSite project and can be modified for additional inputs.

SetSecurityOnSite

Retrieves the InheritPermissions user input and sets the owners group on the newly created site. This is within the Akumina.SiteProvision.CoreSteps dll

SiteDefinitions Folder

image 2

The assets needed for the deployment of subsites are a subset of those needed for root sites

ContentEditor

The ContentEditor folder contains the ContentEditor.xml file, we need this for deploying our widgets. Do not edit or delete this file.

ListDefinitions

The ListDefinitions folder contains information that the Site Creator App uses to create lists on the subsite. This information is stored in an xml file called Lists.xml.

PageContent

The PageContent folder contains information that the Deployment Manager App will use to add content to the pages we create. This information is stored within an xml file called pages.xml.

Pages

The Pages folder designates the pages that are deployed to the Pages Library of our subsite. This information is stored within an xml file called Elements.xml. Our pages will need to reference layouts that are deployed on the root site.

ProvisionerFiles

Within the ProvisionerFiles folder we will store our provisioning javascript. Having a provisioning javascript file is required for the deployment view to function. The provisioning javascript for a subsite is shown below. This file can be modified to enhance the UI functionality of the deployment view

var SiteCreator = SiteCreator ? SiteCreator : {};

if ((typeof SiteCreator.SampleSubSite) === 'undefined') {
    SiteCreator.SampleSubSite = function () {
        var _cur = this;

        this.Init = function (model) {
            SiteCreator.Eventing.Subscribe('/SiteCreator/DeployButtonclick/', _cur.OnDeploymentClick);
            SiteCreator.Eventing.Subscribe('/SiteCreator/SelectActionChange/', _cur.SelectActionChange);
            SiteCreator.Eventing.Subscribe('/SiteCreator/SiteChange/', _cur.OnSiteChange);
            SiteCreator.Eventing.Subscribe('/SiteCreator/GetFeatureName/', _cur.GetFeatureName);
            _cur.className = model.className;
            _cur.siteContainerId = model.siteContainerId;

            //Get subsites in dropdown
            _cur.GetSubSites();

            _cur.BindEvents();
        };

        this.IsLanguageEnabled = function () {

            $('#ak-loading').show();
            var def = $.Deferred();

            $.ajax({
                url: '/api/Config/IsLanguageEnabled',
                type: 'GET',
                contentType: 'application/json; charset=utf-8',
                success: function (isLanguageEnabled) {
                    def.resolve(isLanguageEnabled);
                    //Bind dropdown
                    $('#ak-loading').hide();
                },
                error: function (xhr, textStatus, errorThrown) {
                    def.reject();
                    $('#ak-loading').hide();
                }
            });

            return def;
        };

        this.GetSubSites = function () {
            $('#ak-loading').show();

            $.ajax({
                url: '/api/connector/subsites',
                type: 'GET',
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    for (var obj in data) {
                        if (obj.indexOf('/') > -1) {
                            var html = "<option value='" + data[obj] + "'>" + obj.substring(obj.lastIndexOf('/') + 1) + "</option>";
                            $('#ak-siteprovisioning-usersetting-SubSite').append(html);
                        }
                    }
                    //Bind dropdown
                    $('#ak-loading').hide();
                },
                error: function (xhr, textStatus, errorThrown) {
                    $('#ak-loading').hide();
                }
            });
        };

        this.IsUpgradeRequired = function (siteId) {
            var def = $.Deferred();

            $.ajax({
                url: '/api/connector/isupgraderequired?siteId=' + siteId,
                type: 'GET',
                contentType: 'application/json; charset=utf-8',
                success: function (result) {
                    def.resolve(result);
                },
                error: function (xhr, textStatus, errorThrown) {
                    def.reject();
                }
            });

            return def;
        };

        this.BindEvents = function () {
            $('#ak-siteprovisioning-usersetting-SubSite').change(function () {
                $('#ak-loading').show();
                //Display theme image in preview section
                var selectedSubSiteId = this.value;

                //Get properties of subsite
                $.ajax({
                    url: '/api/connector/siteproperties?siteId=' + selectedSubSiteId,
                    type: 'GET',
                    success: function (data) {
                        //Display properties for subsites
                        $("#ak-siteprovisioning-usersetting-Title").val(data.Title);
                        if (data.Url.indexOf('/') > -1) {
                            $("#ak-siteprovisioning-usersetting-URL").val(data.Url.substring(data.Url.lastIndexOf('/') + 1));
                        }
                        //$("#ak-siteprovisioning-usersetting-InheritPermissions").prop("checked", data.InheritPermissions);
                        $("#ak-siteprovisioning-usersetting-Image option[value=" + data.Image + "]").attr('selected', 'selected');

                        $('#ak-loading').hide();
                        //Check if version upgrade is required for selected subsite.
                        //_cur.IsUpgradeRequired(selectedSubSiteId).then(function (isUpgradeRequired) {
                        //    if (!isUpgradeRequired) {
                        //        $("#" + _cur.siteContainerId + " [id^=Step_][data-steptype=Upgrade]").hide();
                        //        if ($('input[type=radio][name=select-an-action][value=UpgradeSite]').is(':checked')) {
                        //            $("#upgradeSiteDiv").show();
                        //        }
                        //    }
                        //    else {
                        //        if ($("#" + _cur.siteContainerId + " [id^=Step_][data-steptype=Upgrade]").length == 0 && $('input[type=radio][name=select-an-action][value=UpgradeSite]').is(':checked')) {
                        //            $("#upgradeSiteDiv").show();
                        //        }
                        //        else {
                        //            $("#" + _cur.siteContainerId + " [id^=Step_][data-steptype=Upgrade]").show();
                        //            $("#upgradeSiteDiv").hide();
                        //        }
                        //    }
                        //    $('#ak-loading').hide();
                        //}, function () {
                        //    $('#ak-loading').hide();
                        //});
                    },
                    error: function (xhr, textStatus, errorThrown) {
                        $('#ak-loading').hide();
                    }
                });
            });
        };

        this.OnDeploymentClick = function (model) {
            BaseDeployment(model, _cur.siteContainerId);
        };

        this.SelectActionChange = function (model) {
            if (model.siteContainerId == _cur.siteContainerId) {
                _cur.DisplayDepartmentProperties();
                $("#ak-siteprovisioning-usersetting-SubSite").parent().hide();
                $("#ak-siteprovisioning-usersetting-Title").val("");
                $("#ak-siteprovisioning-usersetting-Title").attr('disabled', false);
                $("#ak-siteprovisioning-usersetting-URL").val("");
                $("#ak-siteprovisioning-usersetting-URL").attr('disabled', false);
                $("#ak-siteprovisioning-usersetting-InheritPermissions").attr('disabled', false);
                $("#ak-siteprovisioning-usersetting-Image").attr('disabled', false);
                //Detect Add mode
                if ($('input[type=radio][name=select-an-action][value=CreateNewInstallation]').is(':checked')) {
                }//Detect Update mode
                else if ($('input[type=radio][name=select-an-action][value=UpdateConfigurationSettings]').is(':checked')) {
                }//Detect Individual Deployment Step mode
                else if ($('input[type=radio][name=select-an-action][value=ExecuteIndividualDeploymentSteps]').is(':checked')) {
                    //Display all department site properties
                    $("#ak-siteprovisioning-usersetting-SubSite").parent().show();
                    $("#ak-siteprovisioning-usersetting-Title").attr('disabled', true);
                    $("#ak-siteprovisioning-usersetting-URL").attr('disabled', true);
                    $("#ak-siteprovisioning-usersetting-InheritPermissions").attr('disabled', true);
                    $("#ak-siteprovisioning-usersetting-Image").attr('disabled', true);

                    //Trigger subsite change and load subsite properties
                    var firstValue = $("#ak-siteprovisioning-usersetting-SubSite option:first").val();
                    if (firstValue != "" && typeof firstValue != 'undefined') {
                        $("#ak-siteprovisioning-usersetting-SubSite").val($("#ak-siteprovisioning-usersetting-SubSite option:first").val());
                        $("#ak-siteprovisioning-usersetting-SubSite").trigger('change');
                    }

                    $("#" + model.siteContainerId + " [id='Step_Validate User Settings'] .ak-siteprovisioning-featuredeploy-btn").prop("disabled", true).css('opacity', '0.6');
                    $("#" + model.siteContainerId + " [id='Step_Create Site from URL user setting'] .ak-siteprovisioning-featuredeploy-btn").prop("disabled", true).css('opacity', '0.6');
                    $("#" + model.siteContainerId + " [id='Step_Enable Multilingual'] .ak-siteprovisioning-featuredeploy-btn").prop("disabled", true).css('opacity', '0.6');
                    $("#" + model.siteContainerId + " [id='Step_Update Friendly Urls'] .ak-siteprovisioning-featuredeploy-btn").prop("disabled", true).css('opacity', '0.6');
                    $("#" + model.siteContainerId + " [id='Step_Update List Items - Multilang Provisioning'] .ak-siteprovisioning-featuredeploy-btn").prop("disabled", true).css('opacity', '0.6');
                }
                else if ($('input[type=radio][name=select-an-action][value=UpgradeSite]').is(':checked')) {
                    $('#' + model.siteContainerId + " .ak-siteprovisioning-upgrade-btn").hide();
                }
            }
        };

        this.ShowHideMultilingualStep = function () {
            if (_cur.isLanguageEnabled) {
                $("#" + _cur.siteContainerId + " [id='Step_Enable Multilingual']").show();
            }
            else {
                $("#" + _cur.siteContainerId + " [id='Step_Enable Multilingual']").hide();
            }
        };

        this.DisplayDepartmentProperties = function () {
            $("#ak-siteprovisioning-usersetting-Title").parent().show();
            $("#ak-siteprovisioning-usersetting-URL").parent().show();
            $("#ak-siteprovisioning-usersetting-InheritPermissions").parent().show();
            $("#ak-siteprovisioning-usersetting-Image").parent().show();
        };

        this.OnSiteChange = function (model) {
            if (model.siteContainerId == _cur.siteContainerId) {
                    $("#selectActionDiv").show();
                    $("#updateConfigOption").hide();
                    $("#upgradeSiteOption").hide();
            }
        };

        this.GetFeatureName = function (model) {
            BaseGetFeatureName(model, _cur.siteContainerId);
        };
    }
};

UploadFiles

The UploadFiles folder contains all files that we want uploaded to SharePoint file libraries within our site via the UploadFiles.cs step. See UploadFiles for more details.

Download

You can download the code the for SampleSite project here

References

To learn how to leverage the Deployment Manager SDK see the following articles:

  • Overview
  • Adding A Custom Site Definition
  • Core Step Classes
  • Custom Site Definition Components
  • Custom Site Definition XML
  • Custom Subsite Definitions
  • Sample Step Code
← Custom Site Definition XMLSample Step Code →
  • Applies to
  • Download
  • Overview
  • The C# class inheriting the SiteProvisionerSiteBase class
    • Key Differences from the Root Site Definition
    • Steps specific to Subsite Definitions
  • SiteDefinitions Folder
    • ContentEditor
    • ListDefinitions
    • PageContent
    • Pages
    • ProvisionerFiles
    • UploadFiles
  • Download
  • References
Akumina Developer Documentation
Docs
Akumina Framework 5.0Akumina Widget BuilderAkumina Yeoman GeneratorSite Deployer
Community
Akumina Community Site
More
GitHubStar
Copyright © 2024 Akumina