Oicana

Inputs

There are two types of inputs. A jsonjson input contains structured data while a blobblob input passes bytes and optionally metadata to the template. For example, in an invoice the items and customer data could be a jsonjson input and the company logo could be a blobblob input.

The Oicana Typst package

Template inputs are configured in the manifest file typst.tomltypst.toml. The Oicana Typst package determines the current values of inputs.


Early Alpha

The Typst package is not (yet) published on Typst universe. You will have to install it locally.

  1. Download and install the typship CLIthe typship CLI
  2. Clone the Oicana repository
  3. Run typship install localtypship install local in oicana/integrations/typstoicana/integrations/typst

See the template dependencies section for more information.


Add the following to the top of your main.typmain.typ file to initialize the package:


                                  
#import "@local/oicana:0.1.0": setup

                                  


                                  
#let read-project-file(path) = return read(path, encoding: none);

                                  
#let (input, oicana-image, oicana-config) = setup(read-project-file);

                                  
#import "@local/oicana:0.1.0": setup

                                  


                                  
#let read-project-file(path) = return read(path, encoding: none);

                                  
#let (input, oicana-image, oicana-config) = setup(read-project-file);

                                  
#import "@local/oicana:0.1.0": setup

                                  


                                  
#let read-project-file(path) = return read(path, encoding: none);

                                  
#let (input, oicana-image, oicana-config) = setup(read-project-file);

                                  
#import "@local/oicana:0.1.0": setup

                                  


                                  
#let read-project-file(path) = return read(path, encoding: none);

                                  
#let (input, oicana-image, oicana-config) = setup(read-project-file);


This snippet gives the Oicana package access to the Typst project's files. We can now use the return values from calling setupsetup in the rest of the template.

Defining inputs

We will use a jsonjson input to pass a name into the template. Add the following to the end of the typst.tomltypst.toml file:


                                  
[[tool.oicana.inputs]]

                                  
type = "json"

                                  
key = "info"

                                  
[[tool.oicana.inputs]]

                                  
type = "json"

                                  
key = "info"

                                  
[[tool.oicana.inputs]]

                                  
type = "json"

                                  
key = "info"

                                  
[[tool.oicana.inputs]]

                                  
type = "json"

                                  
key = "info"


The value of this input is now available in the template as input.infoinput.info, where infoinfo is the key of the input as defined in typst.tomltypst.toml.


While we develop the template, the value of the input will be nonenone, because there is no Oicana integration setting a value for it. We can change that by defining a defaultdefault or developmentdevelopment value for the input.

Default and Development values

Inputs can define two different fallback values, defaultdefault and developmentdevelopment. These fallback values differ in priority based on which mode the template is compiled in.


When compiling a template in development mode, input values have the priority

  1. Explicit input value (for example through an integration)
  2. developmentdevelopment value
  3. defaultdefault value


If you compile in production mode, the developmentdevelopment value is ignored:

  1. Explicit input value (for example through an integration)
  2. defaultdefault value


While developing an Oicana template in a Typst editor, it will be compiled in development mode. It makes sense to define developmentdevelopment values for all required inputs of you template to have a functioning preview.


Let's extend our input with a developmentdevelopment value. First create an info.jsoninfo.json file in the template directory:


                                  
{

                                  
  "name": "Chuck Norris"

                                  
}

                                  
{

                                  
  "name": "Chuck Norris"

                                  
}

                                  
{

                                  
  "name": "Chuck Norris"

                                  
}

                                  
{

                                  
  "name": "Chuck Norris"

                                  
}


Then extend the input definition and set the developmentdevelopment value to be info.jsoninfo.json:


                                  
[[tool.oicana.inputs]]

                                  
type = "json"

                                  
key = "info"

                                  
development = "info.json"

                                  
[[tool.oicana.inputs]]

                                  
type = "json"

                                  
key = "info"

                                  
development = "info.json"

                                  
[[tool.oicana.inputs]]

                                  
type = "json"

                                  
key = "info"

                                  
development = "info.json"

                                  
[[tool.oicana.inputs]]

                                  
type = "json"

                                  
key = "info"

                                  
development = "info.json"


In our template we can now use input.info.nameinput.info.name and the preview will show "Chuck Norris".


                                  
#import "@local/oicana:0.1.0": setup

                                  


                                  
#let read-project-file(path) = return read(path, encoding: none);

                                  
#let (input, oicana-image, oicana-config) = setup(read-project-file);

                                  


                                  
= Hello from Typst, #input.info.name

                                  


                                  
Now we can pass names into the template from any Oicana integration. We will set the name out of C#sym.hash in the next step.

                                  
#import "@local/oicana:0.1.0": setup

                                  


                                  
#let read-project-file(path) = return read(path, encoding: none);

                                  
#let (input, oicana-image, oicana-config) = setup(read-project-file);

                                  


                                  
= Hello from Typst, #input.info.name

                                  


                                  
Now we can pass names into the template from any Oicana integration. We will set the name out of C#sym.hash in the next step.

                                  
#import "@local/oicana:0.1.0": setup

                                  


                                  
#let read-project-file(path) = return read(path, encoding: none);

                                  
#let (input, oicana-image, oicana-config) = setup(read-project-file);

                                  


                                  
= Hello from Typst, #input.info.name

                                  


                                  
Now we can pass names into the template from any Oicana integration. We will set the name out of C#sym.hash in the next step.

                                  
#import "@local/oicana:0.1.0": setup

                                  


                                  
#let read-project-file(path) = return read(path, encoding: none);

                                  
#let (input, oicana-image, oicana-config) = setup(read-project-file);

                                  


                                  
= Hello from Typst, #input.info.name

                                  


                                  
Now we can pass names into the template from any Oicana integration. We will set the name out of C#sym.hash in the next step.

Inputs in the C# integration

With the input defined, we can update the packed template in the C# project. Run oicana packoicana pack in the template directory and replace example-0.1.0.zipexample-0.1.0.zip in the ASP.NET project with the new file.


Our compilecompile endpoint is currently calling var stream = template.Compile([], [], CompilationOptions.Pdf());var stream = template.Compile([], [], CompilationOptions.Pdf());. This compiles the template without any inputs. The first empty array are the jsonjson inputs and the second one the blobblob inputs.


Change the endpoint to set the name input we just defined.


                                  
app.MapGet("compile", () =>

                                  
{

                                  
    var input = new TemplateJsonInput("info", JsonSerializer.Deserialize<JsonNode>("{ \"name\": \"Baby Yoda\" }")!);

                                  
    var stream = template.Compile([input], [], CompilationOptions.Pdf());

                                  
    var now = DateTimeOffset.Now;

                                  
    // ... more code from before

                                  
});

                                  
app.MapGet("compile", () =>

                                  
{

                                  
    var input = new TemplateJsonInput("info", JsonSerializer.Deserialize<JsonNode>("{ \"name\": \"Baby Yoda\" }")!);

                                  
    var stream = template.Compile([input], [], CompilationOptions.Pdf());

                                  
    var now = DateTimeOffset.Now;

                                  
    // ... more code from before

                                  
});

                                  
app.MapGet("compile", () =>

                                  
{

                                  
    var input = new TemplateJsonInput("info", JsonSerializer.Deserialize<JsonNode>("{ \"name\": \"Baby Yoda\" }")!);

                                  
    var stream = template.Compile([input], [], CompilationOptions.Pdf());

                                  
    var now = DateTimeOffset.Now;

                                  
    // ... more code from before

                                  
});

                                  
app.MapGet("compile", () =>

                                  
{

                                  
    var input = new TemplateJsonInput("info", JsonSerializer.Deserialize<JsonNode>("{ \"name\": \"Baby Yoda\" }")!);

                                  
    var stream = template.Compile([input], [], CompilationOptions.Pdf());

                                  
    var now = DateTimeOffset.Now;

                                  
    // ... more code from before

                                  
});


Calling the endpoint now, will result in a PDF with the new name. Building on this minimal service, one could now start to accept inputs through the HTTP endpoint or add other inputs. Take a look at the open source ASP.NET example project on GitHub for a more complete showcase of the Oicana C# integration.