3 - Handle Internal Links

Previous - Code DiffNext

Reset the workspace to step 3:

git checkout -f step-3

Internal Links

As you have noticed in the previous step internal links inside rich text content are not working in the app. In this step the app is extended with logic to resolve internal links.

Bloomreach Experience Manager defines internal links as links from one document in the repository to another document in the repository. Authors create them in the CMS by selecting some text in a rich text field and picking the target document. Because Bloomreach Experience Manager is decoupled from the frontend, internal links are stored in a frontend-agnostic manner: they are references to the target document's location in the repository. It is up to the frontend application to properly handle such links.

To help the frontend application do this the Document Detail resource's response includes for each rich text property a links object containing all links referred to in the rich text content.

For example in the response below the rich text property items['myproject:content'].content contains a link <a data-hippo-link=\"workshop\">workshop</a> which refers to items['myproject:content'].links.workshop.

{
   "id":"b8f5eb45-7200-452a-b26e-3118a0dc60b8",
   "name":"breakfast",
   "displayName":"Breakfast",
   "type":"myproject:eventsdocument",
   "locale":"en",
   "pubState":"published",
   "pubwfCreationDate":"2013-11-12T11:00:00.000+01:00",
   "pubwfLastModificationDate":"2016-01-27T11:50:56.865+01:00",
   "pubwfPublicationDate":"2016-01-27T11:50:58.640+01:00",
   "items":{
      "myproject:enddate":"2017-01-27T10:14:00.000+01:00",
      "myproject:location":"Room 101",
      "myproject:title":"Breakfast",
      "myproject:date":"2013-11-12T08:00:00.000+01:00",
      "myproject:introduction":"Start the day with a nice breakfast.",
      "myproject:content":{
         "type":"hippostd:html",
         "content":"<p>Breakfast is served starting from 8:00 until 9:30.</p><p>After breakfast it&#39;s time to start the <a data-hippo-link=\"workshop\">workshop</a>.</p>",
         "links":{
            "workshop":{
               "type":"local",
               "id":"7a29ec60-2689-48b2-aca2-49696c5c23eb",
               "url":"http://localhost:8080/site/api/documents/7a29ec60-2689-48b2-aca2-49696c5c23eb"
            }
         }
      },
      "myproject:image":{
         "type":"hippogallerypicker:imagelink",
         "link":{
            "type":"binary",
            "url":"http://localhost:8080/site/binaries/content/gallery/myproject/samples/coffee-206142_150.jpg"
         }
      }
   }
}

Code Changes

DocumentsController

The DocumentsController is extended with a function resolveLinks which takes a REST response like above, looks up each internal link and rewrites it to the proper target URL in the app. The processed rich text content is added to the scope so the view can render it.

app.js

contentRestApp.controller('DocumentsController', function($scope, $routeParams,
    DocumentsService, apiPrefix) {

  if (!$routeParams.uuid) {
    DocumentsService.getList().$promise.then(function(response) {
      $scope.documents = response;
    });
  } else {
    DocumentsService.getDocumentById($routeParams.uuid).$promise.then(function(
        response) {
      $scope.document = response;

      // resolve internal links
      $scope.content = $scope.resolveLinks(response);

      // TODO
      // resolve images

    });
  }

  $scope.resolveLinks = function(response) {
    var someElement = document.createElement('div');
    someElement.innerHTML = response.items['myproject:content'].content;
    var links = someElement.querySelectorAll('a[data-hippo-link]');
    for (var index = 0; index < links.length; index++) {
      if (response.items['myproject:content'].links[links[index]
          .getAttribute('data-hippo-link')]) {
        var uuid = response.items['myproject:content'].links[links[index]
            .getAttribute('data-hippo-link')].id;
        links[index].href = '#/' + uuid;
      }
    }
    return someElement.innerHTML;
  };

});

View

The detail view is slightly modified so it renders the processed rich text content instead of the raw property value from the response.

detail.html

<div>
  <h1>{{document.items['myproject:title']}}</h1>
  <p>{{document.items['myproject:introduction']}}</p>
  <div ng-bind-html="content"></div>
</div>

Experiments

  • Use Bloomreach Experience Manager to include an image in a document's rich text content. See how it's handled in the REST response. The same mechanism is used, and a URL to retrieve the image is included. Can you extend the resolveLinks function so that images in rich text content are also properly rendered? 

Summary

In this step the app was extended with logic to resolve internal links in rich text content. Now go to step 4 to learn how to search for documents using the Content REST API.

Previous - Code DiffNext

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?