Using UI Pages in a CMS Site without iFrames

This may not seem so exciting at first, but once you realize the potential of this technique the results can be pretty powerful. It’s no secret that a lot of content in ServiceNow’s ESS Portal lives inside iframes. I don’t want to get into why iframes suck or why having UI Pages and forms from the main interface showing in CMS is not ideal… so I’ll just assume you’ve used it enough to understand why it’s a problem.

This is far from a complete solution, but it highlights one technique that could be used to get rid of those pesky iframes as it pertains to UI Pages.

One of the challenges is that UI Pages usually need to live in both the CMS and the main interface. So the trick is to figure out how to distinguish between the two. The answer to that is in the URL that is used. If you visit: [instance]/kb_home.do it’s loading the UI page as normal. However if you insert “ess/” in front of the ui page name ([instance]/ess/kb_home.do), it will also load in the style sheets from that CMS site. The “ess” refers to the “url_suffix” field on the site. It will also populate a new variable called $[current_site], which really is the GlideRecord of the site record based on the url_suffix. What this allows us to do is distinguish between different sites and the main UI. Consider the following code:

In this example, if we had a header defined in a UI Macro included on our site, we could now also include that header (or footer, or custom markup) on any UI page when used with our site. This essentially removes the need for using iframes. Now it also opens up another can of worms, such as: instance upgrades, and modifying OOB records. However in my personal experimenting I have been able to use this method to bring the full service catalog and knowledge base into a CMS site, without using any iframes, and without causing upgrade issues. It does take some tinkering, but it’s doable with a little bit of work. To start I would definitely suggest cloning the UI pages and experimenting with the copy.

With this method we’re really just styling UI pages to look like a CMS site, there are many other ways of doing it and I’ve experimented with several with great results. However this method is fairly quick to get you started. I’d love to hear your feedback, and let me know if you have any questions.

18 comments

  1. Hi Nathan thanks for posting.

    This is an interesting solution for the iFrame problem in CMS.

    I’m wondering, if I created a copy of the UI Page ‘kb_home.do’ and made the changes you suggested above could I use this copy in a CMS site to avoid modifying OOB code?

    1. Joel,

      I tried literally a dozen different approaches to getting UI pages into CMS, and there are many ways of doing it, but this was the only way I found that didn’t break a bunch of logic and cause javascript errors. Knowledge base was actually simple, it’s Service Catalog that was a pain.

      So to answer your question, yes of course you can (and should) clone the files. The challenge is if you name it something different, then all the links (especially in Service Catalog) break. So the two solutions I see:

      – Clone the UI pages leaving the name the same, and then rename the original to something different. Upgrades are based off sys_id’s so your clone now becomes the new UI page but wont break the upgrade. It’s easy and works very well, and upgrade safe.

      – Clone the UI page and call it something totally different, but then you have to deal with all the broken hyperlinks and reworking the whole shopping cart (if Service Catalog).

      I’ve done both, and the easiest and fastest is just keeping the names the same. This allows you to quickly throw some headers/footers in there and call it done.

      However if you plan on fully gutting the code and stripping out all tables, then having a separate UI page is a better option. I will warn you, some elements are generated after page load via js_includes which makes it very difficult to change. But it’s a very worthwhile effort. I just recently rewrote the whole cart page to be fully responsive and it looks and functions beautifully even on mobile.

      Like I said this is just one way of doing it, I’d be happy to discuss some others if you’re interested. But keep me posted on how it goes for you.

      1. Hey, very interesting approach. I just wanted to mention regarding cloning the original page and renaming the original, the upgrade would still skip. Once you update the record (in anyway), the SN upgrade step assumes you now own the file and will skip it on upgrade. So just means you’ll need to keep an eye for it being skipped and looking at merging your customisations to the updated UI page (if it does get updated of course)

        1. Ahmed,

          I was originally told that simply changing the name would not cause it to be skipped. However upon further digging I believe you are correct. However after some searching around I found that after Calgary, the “active” field on a tracked record will not trigger a change. Both UI Macros and UI Pages allow for duplicate names so the answer is: clone it and keep the name the same and set the active field on the original to false.

          http://wiki.servicenow.com/index.php?title=Administering_Update_Sets

          1. Hello Nathan,

            there is no ACTIVE field on the UI Page table/form. Any idea what to do now ?

            Cheers
            Maros

  2. Hi Nathan,

    Thanks for sharing this. I have a questions here.

    1. I didn’t understand how can we avoid iFrames by using above approach, especially when we are using Service Catalog in CMS. Could you please provide information.

    2. when i type [instance]/ess/kb_home.do, i’m not sure how its opening “kb_home”. because “kb_home” is not part of ESS portal. simply UI Page.

    Regards,
    Hima Pallela

  3. Thank you for a great tip! This is working really well, except for one thing.. When I add a block to kb_view.do I get a lot of this printed on the ui page: “$[AMP]nbsp;$[AMP]nbsp;” Do you have an idea on how to escape that?

    Thanks again 🙂

    1. Hanna, that looks like a Jelly phasing issue to me. Using the code above, when you invoke a macro you are already in phase 2, so if that macro already references phase 2 ($[] instead of ${}) then it will print out the variable instead of processing it. You could either remove the spaces ( ) or try replacing the square brackets with curly brackets in the macro. Does that make sense?

  4. Hey Guys – I’m about a month into a new job working with ServiceNow – so bear with me please.
    I’m wondering why instead of using an iframe, we couldn’t make an AJAX request for the same content?

  5. Hi Nathan,

    I’m trying to implement a new cms and can’t figure how to incorporate my header and footer on standard UI Pages. This thread is the closest I have come to finding a solution. However I’m struggling to get the concept to work. Can you provide more details on how I can incorporate

    1. Ray, in this example I am using a UI Macro as a header and footer instead of the header content block (I’m guessing that’s what you’re trying to use). One of the advantages of using a normal UI Macro is that it can be included in both CMS and UI Pages using:

  6. Hey Nathan,

    In order to avoid iFrames for the Service Catalog portal page, I’m guessing you are building some custom components with HTML, Jelly and some JavaScript. But how are you pulling in a catalog item’s variables? If I have a catalog item that has 10 variables (including choice fields, reference fields, etc.), are you accessing the sc_cat_item variable tables, grabbing all of the items variables, and then generating an HTML template from those variables?

    I’m looking to avoid iFrames as well, but as you know, the Service Catalog sure makes this a pain in the ass 🙁

    Thanks,
    Mark

    1. Mark,

      Actually what I’m doing is creating a header & footer that I use in the portal. Then I include that same header & footer in the catalog UI pages if it is viewed through the portal. So the look and feel remains the same but all the catalog logic remains intact. Does that make sense?

  7. Hi Nathan,

    What should I do to place kb_list.do ui page in our cms site(uc) without using iframe. When I use iframe, kb_list.do place in uc cms site is not visible to public users (users who don’t have access to servicenow instance). Any help would be appreciated.

    Thank you.

    -John

  8. Hi Nathan,

    Congratulations!!!! Your Article was very useful.
    I have some doubts with Service portal functionalities.
    1. Using CMS Iframe we can load the Create new incident form inside the iframe and do all the action within the Same page.Whereas in Service Portal we use the Form Widget to call the Create New Incident form only the incident Table Client Scripts are getting Executed. If any Task table Client Script defined and it inherits in Incident Table are not working ?

    Why it is so?

Leave a Reply to Nathan Firth Cancel reply

Your email address will not be published. Required fields are marked *