Whole page replacement

One of our plugins requires the widget rending pipeline, but we remove the headers and footers of the page so just the content is displayed.  This was done previously using a IHttpFilter and in .net10 we would use some middleware. Can you think of a solution that would work in the new platform? 

Parents
  • Reflecting to modify the underlying stream is not going to be supported either.   What is the specific use case for this and can you provide examples?  Is there a reason you cannot define your custom url as a new route with a definition that omits headers, etc?  This is how oauth authorization works, it's a page route that's page definition only defines a content region.   This is the way the platform wants rendering to occur, modifying the rendering via code is not intended and can break core functionality

  • We have a requirement where a customer requires rendering just a single widget without any other widgets including locked ones on the page, so the page layout does indeed only have the one widget, but it renders the locked header and footer widgets.  We need just the single widget rendered, in the previous iterations we did this using a http post filter on the content once Verint had rendered the page.   

  • Can you provide an example of the API that was used so I can review it?    You can still accomplish this the way I described

  • [assembly: PreApplicationStartMethod(typeof(FourRoads.VerintCommunity.RenderingHelper.RenderingHelperApplicationStart), "Start")]
    
    public class RenderingHelperApplicationStart
    {
        /// <summary>
        /// Dynamically registers HTTP Module
        /// </summary>
        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(RenderingHelperModule));
        }
    }

    This didn't use API's as it wasn't possible and still isn't possible it seems.

Reply
  • [assembly: PreApplicationStartMethod(typeof(FourRoads.VerintCommunity.RenderingHelper.RenderingHelperApplicationStart), "Start")]
    
    public class RenderingHelperApplicationStart
    {
        /// <summary>
        /// Dynamically registers HTTP Module
        /// </summary>
        public static void Start()
        {
            DynamicModuleUtility.RegisterModule(typeof(RenderingHelperModule));
        }
    }

    This didn't use API's as it wasn't possible and still isn't possible it seems.

Children
  • We didn't support HttpModules, same as we don't support HttHandlers.  Where functionality was reasonable for extensibility we built APIs for them.  For example HttpHandlers are not supported, but RAW custom routes are the API equivalent.   HttpModules provide privileged access to low level application functions that could create significant issues functionally, performance wise an security wise within the platform.

    I suggest taking the route of defining the url and page as a content section only in a custom INavigable Plugin Type  plugin

  • That won't work as we need the theme, javascript and widget rendering, just not the header and footer regions, unless I have misunderstood some functionality?

  • Adding a page via that plugin with only a content region defined in the xml is only emitting widget regions, all platform related functionality is still provided, including css, javascript etc.   

  • Maybe I am misunderstanding something, if I wanted to render just one widget on the page, but not render anything in the header or footer regions including widgets that are locked in the theme how can you achieve that with INavigable Plugin Type? 

  • INavigable.RegisterUrls -> IUrlController.AddPage(...), PageDefinitonOptions.DefaultPageXml would be your page xml defining only the content region, not header or footer region.  In The content region xml you define the widget you want there.

    IUrlController Plugin Supplementary Type 

     PageDefinitionOptions Plugin Supplementary Type 

  • but that still renders the header and footer regions from the theme?

  • Additionally we have requirements where a plugin would want to stop rendering the header and footer widgets programmatically for any particular page. 

  • No, it does not. This is an example of a page doing just as I described.   It has no header or footer region for widgets to render in.

    As for other pages, it is not supported to alter the layouts or content of platform defined pages outside of what you can do in the UI, this is why there is no access to the default definitions, same as default widgets

  • There's a little more to this than I remembered. The default theme defines a stylesheet called "oauth.css" which is configured to render for authorization requests, which is a special case option available to theme file attachments. And in that stylesheet, it hides the header and footer (among other things). Is this ideal? No. Could a similar approach be adapted to hiding regions on other pages? Yes. 

    Similarly, the styling that that hides these elements could be applied dynamically on the client side too for cases where it needs to be programmatic.

    .

    Here's its stylesheet from the social theme, unmodified:

    /*
    When customizing this theme, it is recommended to use existing theme configuration or add override CSS/LESS 
    files instead of editing platform-defined CSS/LESS. This will make future upgrades simpler.
    
    Direct edits to platform-defined CSS/LESS is not prevented, but will require manual diff/merging when upgrading
    to new versions of this theme.
    */
    
    img { max-width: 100%; }
    
    .footer-fragments .layout, 
    .page-editing,
    .page-tabs,
    .admin-bar .navigation-list,
    .admin-bar fieldset.field-list,
    .poweredby-wrapper,
    .header-fragments-header,
    .header-fragments-footer,
    .footer-fragments,
    .footer-fragments-header,
    .footer-fragments-footer,
    .admin-bar,
    .admin-bar-header,
    .admin-bar-footer
    { display: none; }
    
    .header-fragments { min-width: 0; }
    .header-fragments .content-fragment { display: none; }
    .header-fragments .content-fragment.html-content { display: block; }
    .header-fragments .content-fragment.html-content .user-defined-markup > div, .header-fragments .content-fragment.html-content .user-defined-markup > p { display: none; }
    .header-fragments .content-fragment.html-content .user-defined-markup .site-banner-header,
    .header-fragments .content-fragment.html-content .user-defined-markup .site-banner,
    .header-fragments .content-fragment.html-content .user-defined-markup .site-banner-footer
    { display: block; padding: 0; margin: 0; }
    
    .header-fragments .content-fragment.html-content .user-defined-markup .site-banner { padding: 10px 0 0 10px; width: 280px; margin: 0 auto; }
    
    .header-fragments .layout, .content-fragment-page .layout { width: auto !important; min-width: 0 !important; max-width: 450px !important; margin: 0 auto; background: none; }
    .content-fragment-page .layout-header { display: none; }
    
    .layout-content.content-left-sidebar-right .layout-region.right-sidebar,
    .layout-content.sidebar-left-content-right .layout-region.left-sidebar,
    .layout-content.sidebar-left-content-center-sidebar-right .layout-region.left-sidebar,
    .layout-content.sidebar-left-content-center-sidebar-right .layout-region.right-sidebar,
    .layout-content.content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.split-sidebar-left,
    .layout-content.content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.split-sidebar-right,
    .layout-content.content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.right-sidebar,
    .layout-content.header-top-content-left-sidebar-right .layout-region.right-sidebar,
    .layout-content.header-top-sidebar-left-content-right .layout-region.left-sidebar,
    .layout-content.header-top-sidebar-left-content-center-sidebar-right .layout-region.left-sidebar,
    .layout-content.header-top-sidebar-left-content-center-sidebar-right .layout-region.right-sidebar,
    .layout-content.header-top-content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.split-sidebar-left,
    .layout-content.header-top-content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.split-sidebar-right,
    .layout-content.header-top-content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.right-sidebar,
    .layout-content.header-top-split-content .layout-region.right-sidebar,
    .layout-content.header-top-content-left-sidebar-right-footer .layout-region.right-sidebar,
    .layout-content.header-top-sidebar-left-content-right-footer .layout-region.left-sidebar,
    .layout-content.header-top-sidebar-left-content-center-sidebar-right-footer .layout-region.left-sidebar,
    .layout-content.header-top-sidebar-left-content-center-sidebar-right-footer .layout-region.right-sidebar,
    .layout-content.header-top-content-left-split-sidebar-right-top-single-sidebar-right-bottom-footer .layout-region.split-sidebar-left,
    .layout-content.header-top-content-left-split-sidebar-right-top-single-sidebar-right-bottom-footer .layout-region.split-sidebar-right,
    .layout-content.header-top-content-left-split-sidebar-right-top-single-sidebar-right-bottom-footer .layout-region.right-sidebar,
    .layout-content.header-top-split-content .layout-region.right-sidebar,
    .layout-content.header-top-split-content-footer .layout-region.right-sidebar,
    .layout-content.split-content .layout-region.right-sidebar
    { display: none; }
    
    .layout-content.split-content .layout-region.content,
    .layout-content.header-top-split-content .layout-region.content,
    .layout-content.header-top-split-content-footer .layout-region.content
    { width: auto; float: none; }
    
    .layout-content.content-left-sidebar-right .layout-region.content .content-fragment,
    .layout-content.sidebar-left-content-right .layout-region.left-sidebar .content-fragment,
    .layout-content.sidebar-left-content-center-sidebar-right .layout-region.left-sidebar .content-fragment,
    .layout-content.sidebar-left-content-center-sidebar-right .layout-region.content .content-fragment,
    .layout-content.content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.content .content-fragment,
    .layout-content.content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.split-sidebar-left .content-fragment,
    .layout-content.header-top-content-left-sidebar-right .layout-region.content .content-fragment,
    .layout-content.header-top-sidebar-left-content-right .layout-region.left-sidebar .content-fragment,
    .layout-content.header-top-sidebar-left-content-center-sidebar-right .layout-region.left-sidebar .content-fragment,
    .layout-content.header-top-sidebar-left-content-center-sidebar-right .layout-region.content .content-fragment,
    .layout-content.header-top-content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.content .content-fragment,
    .layout-content.header-top-content-left-split-sidebar-right-top-single-sidebar-right-bottom .layout-region.split-sidebar-left .content-fragment
    { margin-right: 10px; }
    
    .content-fragment.login-and-create-user .content-fragment-content .page { float: none; width: auto; }
    .content-fragment.login-and-create-user h3 { display: none; }
    .content-fragment.login-and-create-user .content-fragment-content .page { border-width: 0; background: none; padding: 0; }
    .content-fragment.login-and-create-user .page.login h2, .content-fragment.login-and-create-user .page.link-accounts h2, .content-fragment.login-and-create-user .page.login h3, .content-fragment.login-and-create-user .page.link-accounts h3 { float: none; width: auto; margin: 0 0 10px 0; display: block; }
    .content-fragment.login-and-create-user .login-options  { display: none; }
    .content-fragment.login-and-create-user fieldset.login, .content-fragment.login-and-create-user fieldset.collect-email, .content-fragment.login-and-create-user fieldset.link-accounts { width: auto; margin: 0; min-height: 0; }
    .content-fragment.login-and-create-user fieldset.login.inactive .field-list.login { display: none; }
    .content-fragment.login-and-create-user .login-providers { top: 0; left: 0; position: relative; width: auto; height: auto !important; margin: 6px 0; }
    .content-fragment.login-and-create-user fieldset { background: none; border-width: 0; padding: 0; }
    .content-fragment.login-and-create-user .login-providers .login-provider { width: auto; position: static; }
    .content-fragment.login-and-create-user .login-providers .login-provider .login-provider-icon-wrapper { display: none; }
    .content-fragment.login-and-create-user .login-providers .login-provider .login-provider-privacy p { width: auto; }
    .content-fragment.login-and-create-user .login-providers .login-provider a.connect { margin: 0 0 0 10px; position: relative; top: 0; float: none; }
    .content-fragment.login-and-create-user .login-providers .login-provider .login-provider-heading { float: none; margin: 0; max-width: none; }
    .content-fragment.login-and-create-user fieldset .field-list-description span { display: none; }
    .content-fragment.login-and-create-user fieldset.login ul { padding: 0; margin: 0; }
    .content-fragment.login-and-create-user .field-item .internal-link.submit-button { float: none; margin: 0 0 0 10px; }
    
    .content-fragment.login-and-create-user .content-fragment-content .page.join-manual, .content-fragment.login-and-create-user .content-fragment-content .page.join-manual.no-details { width: auto; padding: 0; }
    .content-fragment.login-and-create-user .join-providers { padding: 0; margin: 10px 0; }
    .content-fragment.login-and-create-user fieldset { display: block; }
    .content-fragment.login-and-create-user fieldset.join-account.no-details, .content-fragment.login-and-create-user fieldset.join-password.no-details { width: auto; float: none; }
    .content-fragment.login-and-create-user fieldset.join-password { background: none; }
    .content-fragment.login-and-create-user fieldset ul.field-list { margin: 10px 0; }
    
    .content-fragment-page.user-createuser .content-fragment, .content-fragment-page.user-forgottenpassword .content-fragment { padding: 0; }

  • The problem with this solution is that notifications and other things will fire as the widgets are still rendered.  However this will be useful for other applications.