Skip to main content

Migrate from jsreport

jsreport templates with the Handlebars engine and the chrome-pdf or chrome-image recipe move to Formfeed almost unchanged: both render with Chromium, jsreport's chrome options are Formfeed's page settings, and header and footer templates use the same pageNumber and totalPages classes. What changes is what jsreport runs as code on your server: custom helpers and scripts.

Import templates​

Export from jsreport, in the Studio (Export) or with the CLI:

jsreport export templates.jsrexport --serverUrl=https://reports.fennlor.example

In the app: Templates → Import → jsreport, choose the .jsrexport file and pick the templates. Handlebars templates with a chrome recipe are preselected; child templates and components need no import of their own, because they are inlined into the templates that use them. Analyse shows a report per template, Create drafts makes a Handlebars template each.

With the CLI, in a template project:

formfeed import jsreport templates.jsrexport # every Handlebars chrome template
formfeed import jsreport templates.jsrexport --template invoices/invoice

Settings​

format, width, height, landscape, the four margins, displayHeaderFooter with headerTemplate and footerTemplate, printBackground, scale, pageRanges and waitForNetworkIdle are mapped to the template's settings (Page setup in the editor), and the title, author, subject and keywords of pdfMeta become the PDF metadata. chrome-image templates become image templates with their viewport size (1200 × 630 when the export has none), type (PNG or JPEG), quality, fullPage, and omitBackground as a transparent background.

waitForJS (window.JSREPORT_READY_TO_START) has no direct equivalent: set waitFor.selector in the template's settings.json or in the settings of the API request, and let your script add that element when it is done. The editor's settings form has no field for it. PDF passwords and mediaType: screen are not imported; the report names both. For a password, send post.password with the render (Starter plan and above). jsreport's localization files are not imported either: put the texts into the template's translations and print them with the t helper.

Assets​

{{asset "logo.png" "dataURI"}} and the other encodings are resolved from the export: images and fonts up to 256 KB become data URIs, text assets (CSS, scripts, utf8 and string encodings) are inlined, and an asset jsreport links from an http(s) address becomes that address. Larger files, assets the export does not contain and assets linked from the jsreport server become {{asset "logo.png"}} and are listed in the report. Formfeed's asset helper points at the workspace's file library: upload those files there under the same name (on the Files page or with formfeed files push) and the references resolve. A public HTTPS URL in their place works as well. A template that is larger than 1 MB after its assets are inlined is an error in the report; upload the large files instead. The jsreport 2 syntax {#asset logo.png @encoding=dataURI} is converted the same way.

Child templates​

{{childTemplate "invoices/lines"}} (and jsreport 2's {#child invoices/lines}) is replaced by the child template's content, which then renders with the same data. The report names child templates the export does not contain.

Components​

{{component "./address"}} is replaced by the component's content. Properties passed to a component are not carried over: the inlined content sees the surrounding data, so reference those values directly.

Helpers​

Custom helpers are JavaScript that jsreport runs on your server; Formfeed does not run custom code. The report lists every helper the template defines, and every call to one is an error, because it would fail the render. Most helpers have a built-in equivalent:

Typical jsreport helperFormfeed
number and currency formatting{{money total "EUR"}}, {{number qty 2}}
date formatting with moment{{date issued "dd.MM.yyyy"}}
sums and totals{{sum lines "total"}}
toJS{{{json value}}} (converted by the importer)
QR codes and barcodes<img src="{{qrcode url}}" alt="QR code">, <img src="{{barcode sku type="code128"}}" alt="Barcode {{sku}}">

For anything else, compute the value in your application and send it with the data. The pdf-utils helpers (pdfAddPageItem, pdfCreatePagesGroup) and module have no equivalent.

Engines​

Formfeed runs Handlebars, Liquid and Jinja2. jsrender, EJS and Pug templates are imported as Handlebars drafts with an error: rewrite them in one of the three languages. A template without an engine (none) becomes a Handlebars template.

Recipes​

chrome-pdf and chrome-image are supported, and the html recipe becomes a PDF template. Excel, Word and other recipes are reported and imported as PDF templates for reference.

Scripts​

jsreport scripts (beforeRender, afterRender) usually load data before the render. Load that data in your application and send it with the render request; Formfeed renders what it receives.

pdf-utils​

Merge, append and prepend operations and headers taken from another template are not imported. Render the parts as separate documents, or combine them in one template with page breaks ({{pageBreak}}).

Sample data​

The data entity a template points at becomes its default data set; completion, the preview and the report's check for missing variables use it.

Switch the API​

jsreport's POST /api/report becomes a render. The import creates drafts, and the API renders the published version, so publish each template first. The request names the template by its slug (the template's name in lowercase with dashes) and sends the data that jsreport's request carried:

curl https://api-eu.formfeed.dev/v1/renders \
-H "Authorization: Bearer ff_live_…" \
-H "Content-Type: application/json" \
-d '{ "template": "invoice", "data": { "number": "R-7", "total": 12.5 } }'