@@ -765,13 +765,15 @@ independently. If you're using `Live Components`_, then there
765
765
*are * some guidelines related to how the re-rendering of parent and
766
766
child components works. Read `Live Nested Components `_.
767
767
768
- Embedded Components
769
- -------------------
768
+ .. _embedded-components :
769
+
770
+ Passing Blocks to Components
771
+ ----------------------------
770
772
771
773
.. tip ::
772
774
773
- Embedded components (i.e. components with blocks) can be written in a more
774
- readable way by using the ` Component HTML Syntax `_ .
775
+ The ` Component HTML Syntax `_ allows you to pass blocks to components in an
776
+ even more readable way .
775
777
776
778
You can write your component's Twig template with blocks that can be overridden
777
779
when rendering using the ``{% component %} `` syntax. These blocks can be thought of as
@@ -830,7 +832,122 @@ The ``with`` data is what's mounted on the component object.
830
832
831
833
.. note ::
832
834
833
- Embedded components *cannot * currently be used with LiveComponents.
835
+ The ``{% component %} `` syntax *cannot * currently be used with LiveComponents.
836
+
837
+ Inheritance & Forwarding "Outer Blocks"
838
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
839
+
840
+ .. versionadded :: 2.10
841
+
842
+ The ``outerBlocks `` variable was added in 2.10.
843
+
844
+ The content inside a ``{% component ... %} `` tag should be viewed as living in
845
+ its own, independent template, which extends the component's template. This means that
846
+ any blocks that live in the "outer" template are not available inside the ``{% component %} `` tag.
847
+ However, a special ``outerBlocks `` variable is added as a way to refer to those blocks:
848
+
849
+ .. code-block :: html+twig
850
+
851
+ {% extends 'base.html.twig' %}
852
+
853
+ {% block call_to_action %}<strong>Attention! Free Puppies!</strong>{% endblock %}
854
+
855
+ {% block body %}
856
+ {% component Alert %}
857
+ {% block content %}{{ block(outerBlocks.call_to_action) }}{% endblock %}
858
+ {% endcomponent %}
859
+ {% endblock %}
860
+
861
+ The ``outerBlocks `` variable becomes specially useful with nested components. For example,
862
+ imagine we want to create a ``SuccessAlert `` component that's usable like this:
863
+
864
+ .. code-block :: html+twig
865
+
866
+ {# templates/some_page.html.twig #}
867
+ {% component SuccessAlert %}
868
+ {% content %}We will successfully <em>forward</em> this block content!{% endblock %}
869
+ {% endcomponent %}
870
+
871
+ But we already have a generic ``Alert `` component, and we want to re-use it:
872
+
873
+ .. code-block :: html+twig
874
+
875
+ {# templates/Alert.html.twig #}
876
+ <div class="alert alert-{{ type }}">
877
+ {% block content %}{% endblock %}
878
+ </div>
879
+
880
+ To do this, the ``SuccessAlert `` component can grab the ``content `` block that's passed to it
881
+ via the ``outerBlocks `` variable and forward it into ``Alert ``:
882
+
883
+ .. code-block :: twig
884
+
885
+ {# templates/SuccessAlert.html.twig #}
886
+ {% component Alert with { type: 'success' } %}
887
+ {% block content %}{{ blocks(outerBlocks.content) }}{% endblock %}
888
+ {% endcomponent %}
889
+
890
+ Note that to pass a block multiple components down, each component needs to pass it.
891
+
892
+ Context / Variables Inside of Blocks
893
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
894
+
895
+ The content inside of the ``{% component ... %} `` should be viewed as living in its own,
896
+ independent template, which extends the component's template. This has a few interesting consequences.
897
+
898
+ First, once you're inside of ``{% component ... %} ``, the ``this `` variable represents
899
+ the component you're now rendering *and * you have access to all of that component's variables:
900
+
901
+ .. code-block :: twig
902
+
903
+ {# templates/SuccessAlert.html.twig #}
904
+ {{ this.someFunction }} {# this refers to SuccessAlert #}
905
+
906
+ {% component Alert with { type: 'success' } %}
907
+ {{ this.someFunction }} {# this refers to Alert! #}
908
+
909
+ {{ type }} {# references a "type" prop from Alert #}
910
+ {% endcomponent %}
911
+
912
+ Conveniently, in addition to the variables from the ``Alert `` component, you still have
913
+ access to whatever variables are available in the original template:
914
+
915
+ .. code-block :: twig
916
+
917
+ {# templates/SuccessAlert.html.twig #}
918
+ {% set name = 'Fabien' %}
919
+ {% component Alert with { type: 'success' } %}
920
+ Hello {{ name }}
921
+ {% endcomponent %}
922
+
923
+ Note that ALL variables from upper components (e.g. ``SuccessAlert ``) are available to lower
924
+ components (e.g. ``Alert ``). However, because variables are merged, variables with the same name
925
+ are overridden by lower components (that's also why ``this `` refers to the embedded, or
926
+ "current" component).
927
+
928
+ The most interesting thing is that the content inside of ``{% component ... %} `` is
929
+ executed as if it is "copy-and-pasted" into the block of the target template. This means
930
+ you can access variables from the block you're overriding! For example:
931
+
932
+ .. code-block :: twig
933
+
934
+ {# templates/SuccessAlert.html.twig #}
935
+ {% for message in messages %}
936
+ {% block alert_message %}
937
+ A default {{ message }}
938
+ {% endblock %}
939
+ {% endfor %}
940
+
941
+ When overriding the ``alert_message `` block, you have access to the ``message `` variable:
942
+
943
+ .. code-block :: twig
944
+
945
+ {# templates/some_page.html.twig #}
946
+ {% component SuccessAlert %}
947
+ {% block alert_message %}
948
+ I can override the alert_message block and access the {{ message }} too!
949
+ {% endblock %}
950
+ {% endcomponent %}
834
951
835
952
Component HTML Syntax
836
953
---------------------
0 commit comments