@@ -832,6 +832,136 @@ The ``with`` data is what's mounted on the component object.
832
832
833
833
Embedded components *cannot * currently be used with LiveComponents.
834
834
835
+ Passing blocks to embedded components
836
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
837
+
838
+ By combining nested components and embedded components very powerful structures can be created.
839
+ There's one important thing to remember: **each embedded component, a.k.a. a component with
840
+ blocks, inside a template, a.k.a. a nested component, starts its own template **.
841
+ Any blocks that are available in your component template are *NOT * available *inside * the embedded component.
842
+
843
+ Imagine this simple Alert component, which allows its content to be set by a higher component,
844
+ for example a SuccessAlert component.
845
+
846
+ .. code-block :: html+twig
847
+
848
+ {# templates/alert.html.twig #}
849
+ <div class="alert alert-{{ type }}">
850
+ {% block content %}{% endblock %}
851
+ </div>
852
+
853
+ .. code-block :: twig
854
+
855
+ {# templates/successAlert.html.twig #}
856
+ {% component Alert with { type: 'success' } %}
857
+ I can override the content, but that's pretty dull.
858
+ {% endcomponent %}
859
+
860
+ What if this SuccessAlert component wants to make the content of its nested Alert component configurable?
861
+ Well, you can use the special `outerBlocks ` variable for those cases. This makes it possible to refer
862
+ to blocks that are passed in from another higher component.
863
+
864
+ .. code-block :: twig
865
+
866
+ {# templates/successAlert.html.twig #}
867
+ {% component Alert with { type: 'success' } %}
868
+ {{ blocks(outerBlocks.content) }}
869
+ {% endcomponent %}
870
+
871
+ .. code-block :: twig
872
+
873
+ {# templates/some_page.html.twig #}
874
+ {% component SuccessAlert %}
875
+ Look mom, I'm a complex component!
876
+ {% endcomponent %}
877
+
878
+ Note that to pass a block multiple components down, each component would need to pass it along.
879
+
880
+ .. code-block :: twig
881
+
882
+ {# templates/level1.html.twig #}
883
+ {% component Level2 %}
884
+ {% block foo %}
885
+ I'm providing/overriding the foo block of Level2
886
+ {% endblock %}
887
+ {% endcomponent %}
888
+
889
+ .. code-block :: twig
890
+
891
+ {# templates/level2.html.twig #}
892
+ {% component Target %}
893
+ {% block foo %}
894
+ {# overriding the foo block of Target #}
895
+ {# but actually passing it along from the upper component #}
896
+ {# it could add some extra stuff here of course #}
897
+ {# and even append/prepend the content of Target's foo block by using {{ parent() }} #}
898
+
899
+ {{ blocks(outerBlocks.foo) }}
900
+ {% endblock %}
901
+ {% endcomponent %}
902
+
903
+ .. code-block :: html+twig
904
+
905
+ {# templates/target.html.twig #}
906
+ <div>{% block foo %}default content for foo{% endblock %}</div>
907
+
908
+ Context of embedded components
909
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
910
+
911
+ Every embedded component can be viewed as another template inside a template, hence the name.
912
+ Or in other words, in the other direction, it's as if the embedded component's blocks are copy-pasted
913
+ into that component's template. This has a few interesting consequences.
914
+
915
+ First of all, although `this ` is referring to the component of the template into which an (embedded)
916
+ component is nested, *INSIDE * an embedded component it is referring to the *embedded * component,
917
+ *NOT * the component into which it's being nested.
918
+
919
+ .. code-block :: twig
920
+
921
+ {# templates/successAlert.html.twig #}
922
+ {{ this.someFunction }} {# this refers to SuccessAlert #}
923
+
924
+ {% component Alert with { type: 'success' } %}
925
+ {{ this.someFunction }} {# this refers to Alert! #}
926
+ {% endcomponent %}
927
+
928
+ On the other hand, all variables are also available to the embedded component.
929
+
930
+ .. code-block :: twig
931
+
932
+ {# templates/successAlert.html.twig #}
933
+ {% set name = 'Fabien' %}
934
+ {% component Alert with { type: 'success' } %}
935
+ Hello {{ name }}
936
+ {% endcomponent %}
937
+
938
+ Note that even ALL variables from upper components are available to lower components. However,
939
+ because variables are merged in the context, variables with the same name are overridden by
940
+ lower components. (That's also why `this ` refers to the embedded, or "current" component)
941
+
942
+ Finally, the most interesting thing is that, because the embedded components are literally
943
+ resolved when rendering the nested component's template, you can even access the variables
944
+ from THAT template as well. Again, it's as if the embedded component's blocks are being
945
+ copy-pasted into the nested component's template.
946
+
947
+ .. code-block :: twig
948
+
949
+ {# templates/successAlert.html.twig #}
950
+ {% for message in messages %}
951
+ {% block message %}
952
+ A default {{ message }}
953
+ {% endblock %}
954
+ {% endfor %}
955
+
956
+ .. code-block :: twig
957
+
958
+ {# templates/some_page.html.twig #}
959
+ {% component SuccessAlert %}
960
+ {% block message %}
961
+ I can override the message block and access the {{ message }} too!
962
+ {% endblock %}
963
+ {% endcomponent %}
964
+
835
965
Component HTML Syntax
836
966
---------------------
837
967
0 commit comments