Skip to main content

Build Script

When a build script is specified in the renderpdf configuration, the entrypoint to the rendering process is that script. Scripts can be written in CScript or Python. The default-script is written in Python. Many components in this script make use of mechanics that are used in other scripts and may serve as example for creating custom scripts.

In the following, we'll explain the most important parts of the script.

Boilerplate​

First, some boilerplate is needed to tell comet-renderer that the script is written in Python and unencrypted. Additionally, the comet-module is imported to make use of methods for interacting with the document through the comet pdf-renderer:

#!py
#pragma plain

import comet

In this default-project several libraries are imported and initialized upon connecting to the project. They're stored to a variable in the comet-module and can be accessed in later scripts during the rendering process to avoid having to import them from the library-folder for each script:

"""
Import this initializer-script and run its main-method:
comet.pyImport('[xml]/scripts/initialize_global_library_objects.py').main()

By default, this is done automatically when the comet-renderer connects to the project by a panelstatement (panelstatements.xml -> id: 92).
It does not need to be specifically called in the build-script, but we mention this here, as subsequent mechanics rely on it being executed at the beginning.

After this, the libraries / their objects from variables in the comet-module can be used in all your scripts:
"""
LOGGER = comet.lib_logger.Logger("BUILDSCRIPT")
LOGGER.wlog("Hello World!")

CONST = comet.lib_constants
LOGGER.wlog(CONST.SPAMANDEGGS)

PRIINTCLOUD = comet.lib_priintcloud
LOGGER.wlog(PRIINTCLOUD.ticket)

Retrieving data from the datafile​

This project-framework includes a library for interacting with the incoming datafile. It expects an XML-structure outlined here. To retrieve data from the datafile, initialize an instance of DataProdvider from the library library/framework/data_provider.py.

Specify the type of the node of the main-product in the datafile. To connect the dataprovider to a specific item with the previously given node-type, use the method set_string_id with parameter find_string_id=True. This should find the id of the first item matching the node-type. It is used as the product's string-id for further queries with the dataprovider and is required for many more processes in comet.

Now, attribute values of the found item can be retrieved using the class' methods. For more information, see the library's documentation.

my_datasource_lib = comet.pyImport('[xml]/library/framework/data_provider.py')
DATAPROVIDER = my_datasource_lib.DataProvider(node_type="product")
DATAPROVIDER.set_string_id(find_string_id=True)

STRING_ID:str = DATAPROVIDER.get_string_id()
LOGGER.wlog(f"found a string-id: {STRING_ID}")

my_value:str = DATAPROVIDER.get_attribute_value("my_attribute")
LOGGER.wlog(f"found an attribute-value: {my_value}")

Establishing a productlist​

Next to the lines of boilerplate-code, the most important step in the build-script is to start the process of placing product-templates on the document-pages.

In the default script, we highlight many ways to obtain information on the products and templates that should be used for populating the document. For example, template- and pagetemplate-IDs can be read from the XML-datafile. Or they can be retrieved from a predefined mapping in the templates.py-library using a given key.

These IDs are used to create a productlist which is then used as parameter in the method comet.product.establish. This starts the process of placing the selected product-templates into the document. The productlist must at least contain one product-item with information on the product's Id and the template's Id.

The productlist can be created by a custom logic, to establish multiple products, a product and its variants, multiple sub-templates for the same product, etc. It can contain page-items to designate a page-template and parent-page for the product-items, that follow the page-item. Also, this way pagebreaks can be forced between product-templates. The establish-method can also be called multiple times in case it is necessary to jump between pages.

info

In most projects a custom productlist is required, as most documents have specialized layoutlogic with custom layout components.

For more information on custom productlists see page Creating a custom productlist

Examples:

Manually create a productlists based on IDs found in XML-data
def main():
templates_lib = comet.pyImport('[xml]/library/framework/templates.py')
my_datasource_lib = comet.pyImport('[xml]/library/framework/data_provider.py')
DATAPROVIDER = my_datasource_lib.DataProvider(node_type="product")
DATAPROVIDER.set_string_id(find_string_id=True)

STRING_ID:str = DATAPROVIDER.get_string_id()
PAGE_TEMPLATE_ID: int = 1 # valid Id of Entry in Panel "Page Templates"
PARENT_PAGE: str = "A-Parent Page" # valid parent page in parent-document
TEMPLATE_ID: int = 2 # valid Id of Entry in Panel "Templates"

productlist: list[comet.CProduct] = [
templates_lib.create_comet_page(PAGE_TEMPLATE_ID,PARENT_PAGE),
templates_lib.create_comet_product(STRING_ID,TEMPLATE_ID)
]
last_page = comet.gDocument.getPages()[-1]
comet.product.establish(productlist, PAGE_TEMPLATE_ID, TEMPLATE_ID, last_page)

return 0
Automatically create a productlists based on IDs found in XML-data
def main():
templates_lib = comet.pyImport('[xml]/library/framework/templates.py')
my_datasource_lib = comet.pyImport('[xml]/library/framework/data_provider.py')
DATAPROVIDER = my_datasource_lib.DataProvider(node_type="product", find_string_id=True)
STRING_ID:str = DATAPROVIDER.get_string_id()

template_mapping: templates_lib.TemplateMapping = templates_lib.TemplateMapping(templates_lib.TemplateMapping.Method.BY_IDS_XMLDATA, DATAPROVIDER)
PAGE_TEMPLATE_ID, PARENT_PAGE, TEMPLATE_ID = template_mapping.get_mapping_ids()
productlist: templates_lib.ProductList = template_mapping.get_productlist([STRING_ID])

last_page = comet.gDocument.getPages()[-1]
comet.product.establish(productlist, PAGE_TEMPLATE_ID, TEMPLATE_ID, last_page)

return 0

For more explanation on this, check out the see page Creating a custom productlist

Load dynamic content on parent pages​

If the document contains layoutelements on parent pages (for example, page-headlines, chapter-names, ...) that have dynamic content based on the products on the pages, these can be loaded after establishing all products using a method of the comet-module. Remember to specify for each dynamic-element on a parent page how the String-Id should be assigned during templating in InDesign (Placeholder -> Context Menu -> Placeholders in Frames of Parent Pages -> First Product | Last Product | Do not link).

for page in comet.gDocument.getPages():
page.loadMasterItems()

Optional steps in a buildscript​

You may want to enrich the generated documents with further information like Bookmarks or Metadata or you might want to optimize the rendering process by preloading webimages.