Template Guide

Overview

Bausteinsicht uses a template draw.io file to define the visual appearance of elements and connectors. When new elements are created during forward sync, their style (color, shape, size) comes from this template.

The template file is a regular .drawio file that you can open and edit in draw.io. It contains one sample shape for each element kind, plus a connector sample. Bausteinsicht identifies these samples via special bausteinsicht_template attributes.

How It Works

During forward sync, when Bausteinsicht needs to create a new element on the diagram:

  1. It looks up the element’s kind (e.g., "container")

  2. It searches the template file for an <object> with bausteinsicht_template="container"

  3. It copies the style, width, and height from the template shape

  4. It copies sub-cell styles (title, technology, description) from the template’s child <mxCell> elements

  5. It creates the new element with label="" and container=1, plus child text sub-cells for title, technology, and description

If no matching template is found, a default rectangle (160×70) is used and a warning is displayed.

Template File Structure

The template file (template.drawio by default) is created by bausteinsicht init. It contains:

Template Type Purpose

Core element templates (actor, system, container, component)

Define the visual style for the standard C4 element kinds

Specialized element templates (datastore, ui, queue, mobile, filestore)

Define the visual style for common specialized element kinds: database cylinders, web frontends, message queues, mobile apps, and file stores

External system template (external_system)

Defines the visual style for external/third-party systems

Boundary templates (system_boundary, container_boundary)

Define the swimlane style when an element is used as a view scope

Connector template (relationship)

Defines the arrow/line style for all relationships

Identifying Templates

Templates are identified by the bausteinsicht_template attribute:

Element templates use an <object> wrapper with child sub-cell <mxCell> elements:

<object label=""
        id="template-container"
        bausteinsicht_template="container">  <!--(1)-->
  <mxCell style="rounded=1;fillColor=#438DD5;...;container=1;" <!--(2)-->
          vertex="1" parent="1">
    <mxGeometry width="240" height="150" />   <!--(3)-->
  </mxCell>
</object>
<!-- Sub-cell style templates (parent references template object ID) -->
<mxCell id="template-container-title" value="Title"  <!--(4)-->
        style="text;html=1;fontSize=14;fontStyle=1;fontColor=#ffffff;..."
        vertex="1" parent="template-container">
  <mxGeometry x="0" y="20" width="240" height="30" as="geometry" />
</mxCell>
<mxCell id="template-container-tech" value="[Technology]"
        style="text;html=1;fontSize=11;fontStyle=2;fontColor=#CCCCCC;..."
        vertex="1" parent="template-container">
  <mxGeometry x="0" y="55" width="240" height="20" as="geometry" />
</mxCell>
<mxCell id="template-container-desc" value="Description"
        style="text;html=1;fontSize=10;fontColor=#BBBBBB;..."
        vertex="1" parent="template-container">
  <mxGeometry x="0" y="80" width="240" height="40" as="geometry" />
</mxCell>
  1. The bausteinsicht_template attribute must match the element kind name from your model’s specification.elements

  2. The style string is copied to new elements. Must include container=1; for sub-cell grouping.

  3. The width and height are used as default dimensions

  4. Sub-cell templates define the font style, size, color, and vertical position for title, technology, and description text. ID suffixes (-title, -tech, -desc) identify the role.

Boundary templates follow the same pattern but with a _boundary suffix:

<object label="System Boundary"
        bausteinsicht_template="system_boundary">
  <mxCell style="swimlane;startSize=30;fillColor=#E8E8E8;..."
          vertex="1" parent="1">
    <mxGeometry width="400" height="250" />
  </mxCell>
</object>

The connector template is a bare <mxCell> (no <object> wrapper needed):

<mxCell bausteinsicht_template="relationship"
        style="edgeStyle=orthogonalEdgeStyle;endArrow=block;..."
        edge="1" parent="1">
  <mxGeometry relative="1" as="geometry" />
</mxCell>

Customizing the Template in draw.io

Step 1: Open the Template File

Open template.drawio in draw.io (desktop app or VS Code extension). You will see the template shapes arranged on a single page:

  • Top row: Core element templates (Actor, System, Container, Component)

  • Middle rows: Specialized shapes (Datastore, UI, Queue, Mobile, Filestore) and External System

  • Bottom row: Boundary templates (swimlanes)

  • Arrow: Connector template linking two elements

Step 2: Edit a Shape’s Style

To change an existing element’s appearance:

  1. Click on the template shape you want to modify

  2. Use draw.io’s formatting tools:

    • Fill color: Right-click → Edit Style, or use the Format panel

    • Border: Change strokeColor in the style

    • Font: Change fontSize, fontColor

    • Shape: Change the shape type (e.g., shape=mxgraph.c4.person2 for the person icon)

    • Size: Drag the handles to resize — the new width/height become the default for new elements

  3. Save the file

Important
Do not remove or rename the bausteinsicht_template attribute. Bausteinsicht reads this attribute to match templates to element kinds. If you edit the XML directly, keep bausteinsicht_template="<kind>" intact.

Step 2b: Edit Sub-Cell Text Styles

Each element template contains child text cells for title, technology, and description. To customize their typography:

  1. In draw.io, double-click into the template element to select a child text cell

  2. Use the Format panel to change font size, color, style (bold/italic), or alignment

  3. Drag the child cell to adjust its vertical position within the parent

  4. Save the file

Sub-cell IDs follow the pattern <template-id>-title, <template-id>-tech, <template-id>-desc. When editing XML directly, keep these suffixes intact.

Step 3: Edit the Connector Style

  1. Click on the arrow connecting two template elements

  2. Use draw.io’s edge formatting:

    • Line style: Straight, orthogonal, curved

    • Arrow head: Block, open, diamond, etc.

    • Color: Change strokeColor

    • Line width: Add strokeWidth=2 to style

  3. Save the file

Example: Changing Container Color to Green

In draw.io:

  1. Click the "Container Name" template shape

  2. In the Format panel, change Fill Color to #2D8659

  3. Change Font Color to #FFFFFF

  4. Save

Or edit the XML directly (Right-click → Edit Style):

rounded=1;whiteSpace=wrap;html=1;fillColor=#2D8659;fontColor=#ffffff;strokeColor=#1E5C3D;arcSize=5;fontSize=11;align=center;verticalAlign=middle;

After the next bausteinsicht sync, all new container elements will use the green style. Existing elements keep their current style.

Adding a New Element Kind

When you define a new element kind in your model’s specification (e.g., "database"), you should also add a template for it.

Step 1: Define the Kind in the Model

{
  "specification": {
    "elements": {
      "database": {
        "notation": "DB",
        "description": "A database or data store"
      }
      // ... other kinds
    }
  }
}

Step 2: Add the Template Shape

Open template.drawio in draw.io and create a new shape:

  1. Draw a rectangle (or any shape) on the template page

  2. Style it as desired (color, border, size)

  3. Right-click → Edit Data (or Edit Metadata)

  4. Add a custom property: bausteinsicht_template = database

  5. Save

Alternatively, edit the XML directly. Add inside <root>:

<object label=""
        id="template-database"
        bausteinsicht_template="database">
  <mxCell style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#60A917;fontColor=#ffffff;strokeColor=#4B8412;size=12;fontSize=11;align=center;verticalAlign=middle;container=1;"
          vertex="1" parent="1">
    <mxGeometry x="0" y="0" width="120" height="100" as="geometry" />
  </mxCell>
</object>
<!-- Sub-cell templates for the new kind -->
<mxCell id="template-database-title" value="Title"
        style="text;html=1;fontSize=14;fontStyle=1;fontColor=#ffffff;fillColor=none;strokeColor=none;align=center;verticalAlign=middle;movable=0;resizable=0;deletable=0;editable=0;"
        vertex="1" parent="template-database">
  <mxGeometry x="0" y="15" width="120" height="25" as="geometry" />
</mxCell>
<mxCell id="template-database-tech" value="[Technology]"
        style="text;html=1;fontSize=10;fontStyle=2;fontColor=#CCCCCC;fillColor=none;strokeColor=none;align=center;verticalAlign=middle;movable=0;resizable=0;deletable=0;editable=0;"
        vertex="1" parent="template-database">
  <mxGeometry x="0" y="45" width="120" height="20" as="geometry" />
</mxCell>
<mxCell id="template-database-desc" value="Description"
        style="text;html=1;fontSize=9;fontColor=#BBBBBB;fillColor=none;strokeColor=none;align=center;verticalAlign=middle;movable=0;resizable=0;deletable=0;editable=0;"
        vertex="1" parent="template-database">
  <mxGeometry x="0" y="65" width="120" height="30" as="geometry" />
</mxCell>

Step 3: Add a Boundary Template (Optional)

If the new kind can act as a container (has "container": true in the specification), add a boundary template too:

<object label="Database Boundary"
        id="template-database-boundary"
        bausteinsicht_template="database_boundary">
  <mxCell style="swimlane;startSize=30;fillColor=#E8F5E9;strokeColor=#4B8412;fontColor=#4B8412;fontStyle=1;rounded=1;arcSize=5;whiteSpace=wrap;html=1;container=1;collapsible=0;fontSize=12;"
          vertex="1" parent="1">
    <mxGeometry x="0" y="0" width="400" height="250" as="geometry" />
  </mxCell>
</object>

The boundary template is used when this element is the scope of a view and renders as a swimlane.

Fallback Behavior

Situation Behavior

Element kind has no matching template

A default rectangle (160×70 px, no style) is used. Warning: no template style for kind: <kind>

Boundary kind has no matching template

A default swimlane (400×300 px) is used. Warning: no boundary template for kind: <kind>_boundary

Connector has no template

A plain edge with default draw.io styling is used

Template shape has width/height of 0

Default dimensions are used (160×70 for elements, 400×300 for boundaries)

What Gets Copied from the Template

Property Copied? Notes

style string

Yes

The full mxCell style (colors, shape, borders, fonts, etc.)

width

Yes

Default width for new elements

height

Yes

Default height for new elements

Sub-cell styles

Yes

Font size, color, weight, and vertical position for title, technology, and description text cells

Sub-cell geometry

Yes

Y-position and height; width is scaled to the parent element width

label

No

Parent label is set to empty; text comes from sub-cell value attributes

Position (x, y)

No

New elements are placed by the layout algorithm

id

No

IDs are generated from the model element ID

Template vs. Existing Elements

Templates only affect newly created elements during forward sync. Changing a template does not retroactively restyle existing elements on the diagram.

To restyle existing elements, either:

  1. Delete them from the draw.io file and re-sync (they will be recreated with the new template)

  2. Manually edit their style in draw.io (layout changes are preserved during sync)

Using --template Flag

By default, Bausteinsicht looks for the template file next to the model file (same directory, matching name pattern). You can override this:

bausteinsicht sync --template /path/to/custom-template.drawio

This is useful for:

  • Sharing a template across multiple projects

  • Switching between different visual themes

  • CI/CD pipelines with a centralized template

Tips

  • Keep the template file in version control — it defines your project’s visual language

  • Use draw.io’s "Edit Data" dialog to set bausteinsicht_template — it’s safer than editing XML

  • Test changes by adding a new element to your model and running bausteinsicht sync

  • The template page is never shown in your architecture diagram — it’s only read during sync

  • The id attribute on template shapes (e.g., template-actor) is arbitrary and only needs to be unique within the template file

  • New element marker: New elements get a temporary red dashed border (strokeColor=#FF0000;dashed=1) on top of the template style, so you can spot them easily in draw.io