6 Replies Latest reply on Dec 13, 2008 11:28 PM by dkrieger

    Injection of header content (title, scripts) with portal 2.7

    andixt

      Hi,

      How I can inject header content - titles, keywords, scripts, etc with new Portal 2.7? I have done as described in Reference Guide but unfortunatelly it doesn't work. My Portlet extends GenericPortlet and it overrides method doHeaders:

      public class InfoPortlet extends GenericPortlet {
       public void doView(RenderRequest request,
       RenderResponse response) throws PortletException,
       IOException {
      ....
      }
       public void doHeaders(RenderRequest request, RenderResponse response){
       Element element = response.createElement("title");
       element.setTextContent("My new web browser title");
       response.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, element);
       }
      }
      


      Also I have used previous way to set header content but it also doesn't work.
      response.setProperty("HEADER_CONTENT",getPageHeaderTags(metaHeaders));
      

      Layout of that pages includes

      ...
      <%@ taglib uri="/WEB-INF/portal-layout.tld" prefix="p" %>
      ...
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
       <meta http-equiv="Content-Type" content="text/html"/>
       <script type="text/javascript"></script>
       <p:headerContent/>
      </head>
      ...
      


      Seems like everything is done correctly but it doesn't work.
      Any help is appreciated.

        • 1. Re: Injection of header content (title, scripts) with portal
          claprun

          I have just tested the JSR 286 in Portal 2.7 and it works as expected. I haven't tested the old way to do things, though it should still work if you're not using JSR 286.
          Not sure what is wrong on your side.

          • 2. Re: Injection of header content (title, scripts) with portal
            theute

            For the title, don't forget to use the specific tag that ensure that it is included once only. (The tag is present in the shipped-in theme)

             <title><p:title default="<%= PortalConstants.VERSION.toString() %>"/></title>
            


            • 3. Re: Injection of header content (title, scripts) with portal
              andixt

              1. Ok, I have included in my layouts

              <title><p:title default="<%= PortalConstants.VERSION.toString() %>"/></title>
              

              And it really helped me. But only when I replaced portal-layout.tld from portal 2.6 with version from portal 2.7. I think this point should be noticed in reference guide in migration chapter. Also it should be noticed that we should add this specific tag to our layouts.

              2. Somehow my <p:headerContent/> started to output injected header contents from portlets. I don't know how. But the problem is that your tag handler (HeaderContentTagHandler) doesn't know how to parse w3c.dom.Element, so they just do simple Element.toString(). But, doing this, it returns following:
              [meta: null][meta: null][link: null] [script: null]

              for java code:
               Element element = response.createElement("title");
               element.setTextContent("Just small");
               response.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, element);
              
               Element elementK = response.createElement("meta");
               elementK.setAttribute("name", "keywords");
               elementK.setAttribute("content", "keyword,new keyword");
               response.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, elementK);
              
               Element elementD = response.createElement("meta");
               elementD.setAttribute("name", "description");
               elementD.setAttribute("content", "sample description");
               response.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, elementD);
              
              
               Element elementL = response.createElement("link");
               elementL.setAttribute("type", "text/css");
               elementL.setAttribute("rel", "stylesheet");
               elementL.setAttribute("href", "/local/yuruy.css");
               response.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, elementL);
              
               Element elementS = response.createElement("script");
               elementS.setAttribute("type", "text/javascript");
               elementS.setAttribute("src", "/local/yuruy.js");
               response.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, elementS);
              
               response.addProperty(MimeResponse.MARKUP_HEAD_ELEMENT, "<meta name="simple"></meta>");
              

              For last one "meta" no output at all.

              So, as you can see, it returns some object instead of valid xml tag string. I ahve found the message, that it's a bug, or maybe other behavior of java 1.5, because in 1.4.2 it returned proper xml string. More here:
              http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6181019

              So, what to do, what workaround use to have tags in page header? We are using xml-apis-1.3.03.jar for w3c.dom.Element

              • 4. Re: Injection of header content (title, scripts) with portal
                theute

                Can you please open a Jira for it ?
                Also if you have a patch in mind, that would be very helpful to attach it to the Jira.

                Thanks for the report !

                • 5. Re: Injection of header content (title, scripts) with portal
                  theute

                  What JVM are you using ?

                  I don't see the issue with a recent JDK 5: 1.5.0_15-b04

                  • 6. Re: Injection of header content (title, scripts) with portal
                    dkrieger

                    I am running into the same problem as andiXT.

                    I am running with JDK 6: 1.6.0_07

                    Doing a bit more inspecting I think I have found the problem, but unfortunately do not have a solid solution for it:

                    PortletResponseImpl creates an element based on the default document factory for your java implementation. In my case I get back an instance of org.apache.xerces.dom.ElementImpl

                    Inside of HeaderContentTagHandler when its going through the list of header elements, it simply appends the element to the output buffer. This forces a toString() call on the element. This is where the randomness may occur depending on the implementation.

                    I looked at the latest xerces source and the toString() implementation in NodeImpl (parent class for ElementImpl which contains toString() function) doesn't actually output the element in xml format, but instead is for debug purposes only:

                     //
                     // Object methods
                     //
                    
                     /** NON-DOM method for debugging convenience. */
                     public String toString() {
                     return "["+getNodeName()+": "+getNodeValue()+"]";
                     }
                    


                    I found a solution using Xerces to do the serializing. Its not that elegant of a solution, but it seems many of the elements that are injected via jboss-portlet.xml injection method are W3C Elements that throw UnsupportedOperationException.

                    I created a JIRA entry and patch which should resolve this issue for everybody:

                    https://jira.jboss.org:8443/jira/browse/JBPORTAL-2260