Skip to content

JDF and JMF (ctx.jdf, ctx.jmf) ​

CoCoCo's print functionality adds JDF (Job Definition Format) and JMF (Job Messaging Format) support to the SCRIPT, CUSTOM_APP and INTEGRATION roles. It is not available in product-template resolver scripts.

FunctionReturns
ctx.jdf.parse(xml, options?)(ok, doc): the JDF document as a table
ctx.jmf.parse(xml, options?)(ok, doc): the JMF message as a table
ctx.jdf.loadTemplate(name)(ok, template): the value a JDF-template Script returns
ctx.jmf.loadTemplate(name)(ok, template): the value a JMF-template Script returns
device:jmf(xml, path?)(ok, { status, headers, body }): sends a JMF message to a device

All of them are asynchronous and return (ok, res). A parse failure returns false with the error message.

Parsing ​

lua
local input = ...
local xml = ""
if type(input) == "table" and type(input.jmf) == "string" then
  xml = input.jmf
end

local ok, doc = ctx.jmf.parse(xml)
if not ok then
  ctx.log.warn("JMF could not be parsed", { reason = tostring(doc) })
  return { parsed = false }
end

ctx.log.info("JMF parsed", { structure = inspect(doc) })
return { parsed = true, doc = doc }

Use inspect(doc) or the playground output to see the table structure of the documents your devices send before you write code against specific fields.

Template Scripts ​

A JDF or JMF template is a tenant Script whose role is JDF_TEMPLATE or JMF_TEMPLATE. loadTemplate runs that Script in a separate environment and returns the value it returns. That value crosses back as data (tables, strings, numbers, booleans); Lua functions cannot be passed back this way. Template Scripts run with the standard library, a clock and a random source, and no ctx services. A template that does not exist raises an error.

lua
local ok, template = ctx.jdf.loadTemplate("default-ticket")
if not ok then error(template) end

return { loaded = template ~= nil }

In integrations, loadTemplate takes the ID of a template Script resource declared in the manifest and bound on the instance, not a Script name.

Sending JMF to a device ​

A device handle from ctx.device.get or ctx.device.forWorkcenter has a jmf method. It POSTs the message with the content type application/vnd.cip4-jmf+xml to the device's configured address. path defaults to /.

lua
local input = ...
local message = ""
if type(input) == "table" and type(input.message) == "string" then
  message = input.message
end

local press = ctx.device.get("press-01")

local ok, resp = press:jmf(message, "/jmf")
if not ok then error(resp) end

return { status = resp.status, body = resp.body }

An empty message or an unknown device raises an error. Transport failures return false, message; an HTTP error status comes back with ok == true, so check resp.status.

Building JDF and JMF ​

ctx.jdf.build(operations) and ctx.jmf.build(operations) render an operation list to XML, and the print modules lib/jdf and lib/jmf (loaded with ctx.script.load) wrap them in builder APIs. The operation format and the builder method names are not documented here yet; check the type definitions and the API search in the console for the current surface before using them.

Connect machines, automate workflows, and build custom apps for print production.