3 Replies Latest reply on Jul 23, 2012 11:52 AM by iHomaid

    Creating a Global Function

    Jayatl Level 1

      Hello,

       

      I’m trying to create a global function that can be used by all of my components at runtime.  My confusion is where to put the function (I keep reading that the /apps/ folder is not available to the dispatcher) and how to get the return value.  Here’s an example of simple local cookie function that I’d like to be able to call from any of my components.

       

       

      <%@page import="javax.servlet.http.Cookie"%>
      <%
       boolean myCookie = false;     
       Cookie[] cookies = request.getCookies(); 
        for(int i = 0; i < cookies.length; i++) { 
         Cookie c = cookies[i];
            if (c.getName().equals("myaccount")) {
              myCookie = true;
            }
         }
      %>
      

       

      Thanks - using CQ 5.5 Update 1

        • 1. Re: Creating a Global Function
          tb7032

          Hi Jayatl,

           

          Just to confirm - you're trying to write a Java utility method which you want to reference in JSPs (at the server side)? If so, the Dispatcher doesn't directly come into it, as that caches the output of rendering the page (ie executing all the component scripts/jsps). Having said that, looking at the intended behaviour of code above, you do probably want to think about how cacheable it would be, but that's another matter.

           

          Essentially you're probably wanting to define a method available in all component JSPs. In JSP, there is a standard mechanism for defining methods within JSPs, as described here - http://www.jguru.com/faq/view.jsp?EID=1010.

           

          However, how to make it available to all your component JSPs?

           

          You've probably noticed that component JSPs generally statically include '/libs/foundation/global.jsp' (imagine <%@include as pasting in the other file into this file, so all variables are visible to the including page, in contrast to other includes like sling:include or cq:include). This is done like so:

           

          <%@ include file="/libs/foundation/global.jsp" %>

           

          Its the code executed by this included JSP which defines 'currentPage' and all the other objects available to components JSPs.

           

          You shouldn't edit this file directly (as it's under libs) but you could create a new file at /apps/[your project]/global.jsp and add the include above (to include the original foundation global.jsp) then add the method to that JSP (add described in the link above). Then you could change the include at the top of your component JSPs to include the new global.jsp. Everything declared in the original global.jsp and your own global.jsp will be available to your components...

           

          However .... IMO a valuable approach with CQ is to minimize the amount of logic in JSPs, and factor it back to Java classes (where automated unit tests can be written against it). As such, a far better approach would be to create a new OSGI bundle and implement the functionality in a Java class (ie CookieUtils), which is made available to JSPs by 'exporting' the containing package from the bundle. Even better would be to declare it as as service implementing a separate interface (ie CookieService / CookieServiceImpl), and look up the implementation of that service interface in your JSP like so:

           

          <% CookieService cookieService = sling.getService(CookieService.class); %>

           

          Given what a fundamental best practice it is, the approach to buidling and deploying OSGI bundles is under documented in the CQ docs, but it is mentioned under 'DEVELOPING IN JAVA WITH ECLIPSE AND CQ5' at http://dev.day.com/docs/en/cq/current/developing/developmenttools/developing_with_eclipse. html.

           

          It will be more work initially, and seem like overkill, but is a far more scaleable way to be implementing logic for use in components, and will allow you to automate the testing of that logic (which will help massively with preventing regressions in your code as you extend it in the future).

           

          Hope this helps.

           

          regards,

           

          tom

          • 2. Re: Creating a Global Function
            Jayatl Level 1

            Wow - thank you.  That was the most thorough answer I've seen on this forum.

            • 3. Re: Creating a Global Function
              iHomaid Level 1

              Great and well explained response. Thanks Tom.