{% deprecated 'The "@ContaoCore/Image/Studio/_macros.html.twig" template will be removed in Contao 6. Use the "component/_figure" component from the @Contao namespace instead.' %}

{# @var \Contao\CoreBundle\Image\Studio\Figure figure #}

{#
    Studio Macros
    -------------
    This collection of Twig macros is intended to help you render figure/image
    markup directly from a Studio\Figure. You can use these macros as building
    blocks for your own figure template or to render the whole thing and pass
    some options.


    Options
    -------
    By setting options, the default output can be altered. There are two places
    where this can be done:

      1) By constructing a Studio\Figure object with $options
      2) By passing the $options argument to the macros

     If the same keys are defined in both 1) and 2), the template options
     will have precedence.

     Currently, options allow you to extend/overwrite HTML attributes for all
     tags that are output. Attributes defined under the 'attr' key will be
     placed inside the <figure> tag while those defined under the '%tag%_attr'
     key will end up inside the <%tag%> tag.

     Example:

        {{ _self.figure(figure, {
            attr: { data-foo: 'a' },
            figcaption_attr: { class: 'bar' }
        } }}

        :  <figure data-foo="a">
        :    ...
        :    <figcaption class="bar">
        :      ...
        :    </figcaption>
        :  </figure>
#}

{#
    Build a <figure> including a picture and - if available - a caption from
    Studio\Figure data.

    If a link is defined the picture will be wrapped in an <a> tag.
#}
{%- macro figure(figure, options = {}, addSchemaOrg = true) -%}
    {%- set figure_attributes = figure.options.attr|default({})|merge(options.attr|default({})) %}
    {%- set link_attributes = figure.options.link_attr|default({})|merge(options.link_attr|default({})) ~%}
    <figure{{ _self.html_attributes(figure_attributes) }}>
        {% if figure.linkHref -%}
            {%- set base_attributes = {
                'href': figure.linkHref,
                'title': figure.hasLightbox and figure.hasMetadata ? figure.metadata.title : null,
            }|merge(figure.linkAttributes) -%}
            <a{{ _self.html_attributes(base_attributes|merge(link_attributes)) }}>
                {{~ _self.picture(figure, options) }}
            </a>
        {%- else %}
            {{- _self.picture(figure, options) -}}
        {% endif %}
        {{ _self.caption(figure, options) }}
    </figure>
    {% if addSchemaOrg %}
        {%- do add_schema_org(figure.schemaOrgData) -%}
    {% endif %}
{%- endmacro -%}

{#
    Build a <picture> from Studio\Figure data.

    This falls back to only creating a single <img> if no sources are present.
#}
{% macro picture(figure, options = {}) %}
    {%- set picture_attributes = figure.options.picture_attr|default({})|merge(options.picture_attr|default({})) %}
    {%- set source_attributes = figure.options.source_attr|default({})|merge(options.source_attr|default({})) %}

    {%- if figure.image.sources -%}
        <picture{{ _self.html_attributes(picture_attributes) }}>
            {% for source in figure.image.sources %}
                {%- set define_proportions = source.width|default(false) and source.height|default(false) -%}
                {%- set base_attributes = {
                    'srcset': source.srcset,
                    'sizes': source.sizes|default(null),
                    'media': source.media|default(null),
                    'type': source.type|default(null),
                    'width': define_proportions ? source.width : null,
                    'height': define_proportions ? source.height : null,
                } -%}
                <source{{ _self.html_attributes(base_attributes|merge(source_attributes)) }}>
            {%- endfor %}

            {{ _self.img(figure, options) }}
        </picture>
    {%- else %}
        {{ _self.img(figure, options) }}
    {%- endif %}
{% endmacro %}

{#
    Build an <img> from Studio\Figure data.
#}
{%- macro img(figure, options = {}) -%}
    {% set img_attributes = figure.options.img_attr|default({})|merge(options.img_attr|default({})) %}

    {% set img = figure.image.img %}
    {% set define_proportions = img.width|default(false) and img.height|default(false) %}

    {% set base_attributes = {
        'src': img.src,
        'alt': figure.hasMetadata ? figure.metadata.alt : '',
        'title': figure.hasMetadata ? (figure.metadata.title ?: null) : null,
        'srcset': img.srcset is defined and img.srcset != img.src ? img.srcset : null,
        'sizes': img.sizes|default(null),
        'width': define_proportions ? img.width : null,
        'height': define_proportions ? img.height : null,
        'loading': img.loading|default(null),
        'class': img.class|default(null),
    } %}
    <img{{ _self.html_attributes(base_attributes|merge(img_attributes)) }}>
{%- endmacro -%}

{#
    Build a <figcaption> from Studio\Figure data.

    If no metadata is present, nothing will be output.
#}
{%- macro caption(figure, options = {}) -%}
    {% if figure.hasMetadata and figure.metadata.caption %}
        {% set caption_attributes = figure.options.caption_attr|default({})|merge(options.caption_attr|default({})) %}
        <figcaption{{ _self.html_attributes(caption_attributes) }}>
            {{- figure.metadata.caption|raw -}}
        </figcaption>
    {% endif %}
{%- endmacro -%}

{#
    Helper: Expand an associative mapping into HTML attributes.

     - Values that are null won't be included
     - The output will contain a leading space

    Example:

        { 'foo': 'a', 'bar': 'b', 'foobar': null } --> ' foo="a" bar="b"'
#}
{%- macro html_attributes(attributes) -%}
    {%- for attr, value in attributes|filter(v => v is not null) -%}
        {{ ' ' ~ attr }}{% if value %}="{{ value }}"{% endif %}
    {%- endfor -%}
{%- endmacro -%}
