Archive

Archive for the ‘Hippo’ Category

Custom workflows in Hippo CMS 7

Customizing the CMS workflow is one of the things you eventually come across in almost every CMS implementation, be it minor tweaks or a complete rethink.
In Hippo CMS, the workflow configuration is part of, and stored in, the JCR content repository.
After some searching for workflows in Hippo CMS, you will ultimately find Hippo’s page about hooking into the default workflow.
It’s a fine step by step manual, and it serves as a good starting point, were it not for the fact that it’s quite outdated and does not function anymore.
Read along to find out how to make things work in Hippo CMS 7.6.
Read more…

Categories: Hippo, Java Tags: , , , ,

Geo-location based content (Intro)

The deeper we go into the mobile age the more location based services surround us. Content management systems also have to keep up. In the end – location based-content always follows the location based services.

Being open source enthusiast I am using Hippo CMS for one of my hobby projects where I need to have the ability to tag content with GPS coordinates so that I could use, for example Google Maps, to show how the content is related to a certain place.
Read more…

Using JSON in HST configuration

In some situations the Hippo Site Toolkit component parameter configuration is somewhat limiting.
This is the case when we need to configure a list of repeating options for the layout of a component, say for example a list of JavaScript generated columns or spotlights.
Normally we would break the component up into a parent(container): child(multiple) configuration, but for the sake of this article we will use another solution: JSON.

JSON notation will allow us to configure complex behavior into a page or component in a way that is easy to read and maintain.
The HST is using JSON notation for its faceted navigation configuration.

So far so good, but in the fast lane of a common Hippo Project we really don’t want to spent time on learing some complex jaxb based framework just to read some JSON objects.
This is where GSON shines: creating and reading JSON from and to objects is just 3 lines of code, as it should be.

Configuration

To get this to work we need to do three types of configuration:

  1. first we need to add GSON to our POM
  2. second we need to configure our HST Page or Component
  3. third we need to create our bean

POM Configuration

First we need to add the GSON repository, which is located at a Google svn location:

 <repository>
   <id>gson</id>
     <url>http://google-gson.googlecode.com/svn/mavenrepo</url>
     <snapshots>
       <enabled>false</enabled>
     </snapshots>
    <releases>
      <enabled>true</enabled>
      <updatePolicy>never</updatePolicy>
    </releases>
 </repository>

Next we need to add GSON to our site project:

 <dependency>
   <groupId>com.google.code.gson</groupId>
   <artifactId>gson</artifactId>
   <version>1.6</version>
 </dependency>

HST configuration

In our next example we will be setting up  some layout parameters for a list JavaScript generated set of spotlights on a webpage, with the help of json notation.
We will be grouping all advancedoptions into one list.
For this case Option 1 and 2 have a different set of attributes (title, label ~ sitemap)

 <sv:property sv:name="hst:parameternames" sv:type="String">
   <sv:value>advancedoptions</sv:value>
 </sv:property>
 <sv:property sv:name="hst:parametervalues" sv:type="String">
   <sv:value>
   [
     {"name":"option1", 
     "folder":"option-one", 
     "title":"What are my options?", 
     "label":"More options?", 
     "number":1
     },
     {"name":"option2", 
     "folder":"option-two", 
     "sitemap":"whee", 
     "number":2
    }
    ]
  </sv:value>
</sv:property>

Bean Configuration

In the bean all possible options need to be there

/**
 *  Config bean, for GSON to fill with json configured objects  
 */
public class AdvancedOptions {
 private String name;
 private Integer number;
 private String folder;
 private String sitemap;
 private String title;
 private String label;

 //getters and setters ...

}

HSTComponent

Next we need to read the json objects into our list of optionbeans.
To do this we need to tell gson what kind of list we need, with a Type object.
Passing the json string with the list Type into the GSON converter gives us a List with the beans we need.

...
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * retreives a map of layout options for one or more columns
 */
public class AdvancedOptions extends BaseHstComponent
  {

  private static final String ADVANCED_OPTIONS = "advancedoptions";

   @Override
   public void doBeforeRender(final HstRequest request, final HstResponse response) throws HstComponentException {
     request.setAttribute(ADVANCED_OPTIONS, getAdvancedOptions(request));
   }

   /**
    * get spotlight configuration
    * @param HstRequest
    * @return
    */
   private List getAdvancedOptions(final HstRequest request) {
     final String options = getParameter(ADVANCED_OPTIONS, request);
     if (StringUtils.isNotBlank(options)) {

       // <- start up the gson converter
       final Gson gson = new Gson();

       // configure the list type for the gson converter
       final Type listType = new TypeToken>() {}.getType();

       //convert the json config to a list
       return gson.fromJson(options, listType);
     } else {
       log.warn("Failed to retrieve options from component configuration");
     }
   }
}

Conclusion

Using JSON you can add advanced capabilities to your HST configuration, such as complex beans with lists and arrays, without losing the readability or maintainability of our component configuration.
GSON is a lightweight JSON converter which is easy to learn, this will allow you to use JSON without loosing developing speed.
Converting from and to beans comes at a costs, so for some situations you might want to cache the result into a concurrent hashmap for future requests.

eof

Categories: Hippo Tags: , ,

HST and mockito sitting on a tree

19/10/2010 3 comments

Unit testing your Hippo Site Toolkit components with mockito is so easy, there really is no excuse to not test your hst components any more.
Say you have a component that retrieves a bean from a node, that code might look like this:

public class AnHstComponent extends BaseHstComponent{
  @Override
  public void doBeforeRender(HstRequest request, HstResponse response) throws HstComponentException {
  HippoBean bean = getContentBean(request);
  if(bean!=null) {
    request.setAttribute("document",bean);
    }
  }
}

All we would want to test here is that the HippoBean is retrieved and put on the request
This is not an integration test, but a unit test. So we don’t need or want any interaction with any real JCR repository.
To prevent this we mock the HstRequest and HstResponse interfaces and stub the getContentBean(HstRequest) method.
The test code would then look like this:

@RunWith(MockitoJUnitRunner.class)
public class AnHstComponentMockitoTest {
  @Mock public HstRequest request;
  @Mock public HstResponse response;
  @Spy public AnHstComponent component = new AnHstComponent();
  @Test
  public void testDocumentOnRequestAfterDoBeforeRender() throws Exception {
    //stub
    doReturn(new HippoDocument()).when(component).getContentBean(request);
    //test
    component.doBeforeRender(request, response);
    //verify
    verify(request).setAttribute(anyString(), any(HippoDocument.class));
  }
}

An explanation of the test code

The request and response interfaces are mocked, we can use these to stub any methods we need and verify any operations on it.
These mocked interfaces are passed on to the doBeforeRender method of our HSTComponent.

Since the getContentBean method is part of the BaseHstComponent, we need to partially mock the AnHstComponent.
This is done using mockito’s @Spy technique, which we can use to stub the getContentBean method.
In mockito stubbing is usually done with the When() method.
During stubbing the getContentBeans method is actually called upon using this technique on our real object. This will generate a null pointer exception.
To work around this you can use the doReturn method, which will prevent the real getContentBean method ever to get called.

It is this easy to create a simple testcase for your HstComponent, now go on an create your own!! :-)

ps. Jeroen Reijn has an example testing hst components with easy mock.

Categories: Hippo, Java Tags: , ,
Follow

Get every new post delivered to your Inbox.