Snippet Parameterization for Flare HTML5 Output Using AngularJS

Wouldn’t it be nice to be able to do this with snippets?

This is content in a snippet. Every time this snippet is used, the content is the same except for here: x

This is content in a snippet. Every time this snippet is used, the content is the same except for here: y

This is content in a snippet. Every time this snippet is used, the content is the same except for here: z

The text is the same except for one part that varies. The above could be accomplished with condition tags. But each value (x, y, and z) would require a separate condition tag. Without condition tags, three separate snippets would be necessary, four if the repeated content is to be reused. This post describes how to do the above with one snippet and AngularJS.

Maybe this post could use a simpler title. But the point is that variables in Flare are applied globally in outputs. To introduce locally varying behavior with Flare, additional condition tags, snippets, or variables must be added for each desired local behavior. In other words, Flare variables are global and condition tags and snippets are not convenient replacements for variables, local or global.

This has been discussed in previous posts in the context of a Flare to MediaWiki to Flare round trip. MediaWiki enables transclusion of content with MediaWiki templates. MediaWiki templates can have parameters. So MediaWiki supports locally varying behavior in transcluded content.

This poses a problem for exporting to MediaWiki and importing from MediaWiki. The closest Flare comes to MediaWiki templates is Flare snippets. Flare snippets do allow for locally varying behavior via conditions and snippet conditions. But that does not quite meet the functionality of MediaWiki templates.

But that’s okay. Flare is a single-source, multi-channel authoring tool and MediaWiki is a platform for wikis. These are different animals. Parameterization of snippets would be nice to have. But then again, it would introduce complications.

One way to add parameterization of snippets is with scripting. Unfortunately, a JavaScript solution limits the use to web-based outputs. The example which follows is only effective with HTML5 output.

AngularJS comes from Google. It is a JavaScript library which can be referenced in Flare content such as a snippet, topic, or master page. This example references the library on a master page. Here is the markup for the master page:

<?xml version="1.0" encoding="utf-8"?>
<html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" MadCap:lastBlockDepth="2" MadCap:lastHeight="153" MadCap:lastWidth="811">
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js">
        </script>
        <script src="../Data/topic-parameter-controllers.js">
        </script>
    </head>
    <body data-ng-app="">
        <MadCap:bodyProxy />
    </body>
</html>

The first script reference is to a public copy of the AngularJS library. The AngularJS documentation has some guidance about how to reference the library. Although there is guidance to place the reference at the bottom of the document for performance, this example places the reference at the top. Otherwise the variable content may briefly appear in the browser as it does in the snippet markup instead of as the parameter value.

The second script reference is to a JavaScript file which contains the AngularJS controllers and data used to implement parameters on snippets and to hold the values for those parameters. Keep in mind that this example is a simple use of AngularJS. The data and presentation concerns are separated in that the snippet lives in the markup and the controller and data (parameter values) live in a JavaScript file. But the idea behind AngularJS is to implement the Model View Controller pattern. This usage doesn’t go quite as far as building an application based on that pattern.

There is also an extra attribute in the body tag that tells AngularJS where to provide AngularJS functionality.

Now here is the topic:

<?xml version="1.0" encoding="utf-8"?>
<html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" MadCap:lastBlockDepth="7" MadCap:lastHeight="165" MadCap:lastWidth="746">
    <head>
        <link href="Resources/Stylesheets/Styles.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <h1>Topic Title</h1>
        <div data-ng-controller="topicParameterCtrl">
            <MadCap:snippetBlock src="Resources/Snippets/angular-example.flsnp" />
        </div>
        <div data-ng-controller="topic1ParameterCtrl">
            <MadCap:snippetBlock src="Resources/Snippets/angular-example.flsnp" />
        </div>
    </body>
</html>

There are two snippet references. Each is wrapped in a div tag. The attributes in these tags refer to controllers in the JavaScript file referenced on the master page. The controller cannot be applied to the snippet tag because that tag is replaced with the snippet when output is generated.

Remember, the point is there is only one snippet. Here is the snippet markup:

<?xml version="1.0" encoding="utf-8"?>
<html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" MadCap:lastBlockDepth="2" MadCap:lastHeight="62" MadCap:lastWidth="811">
    <head>
    </head>
    <body>
        <p>This is a snippet for {{name}}. The parameterization is accomplished with AngularJS. This only works with HTML5 targets.</p>
    </body>
</html>

The snippet has some text and this: {{name}}. This is a data binding. You can read about this special AngularJS markup here: ngBind and in the hello world. On that note, this post’s example is almost as simple as the hello world. The main complication is how to organize the Flare and AngularJS pieces.

Every instance of {{name}} will be replaced with the value in the controller reference in the div attribute data-ng-controller. This example implements a single parameter of ‘name’ for the snippet.

Here are the controllers for the snippets:

function topicParameterCtrl($scope) {
	$scope.name = 'Jack';
}

function topic1ParameterCtrl($scope) {
	$scope.name = 'Jill';
}

These are located in a file in the path Content\Resources\Data\topic-parameter-controllers.js. This script is loaded on the master page.

Here is the output. In the first instance of the snippet the name is Jack. In the second instance the name is Jill.

angularjs-example

Snippet parameterization for HTML5 output has been implemented. A zipped sample is here: http://tregner.com/example-projects/angular-example.flprjzip.

4 comments

  1. Does it work to add data-ng-controller=”xyz” to other tags than (e.g. )? I create HTML5, PDF and Word and this parameterization would help me, but for all three outputs not just for one.

    1. Thanks for reading! Sorry, this only works where JavaScript and AngularJS work. The value is rendered by the browser and not by the build process for the target. I was hoping with version 10, MadCap would add the ability to define a value for a placeholder inside of a snippet on a per instance basis. We didn’t get that. Although we did get the ability to differentiate values for Flare variables on a target by target basis. MadCap did improve the plug-in API to the point where I think snippet parameters could be implemented without the workflow being too awkward. Do you have some thoughts on how you would imagine that appearing in an extension to the Flare UI?

      1. Hmmm, so I have to go the old copy-paste way. I was hoping that version 10 would have something new when I cannot use parameterization. I don’t have another product idea, parameterization is ideal. The challenge is to find a good way for the author and for translation. Parameterization is good for the author who can reuse the text. But is a translator really able to translate the text? I am not sure.

  2. You can do that now.

    Here is some text that applies to X
    Here is some text that applies to Y
    Here is some text that applies to Z

    What you can do now is have just the one snippet: Here is some text that applies to XYZ.
    Apply a condition to the snippet (XYZ) and to the page.
    Then within the page use the new feature: snippet variables.

    Here is some text that applies to XYZ (select the paragraph and apply snippet variable X or Y or Z).
    It means you can now use all three sentences in the same page by modifying the variables used in each paragraph. At least that’s how I understand the new feature. I just played with it for 30 minutes.

    Oh, this is for Flare v12 by the way.

Leave a Reply to Thomas Tregner Cancel reply

Your email address will not be published.

HTML tags are not allowed.

250,803 Spambots Blocked by Simple Comments