{# ---------- PAC-INFO MACROS ---------- #} {# These macros render semantic HTML with light class hooks. #} {%- macro key_value_table(pairs) -%} {# pairs: dict-like object #} {%- for k, v in pairs.items() -%} {%- if k != "key" -%} {%- endif -%} {%- endfor -%}
{{ k }} {{ v }}
{%- endmacro -%} {%- macro category_block(category) -%}
{{ category.__class__.__name__ }}
{{ key_value_table(category.segments_as_dict()) }}
{%- endmacro -%} {# Renamed from service_table_section/services_table - neither name matched what they render (both emit
s, not s), and the pairing read backwards (the "table" was the inner piece, the "section" wrapped it). #} {%- macro service_links(services) %}
{%- for s in services -%} {{ s.service_name }} {%- endfor -%}
{%- endmacro -%} {%- macro service_group_block(user_handover_group) -%}
from {{ user_handover_group.origin }}
{{ service_links(user_handover_group.services)}}
{%- endmacro -%} {%- macro reference(value, label=None, card_request_params=dict(), target_class=None, display_label=True) %}
{% if display_label %} {# The card above is the primary content; the label is always a real link too, on top of it - route_pac_id_url_for lets an issuer route it through their own page instead of linking straight to the PAC-ID's own URL. #} {% if route_pac_id_url_for is defined %} {{ label or value }} {% else %} {{ label or value }} {% endif %} {% endif %} {% if pac_card_url_for is defined %}
{% endif %}
{%- endmacro %} {%- macro attribute_row(a) -%} {%- endmacro -%} {%- macro attribute_group_block(ag) -%}
{{ ag.label }} (from {{ ag.origin }})
{% if is_reference(a.key) %} {{ reference(a.key, a.label)}} {% elif is_url(a.key) %} {{ a.label }} {% else %} {{ a.label }} {% endif %}
{{a.key}}
{% for value in a.value_list%} {%- if is_image(value) -%}
{{ label|e }}
{{ label }}
{%- elif is_reference(value) -%} {# Checked before is_url - a PAC-ID is itself a valid URL, so a bare (non-pyReference) PAC-ID string would otherwise always hit the generic link branch below and never reach the card. #} {{ reference(value)}} {%- elif is_url(value) -%} {# Same icon+label format as service_links' elements - reuses its classes rather than a parallel set, since the look is meant to be identical. #} {{ value }} {%- else -%} {{ render_text(value) }} {%- endif -%} {% if not loop.last %}
{% endif %} {% endfor%}
{%- for a in ag.attributes.values() -%} {{ attribute_row(a) }} {%- endfor -%}
{%- endmacro -%} {%- macro data_table_inline(dt) -%} {# Renders your DataTable structure; expects filters: is_data_table(dt) #} {%- if dt.data | length == 1 -%} {%- for i in range(dt.col_names | length) -%} {%- endfor -%}
{{ dt.col_names[i] }} {{ dt.data[0][i] }}
{%- else -%} {%- for rn in dt.col_names -%} {%- endfor -%} {%- for row in dt.data -%} {%- for e in row -%} {%- endfor -%} {%- endfor -%}
{{ rn }}
{{ e }}
{%- endif -%} {%- endmacro -%} {%- macro attached_data_block(attached_data) -%}
{%- for name, trex in attached_data.items() -%} {{ attached_data_trex(name, trex) }} {%- endfor -%}
{%- endmacro -%} {# One pictogram , preferring an explicitly-supplied image over the code-derived guess (see explicit_pictogram_images/hazard_pictogram_codes in lib/render_predicates.py). resolve_static_image() only searches flat filenames directly in the static root (Path(base_name).stem strips any directory component before it even searches) - no subdirectory, no extension needed, it tries svg/png/jpg/jpeg/webp itself. #} {%- macro pictogram_image(code, explicit_images=dict()) -%} {%- if code in explicit_images -%} {{ pictogram_name(code) }} {%- else -%} {{ pictogram_name(code) }} {%- endif -%} {%- endmacro -%} {# Shown once above the hazard/precautionary statement table (see hazard_pictogram_codes) rather than repeated per row - a hazard statement's pictogram is a property of the substance as a whole, and several codes commonly share the same one (e.g. H300/H310/H330 are all Skull-and-crossbones). #} {%- macro pictogram_strip(codes, explicit_images=dict()) -%} {%- if codes -%}
{%- for code in codes -%} {{ pictogram_image(code, explicit_images) }} {%- endfor -%}
{%- endif -%} {%- endmacro -%} {# GHS hazard/precautionary statement rows - code beside its full text, resolved from labfreed/utilities/ghs/ghs_statements.json (UNECE GHS Rev.7 Annex 3) rather than requiring the attribute value to carry the full text itself. Falls back to showing the raw value if the code isn't in that table (e.g. an EU-specific EUH code, which isn't part of the UN GHS document this was sourced from) - see developer-docs/design-choices.md. #} {# th/td classes match every other key/value table (key_value_table, attribute_row) - same 1/3-2/3 column widths and label bolding from .lf-table--kv, for free, no GHS-specific CSS needed. #} {%- macro hazard_statement_row(raw_value) -%} {%- set code = extract_statement_code(raw_value) -%} {{ code }} {{ hazard_statement_text(code) or raw_value }} {%- endmacro -%} {%- macro precautionary_statement_row(raw_value) -%} {%- set code = extract_statement_code(raw_value) -%} {{ code }} {{ precautionary_statement_text(code) or raw_value }} {%- endmacro -%} {%- macro attached_data_trex(name, trex) %}
{{ name }}
{%- for k, v in trex.items() -%} {%- endfor -%}
{{ k }} {%- if is_data_table(v) -%} {{ data_table_inline(v) }} {%- else -%} {{ v }} {%- endif -%}
{% endmacro %}