Have a custom page and admin panel point at the same widget?

We've a need to create an admin panel which shows the content from a particular (custom) widget, and also have a custom URL/page that shows the same widget. The admin page displays the widget correctly, but the custom page is blank & doesn't contain the widget.

If I disable the admin panel, the widget then shows up on the custom page.

I assume the admin panel has got there first, and made the widget somehow unavailable to the custom page.. is there any way around that?

using System;
using Telligent.Evolution.Extensibility.Urls.Version1;

namespace Blah.CustomPages
{
    public class CustomPages : INavigable
	{
		public string Name => "Custom Pages";
		public string Description => "Custom Pages";
		public void Initialize() { }

        void INavigable.RegisterUrls(IUrlController controller)
        {
            AddWidgetToPage(controller, "my-pages", "/my/url", "Page List", "d3ab728c-5e18-4fec-9e89-fe8f6b174faa");
        }

        // Small helper to cut down on the clutter above
        void AddWidgetToPage(IUrlController controller, string InternalPageName, string URL, string PageName, string WidgetGUID)
        {
            controller.AddPage(InternalPageName, URL, null, null, PageName, GetSinglePageWidgetDefinition(InternalPageName, WidgetGUID));
        }

        // Helper method that simplifies adding a single widget to a custom page
        PageDefinitionOptions GetSinglePageWidgetDefinition(string InternalPageName, string WidgetGUID)
        {
            return new PageDefinitionOptions
            {
                HasApplicationContext = false,
                SetCustomPageOutput = (context, outputController) => { },
                ParseContext = (context) => { },
                Validate = (context, accessController) => { },
                DefaultPageXml = GetSinglePageWidgetFragment(InternalPageName, WidgetGUID)
            };
        }

        // Return a standard XML fragment that represents a single widget on a page
        string GetSinglePageWidgetFragment(string InternalPageName, string WidgetGUID)
        {
            WidgetGUID = WidgetGUID.Replace("-", "");

            return $@"<contentFragmentPage pageName=""{InternalPageName}"" isCustom=""false"" layout=""Content"">
                    <regions>
                      <region regionName=""Content"" >
                        <contentFragments>
                          <contentFragment type=""Telligent.Evolution.ScriptedContentFragments.ScriptedContentFragment, Telligent.Evolution.Platform::{WidgetGUID}"" showHeader=""False"" cssClassAddition=""no-wrapper with-spacing responsive-1"" isLocked=""False"" configuration="""" />
                        </contentFragments>
                      </region>
                    </regions>
                    <contentFragmentTabs />
                  </contentFragmentPage>";
        }
    }
}

using System;
using System.Configuration;
using System.Collections.Specialized;
using Telligent.Evolution.Components;
using Telligent.Evolution.Extensibility.Administration.Version1;
using Telligent.Evolution.Extensibility.UI.Version1;
using Telligent.Evolution.Extensibility.Urls.Version1;
using Telligent.Evolution.Extensibility.Version1;

namespace Blah.AdminPanels
{

    public class PageList : IPlugin, IScriptablePlugin, IScriptedContentFragmentFactoryDefaultProvider, IAdministrationPanel, IPanel
    {

        private readonly Guid _factoryDefaultProviderId = new Guid("feb7cbc2-0d7d-44d9-987c-07d17872d919"); // Random GUID
        private readonly Guid _contentFragmentId = new Guid("d3ab728c-5e18-4fec-9e89-fe8f6b174faa"); // Points at a widget
        private readonly Guid _id = new Guid("1c434984-79f8-4886-a461-1204028ce75b"); // Random GUID
        private IScriptedContentFragmentController _widgetController;

        private readonly ISecurityService securityService = Telligent.Common.Services.Get<ISecurityService>();
        private readonly IContextService contextService = Telligent.Common.Services.Get<IContextService>();

        public string Name => "Page List";

        public string Description => "List of all our custom pages";

        public string PanelName => "Admin Page List";

        public string PanelDescription => this._widgetController.GetMetadata(this._contentFragmentId).Description;

        public void Initialize()
        {
        }

        public void Register(IScriptedContentFragmentController controller)
        {
            this._widgetController = controller;
            ScriptedContentFragmentOptions options = new ScriptedContentFragmentOptions(this._contentFragmentId)
            {
                IsEditable = true,
                CanBeThemeVersioned = true,
                CanHaveHeader = false,
                CanHaveWrapperCss = true,
                CanReadPluginConfiguration = true,
                HasAccess = (Func<int, PageContext, bool>)((userId, pageContext) => this.HasAccess(userId))
            };
            options.Extensions.Add((IContextualScriptedContentFragmentExtension)new PageList.PanelContext());
            controller.Register(options);
        }

        public Guid ScriptedContentFragmentFactoryDefaultIdentifier => this._factoryDefaultProviderId;

        public Guid AdministrationPanelCategoryId => AdminPanelCategory.Id; // Our own top-level panel

        public bool HasAccess(int userId) => this.securityService.For((ISecuredItem)Telligent.Evolution.Components.Node.Root).Does(this.contextService.GetExecutionContext().User).Have((Permission)SitePermission.ManageSettings);

        public string GetViewHtml() => this._widgetController.RenderContent(this._contentFragmentId, new NameValueCollection());

        public Guid PanelId => this._id;

        public int? DisplayOrder => new int?();

        public bool IsCacheable => this._widgetController.GetMetadata(this._contentFragmentId).IsCacheable;

        public bool VaryCacheByUser => this._widgetController.GetMetadata(this._contentFragmentId).VaryCacheByUser;

        public string CssClass => this._widgetController.GetMetadata(this._contentFragmentId).CssClass;

        public class PanelContext : IContextualScriptedContentFragmentExtension
        {
            public string ExtensionName => "context";

            public object GetExtension(NameValueCollection context) => (object)new PageList.ContextApi();
        }

        public class ContextApi
        {
            private readonly IThemeOrchestrationService ThemeOrchestrationService = Telligent.Common.Services.Get<IThemeOrchestrationService>();

            public string Dummy(string iterations, string connectionString, string containerName, string operation)
            {
                return "not implemented";
            }
        }
    }
}

If it isn't possible to do this, that's fine (I guess).. but it feels like it should be possible & I've just neglected a setting somewhere.



clarification
[edited by: Matt at 9:16 AM (GMT 0) on Mon, Oct 4 2021]
Parents
  •  I don't suppose you could take a look at this? Or should I raise with Support?

  • This is not currently allowed by design. A scripted plugin and a front UI widget render in very different contexts. A scripted plugin (especially one implementing an administration panel) is targeting unique functionality (within the administration client side API) and markup (administration formats and styling) vs a front UI widget which renders within the context of a theme and its styling. A scripted plugin can also be provided with private APIs and have access permissions defined whereas a front UI widget cannot.

    While both widget types can make use of public script APIs (including custom ones), it's a very unique situation that would have the exact same UI rendering in both locations.

  • Ahh, that makes total sense! Thank you for such a comprehensive reply Slight smile

Reply Children
No Data