Skip to content

Twig: Example Component

Rémy Denton edited this page Aug 12, 2022 · 22 revisions

Main Benefits

  1. Customizable HTML tag in the initially rendered markup
  2. Allowing the component's inner content to be overwritten via {{content}}. It's important to be agnostic about the details of the inner content (see the docs on Decoupling Bolt Components)
  3. Consistent formatting

Code

Example Component

{% set schema = bolt.data.components['@bolt-components-example'].schema %}

{% if enable_json_schema_validation %}
  {{ validate_data_schema(schema, _self)|raw }}
{% endif %}

{# Variables #}
{% set this = init(schema) %}
{% set inner_attributes = create_attribute({}) %}

{#
  Array of classes based on the defined + default props.
  - `spacing` example shows how to handle "string" values
  - `borderless` example shows how to handle "boolean" values
#}
{% set classes = [
  'c-bolt-example',
  this.data.spacing.value ? 'c-bolt-example--spacing-' ~ this.data.spacing.value : '',
  this.data.borderless.value ? 'c-bolt-example--borderless' : '',
] %}

{#
  Sort classes passed in via attributes into two groups:
  1. Those that should be applied to the inner tag (namely, "is-" and "has-" classes)
  2. Those that should be applied to the outer custom element (everything else EXCEPT c-bolt-* classes, which should never be passed in via attributes)
#}
{% set outer_classes = [] %}
{% set inner_classes = classes %}

{% for class in this.props.class %}
  {% if class starts with 'is-' or class starts with 'has-' %}
    {% set inner_classes = inner_classes|merge([class]) %}
  {% elseif class starts with 'c-bolt-' == false %}
    {% set outer_classes = outer_classes|merge([class]) %}
  {% endif %}
{% endfor %}


<bolt-example
  {% if outer_classes %} class="{{ outer_classes|join(' ') }}" {% endif %}
  {{ this.props|without('content')|without('title')|without('class') }}
  >
  <replace-with-grandchildren {{ inner_attributes.addClass(inner_classes) }}>
    {% if title %}
      <div class="c-bolt-example__title">
        {# `title` will go into "title" slot. This pattern may be used for any slotted content, can be renamed depending upon your needs. #}
        <div slot="title">{{ title }}</div>
      </div>
    {% endif %}

    <div class="c-bolt-example__content">
      {# `content` will go into "default" slot. Depending upon component, may be named something else, e.g. `text`, `items`, etc. #}
      {{ content }}
    </div>
  </replace-with-grandchildren>
</bolt-example>
Clone this wiki locally