5. Manual template filling

5.1. Block object methods

The Block object allows to perform direct manual operations with the template variables and blocks using its attributes and methods described in the API section.

The following example illustrates the use of Block object methods to fill the template manually.

template = """
            SHOPPING LIST
  Items                             Quantity
--------------------------------------------
<ITEMS>
<FLAG>IMPORTANT! <^FLAG>MAYBE? </FLAG>
* <@FLAG><ITEM><+>                  <QTY><UNIT> kg<^UNIT> l</UNIT>
</ITEMS>
"""

#   flag, item,               qty, unit
data = (
    ("",  "apples",           "1", 0),
    ("!", "potatoes",         "2", 0),
    ("",  "rice",             "1", 0),
    ("",  "orange juice",     "1", 1),
    ("?", "cooking magazine", "", -1)
)

blk_template = blockie.Block(template)
blk_items = blk_template.get_subblock("items")
[blk_flag, blk_unit] = [blk_items.get_subblock(n) for n in ("flag", "unit")]

for item_data in data:
    blk_items.set_variables(item=item_data[1], qty=item_data[2])
    blk_flag.set(0 if item_data[0] == "!" else 1 if item_data[0] == "?" else -1)
    blk_unit.set(item_data[3])
    blk_items.clone()
blk_items.set()
print(blk_template.content)

Output:

                SHOPPING LIST
  Items                             Quantity
--------------------------------------------
* apples                            1 kg
* IMPORTANT! potatoes               2 kg
* rice                              1 kg
* orange juice                      1 l
* MAYBE? cooking magazine

Filling the whole templates manually is typically not needed and a data-driven approach should be preferred. However, the block fill handler can be utilized to perform more complex manual operations or to implement custom extensions that are not possible with the Block.fill() method alone.

The example below shows the use of Block.get_subblock() and Block.set() methods within the block fill handler:

def format_date(block: blockie.Block, data: dict, _clone_subidx: int) -> None:
    if isinstance(data["month"], str) and not data["month"].isdigit():
        # If month is specified by its name,
        # then make it uppercase and set the date format to: <MONTH> <DAY>
        data["month"] = data["month"].upper()
        block.get_subblock("date").set(vari_idx=1)
    else:
        # Set the date format to: <DAY>.<MONTH>.
        block.get_subblock("date").set(vari_idx=0)

blk = blockie.Block("The date is: <DATE><DAY>.<MONTH>.<^DATE><MONTH> <DAY></DATE>")
blk.fill({"day": 24, "month": 12, "fill_hndl": format_date})
print(blk.content)

Output:

The date is: 24.12.