close

Filter

loading table of contents...

Blueprint Developer Manual / Version 2307

Table Of Contents

6.2.1 Using Dynamic Fragments in HTML Responses

Basic concept

Fragments of responses generated by the Content Application Engine may depend on a context, for example session data or the time of day. If fragments of a response may not be valid for every request, and responses are cached by reverse proxies (like Varnish or a CDN), it's necessary to exclude those parts from the response and load them separately using techniques like AHAH / Ajax or ESI.

To load the fragments, a link scheme and a matching handler handling the bean's type are needed.

CAE Implementation

In order to support loading of fragments in a generic and almost transparent way, beans are wrapped in a (com.coremedia.blueprint.cae.view.DynamicInclude) bean when they are included in the view layer. Whether the bean is wrapped or not is decided using Predicate<RenderNode> implementations that are called with the current RenderNode. A RenderNode represents the current "self" object and the view it's supposed to be rendered in. If any of the available predicates evaluate to true, the bean and view is wrapped as described above.

      public class DynamicPredicate implements DynamicIncludePredicate {

  //only use DynamicInclude if view matches.
  private static final String VIEW_NAME="myView";

  public boolean apply(RenderNode input) {

    if (input == null) {
      return false;
    } else if (input.getBean() instanceof MyBean
            && VIEW_NAME.equals(input.getView())) {
      return true;
    }

    return false;
  }
}

    

Example 6.3. Predicate Example


The predicate has to be added to a predefined Spring bean in order to be evaluated:

      <customize:append id="addMyDynamicPredicates" bean="dynamicIncludePredicates">
  <list>
    <bean id="myPredicate“
          class=“DynamicPredicate"/>
  </list>
</customize:append>

    

Example 6.4. Predicate Customizer Example


Render fragment placeholder

After wrapping the bean, the DynamicInclude is then rendered by the Content Application Engine.

DynamicInclude beans are rendered just as other beans by the Content Application Engine. By default, the view DynamicInclude.ftl is used to render the beans. It will either add a placeholder DOM element that can be used to load the fragment using AHAH, or an <esi:include> tag, depending on whether there is a reverse proxy telling the CAE to do so using the Surrogate-Capability header. This is described in the Edge Architecture Specification.

Links to dynamic fragments

In order to generate a link for either AHAH or ESI, a separate link scheme must be created for each bean type that should be included dynamically.

If the fragment depends on the context (for example, Cookies, session or the time of day), the link scheme must have the prefix /dynamic/ (see UriConstants$Prefixes) so that a preconfigured interceptor will set all Cache headers necessary that downstream proxies never cache those fragments. Matching Apache and Varnish rewrite rules are provided by CoreMedia Blueprint.

      @Link(type = MyBean.class,
      view = "fragment",
      uri = "/dynamicfragment/mybean")
public UriComponents buildFragmentLink(Cart cart,
        UriTemplate uriPattern,
        Map<String, Object> linkParameters,
        HttpServletRequest request) {

    UriComponentsBuilder result =fromPath(uriPattern.toString());
    //parameter "targetView" needs to be added
    result.queryParam("targetView",linkParameters.get("targetView"));
    return result.build();
}

    

Example 6.5. Dynamic Include Link Scheme Example


Handling dynamic fragments

These links have to be handled by using a handler. The handler has to use the RequestParam "targetView" to be able to construct a ModelAndView matching the values as originally intended in the include including the original bean.

      @RequestMapping(value="/dynamicfragment/{mybean}")
public ModelAndView handleFragmentRequest(
       @PathVariable("mybean") String mybean,
       @RequestParam(value = "targetView") String view) {

  Object myBean = resolve(mybean);

  //do not create Page, return bean directly (!)
  ModelAndView modelWithView = createModelWithView(myBean, view);
  return modelWithView;
}

    

Example 6.6. Dynamic Include Handler Example


Preserve view parameters for dynamic fragments

When including fragments dynamically expect the same behaviour as for server side includes. This means that the view parameters which may include all kinds of objects need to be passed to subsequent templates.

To preserve these parameters a hashed string representation of the parameters will be appended by the IncludeParamsAppendingLinkTransformer as includeParams query parameter to the asynchronous call. When receiving the call, the IncludeParamsFilter will retrieve the view parameters back from the query parameter.

Note

Note

Custom URI paths, considered by the IncludeParamsAppendingLinkTransformer may be configured via cae.link-transformer.uri-paths property.

A server side secret for the hash generation has to be configured via cae.hashing.secret property.

Have a look at Table 3.1, “Configuration Properties with Prefix cae” in Deployment Manual for further information.

Warning

Warning

If the server side secret for the hash generation is not configured, the CAE generates a secret and prints it to the log. You may copy the secret value to your config. If the secret changes then hashes change and may break HTTP caching.

The following types of view parameters are supported for dynamic fragments:

  • primitives (boolean,int, float,long)

  • String

  • ContentBeans

  • Content

  • Maps and Collections of the above types.

Additional custom types may be configured via the cae.link-transformer.serializer-classes property.

Caution

Caution

For every custom type an IdScheme registered at the IdProvider is presumed.

Search Results

Table Of Contents
warning

Your Internet Explorer is no longer supported.

Please use Mozilla Firefox, Google Chrome, or Microsoft Edge.