Today we will look at a more advanced way of extending PageBuilder through custom development.
In InDesign, you can add structured metadata to the content in your documents.
In fact, this is how the PageBuilder Tagger plug-in stores any layout options and links to ADAM in the templates you create.
But you can also define your own tags and attributes which can be accessed through the PageBuilder API.
Suppose you want to develop a wild new feature that is currently not covered by the out-of-the-box behavior.
Say you want to add a variable horizontal offset to the item groups that are added to your catalog.
An ADAM field will be used to store the desired offset for each record or product in the database.
Here's what a simple record in ADAM for an item group with an offset of 40 points might look like:

To implement this feature, you write a custom CatalogBuilder that offsets each item group after it has been added to the catalog (we will show some code later on).
Your new feature turns out to be quite popular among your customers, but you notice that each customer wants to use a different field to specify the offset.
In fact, some of your customers want to use multiple offset fields for different design templates.
Ideally, you want to be able to specify the offset field that should be used within the design template itself.
That way your feature can be used in a much more generic way. So you tell your customers that they can choose the offset field
by tagging an arbitrary element in their design templates and adding an attribute with a predefined key to it.
Below you can see a design template where we have tagged an image and specified that the field with name "HorizontalOffset" should be used to determine the offset for each item group:

Let's take a look at some code now. As hinted on earlier, our custom CatalogBuilder uses a
custom RecordPaginateAction which overrides the OnPlaced method (in a way that is very
similar to previous blog posts). Here's the implementation for our OffsetRecordPaginateAction:
| C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
using System;
using System.Collections.Generic;
using System.Linq;
using Adam.Core;
using Adam.Core.Fields;
using Adam.Core.Records;
using Adam.DocMaker.Core;
using Adam.DocMaker.Core.Geometry;
using Adam.PageBuilder.Core.Extensions;
using Adam.PageBuilder.Core.Paginate;
namespace CustomTags
{
public class OffsetRecordPaginateAction : RecordPaginateAction
{
private const string _attributeKey = "OffsetFieldName";
public OffsetRecordPaginateAction(Application application) : base(application)
{
}
protected override void OnPlaced(PlaceTarget placeTarget)
{
// Select the tags on the elements in the placed item group.
IEnumerable<Tag> tags = placeTarget.Elements
.Select(element => element.Tag)
.Where(tag => tag != null);
// Look for an attribute that specifies the name of the offset field to use.
string fieldName = null;
if (tags.Any(tag => tag.Attributes.TryGetValue(_attributeKey, out fieldName)))
{
// Load the record that corresponds to the placed item group.
Guid? recordId = placeTarget.Elements.GetResolvedRecordId();
if (recordId.HasValue)
{
Record record = new Record(App);
record.Load(recordId.Value);
// If the offset field can be found in the current record,
// use its value to offset all elements in the item group.
NumericField field = record.Fields[fieldName].MyLanguage as NumericField;
if (field != null)
{
double offset = (double)field.Value;
foreach (Element element in placeTarget.Elements)
{
element.MoveBy(new SizeD(offset, 0));
}
}
}
}
}
}
}
|
The code and comments should be quite straightforward. The interesting bit is that custom tags and attributes
that were added in the InDesign template can be accessed through the PageBuilder API and can be used to implement
new functionality. While today's example may seem a bit far stretched, several partners have requested this kind of
extensibility. The next step could be to develop your own InDesign plug-in with an attractive UI to replace
manual editing of tags and attributes.
Of course we still need to show what the result of running our code looks like (using the kind of records and design template shown above).
In the catalog pictured below, each item group has been placed with a horizontal offset that was specified in the corresponding ADAM record:
