{"id":12468,"date":"2017-02-14T13:59:49","date_gmt":"2017-02-14T21:59:49","guid":{"rendered":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts"},"modified":"2019-11-20T19:08:29","modified_gmt":"2019-11-21T03:08:29","slug":"debugging-frontend-layouts","status":"publish","type":"post","link":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/","title":{"rendered":"Debugging frontend layouts"},"content":{"rendered":"<p>Changing any visual HTML part of a complex application like OroCommerce may easily become a challenge for designer or developer. When similar elements and blocks are reused throughout the system, you need a tool to visualize their mutual location without a distraction of the actual content.<\/p>\n<p>In OroCommerce, <a href=\"https:\/\/github.com\/orocrm\/platform\/blob\/master\/src\/Oro\/Bundle\/LayoutBundle\/Resources\/doc\/what_is_layout.md\" target=\"_blank\" rel=\"noopener noreferrer\">Layouts<\/a> translate the structure of user interface into the adapted and simplified tree structure of the page blocks.<\/p>\n<p>In this post, you will learn about:<\/p>\n<ul>\n<li>the layout profiler that enables viewing layout structure and context<\/li>\n<li>using layouts for editing, adding, rearranging and removing the content of the web application.<\/li>\n<\/ul>\n<h2>Layout profiler<\/h2>\n<p>For layout context investigation &#8211; to better understand the relationship between the layout blocks &#8211; use <a href=\"https:\/\/github.com\/orocrm\/platform\/blob\/master\/src\/Oro\/Bundle\/LayoutBundle\/Resources\/doc\/debug_information.md\" target=\"_blank\" rel=\"noopener noreferrer\">Layout profiler<\/a>.<\/p>\n<p><strong>Note<\/strong>: Layout profiler is available only in the development environment with `debug` mode enabled.<\/p>\n<p>Before you begin, enable all Layout Profiler options in <strong>System &gt; Configuration &gt; Development Settings<\/strong>:<\/p>\n<p><a href=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutDevSettings-2.png\" target=\"_blank\" rel=\"attachment noopener wp-att-1984 noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1984 size-full\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutDevSettings-2.png\" alt=\"Debugging frontend layouts\" width=\"1408\" height=\"430\" srcset=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutDevSettings-2.png 1408w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutDevSettings-2-720x220.png 720w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutDevSettings-2-768x235.png 768w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutDevSettings-2-760x232.png 760w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutDevSettings-2-360x110.png 360w\" sizes=\"auto, (max-width: 1408px) 100vw, 1408px\" \/><\/a><\/p>\n<p>The options are:<\/p>\n<ul>\n<li><em>Include Block Debug Info Into HTML<\/em> &#8211; adds a unique identifier of the current block (<em>data-layout-debug-block-id<\/em>) and a rendered template of the current block (<em>data-layout-debug-block-template<\/em>) to the block HTML attributes.<br \/>\nExample of the html source code after the option is enabled:<br \/>\n<a href=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSourceCode-1.png\" target=\"_blank\" rel=\"attachment noopener wp-att-1977 noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1977\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSourceCode-1.png\" alt=\"LayoutSourceCode\" width=\"800\" height=\"75\" srcset=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSourceCode-1.png 1772w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSourceCode-1-720x68.png 720w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSourceCode-1-768x72.png 768w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSourceCode-1-760x72.png 760w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSourceCode-1-360x34.png 360w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/li>\n<li><em>Generate Layout Tree Dump For The Developer Toolbar<\/em> &#8211; enables rendering of Layout Tree.<\/li>\n<\/ul>\n<p>Now you can view web page layout structure and discover layout context items.<\/p>\n<h2>View layout context items<\/h2>\n<p>Open any page in your web application and hover over the Layout:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSymfonyProfilerMenu.png\" alt=\"Layout\" width=\"400\/\" \/><\/p>\n<p>What you get is the list of layout context items (<em>action<\/em>, <em>route_name<\/em>, <em>theme<\/em>, etc.) and their values.<\/p>\n<p><a href=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSymfonyProfiler-1.png\" target=\"_blank\" rel=\"attachment noopener wp-att-1921 noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1921 size-medium\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSymfonyProfiler-1.png\" alt=\"LayoutSymfonyProfiler\" width=\"549\" height=\"460\" srcset=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSymfonyProfiler-1.png 941w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSymfonyProfiler-1-549x460.png 549w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSymfonyProfiler-1-768x643.png 768w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSymfonyProfiler-1-525x440.png 525w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutSymfonyProfiler-1-251x210.png 251w\" sizes=\"auto, (max-width: 549px) 100vw, 549px\" \/><\/a><\/p>\n<h2>View layout structure<\/h2>\n<p>When you click on the Layout, a layout blocks tree pops up and you can analyze the blocks mutual location and nesting. The <em>data-layout-debug-block-id<\/em> attribute of the block is used as a tree node name.<\/p>\n<p><a href=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutStructure-1.png\" target=\"_blank\" rel=\"attachment noopener wp-att-1982 noreferrer\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1982\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutStructure-1.png\" alt=\"LayoutStructure\" width=\"450\" height=\"665\" srcset=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutStructure-1.png 935w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutStructure-1-311x460.png 311w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutStructure-1-768x1135.png 768w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutStructure-1-298x440.png 298w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/LayoutStructure-1-142x210.png 142w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/a><\/p>\n<h2>Customize a web application<\/h2>\n<h2>Modify a web page using a TWIG template<\/h2>\n<p>Layouts come handy when you customize a web application. Following the steps below, you can add a custom link into the unified web application footer.<\/p>\n<p>Start with creating a new html page (e.g. the one you are reading now) and a <em>controller<\/em> to render it:<\/p>\n<pre class=\"lang:php decode:true \">namespace OroBundleDemoLayoutBundleController;\r\n\r\n    use SymfonyBundleFrameworkBundleControllerController;\r\n    use SensioBundleFrameworkExtraBundleConfigurationRoute;\r\n    use SensioBundleFrameworkExtraBundleConfigurationTemplate;\r\n\r\n    class DefaultController extends Controller\r\n    {\r\n        \/**\r\n         * @Route(\"\/about-layouts\")\r\n         * @Template()\r\n         *\/\r\n        public function showAboutLayoutsAction()\r\n        {\r\n            return [];\r\n        }\r\n    }<\/pre>\n<p>Next, in Layout tree, find an appropriate location for the new block with the link to <em>About layouts<\/em> page.<br \/>\nFor example, create a new <em>about_layouts_block<\/em> inside the <em>footer_menu_container<\/em> block:<\/p>\n<ol>\n<li>In the <em>\/DemoLayoutBundle\/Resources\/views<\/em> create a <em>layouts<\/em> folder and sub-folder named by your active layout theme.<strong>Note:<\/strong> If you use a default theme, create a <em>default<\/em> sub-folder. You can verify the active theme in the layout context items by hovering over the Layout.Let us use the following path: <em>\/DemoLayoutBundle\/Resources\/views\/layouts\/default<\/em>, which means that we modify a layout for the `default` theme.<\/li>\n<li>At the newly created location, create `layout.yml` that defines a block with `link` blockType and adds this new block into the <em>footer_menu_container<\/em>:\n<pre class=\"lang:yaml decode:true \">layout:\r\n    actions:\r\n        - '@addTree':\r\n            items:\r\n                about_layouts_block:\r\n                    blockType: link\r\n                    options:\r\n                        route_name: oro_demolayout_default_showaboutlayouts\r\n                        text: 'About layouts'\r\n            tree:\r\n                footer_menu_container:\r\n                    about_layouts_block: ~<\/pre>\n<\/li>\n<\/ol>\n<p>This will result in the following layout tree:<br \/>\n<a href=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1.png\" rel=\"attachment wp-att-1947\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-1947\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1.png\" alt=\"footer\" width=\"250\" \/><\/a><br \/>\nThe web application footer has temporarily changed to the following:<br \/>\n<a href=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/simpleUpdatedFooter.png\" rel=\"attachment wp-att-1961\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1961 size-medium\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/simpleUpdatedFooter.png\" alt=\"simpleUpdatedFooter\" width=\"720\" height=\"241\" srcset=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/simpleUpdatedFooter.png 1256w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/simpleUpdatedFooter-720x241.png 720w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/simpleUpdatedFooter-768x257.png 768w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/simpleUpdatedFooter-760x254.png 760w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/simpleUpdatedFooter-360x120.png 360w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<p>Now, apply a block theme for the new block by creating a dedicated TWIG template. You probably would like your new link to blend smoothly with the other footer elements.<\/p>\n<p>In your web application, inspect the source code in the footer block to get the general idea of the template you need:<br \/>\n<a href=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/inspectUpdatedFooter.png\" rel=\"attachment wp-att-1963\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1963 size-medium\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/inspectUpdatedFooter.png\" alt=\"inspectUpdatedFooter\" width=\"578\" height=\"460\" srcset=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/inspectUpdatedFooter.png 1612w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/inspectUpdatedFooter-578x460.png 578w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/inspectUpdatedFooter-768x611.png 768w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/inspectUpdatedFooter-553x440.png 553w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/inspectUpdatedFooter-264x210.png 264w\" sizes=\"auto, (max-width: 578px) 100vw, 578px\" \/><\/a><\/p>\n<p>In the actions in <em>DemoLayoutBundle\/Resources\/views\/layouts\/default\/layout.yml<\/em>, add <em>@setBlockTheme<\/em> command with the similar theme:<\/p>\n<pre class=\"lang:php decode:true \">    actions:\r\n        - '@setBlockTheme':\r\n            themes: 'OroBundleDemoLayoutBundle:layouts:default\/layout.html.twig'<\/pre>\n<p>and create a new block theme file &#8211; <em>DemoLayoutBundle\/Resources\/views\/layouts\/default\/layout.html.twig<\/em>:<\/p>\n<pre class=\"lang:php decode:true \">{% block _about_layouts_block_widget %}\r\n<\/pre>\n<div class=\"footer-nav footer-columns footer-columns--one-third\">\n<h2 class=\"footer-nav__title\">How-to&#8217;s<\/h2>\n<p>{{ block_widget(block) }}<\/p>\n<\/div>\n<p>{% endblock %}<\/p>\n<p>After these changes, the link in the footer has moved to the How-to&#8217;s section to the left from the original footer content:<br \/>\n<a href=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1.png\" rel=\"attachment wp-att-1966\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1966 size-medium\" src=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1.png\" alt=\"finalUpdatedFooter\" width=\"720\" height=\"320\" srcset=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1.png 864w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1-720x320.png 720w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1-768x341.png 768w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1-760x338.png 760w, https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2016\/09\/finalUpdatedFooter-1-360x160.png 360w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<h3>Modify a web page using layout actions<\/h3>\n<h4>Prerequisites<\/h4>\n<p>Modify \/DemoLayoutBundle\/Controller\/DefaultController.php to use <em>OroBundleLayoutBundleAnnotationLayout<\/em> instead of the <em>SensioBundleFrameworkExtraBundleConfigurationTemplate<\/em>, and replace the <em>@Template()<\/em> with the <em>@Layout<\/em> annotation, like in the following example:<\/p>\n<pre class=\"lang:php decode:true \">namespace OroBundleDemoLayoutBundleController;\r\n\r\nuse SymfonyBundleFrameworkBundleControllerController;\r\nuse SensioBundleFrameworkExtraBundleConfigurationRoute;\r\nuse OroBundleLayoutBundleAnnotationLayout;\r\n\r\nclass DefaultController extends Controller\r\n{\r\n    \/**\r\n     * @Route(\"\/about-layouts\")\r\n     * @Layout\r\n     *\/\r\n    public function showAboutLayoutsAction()\r\n    {\r\n        return [];\r\n    }\r\n}<\/pre>\n<p>After these changes, the controller switches to the layout-based page rendering.<\/p>\n<h4>@add custom layout block<\/h4>\n<p>In the layout tree, identify the parent block for your new custom bock (e.g. <em>content<\/em>).<\/p>\n<p>In the DemoLayoutBundle\/Resources\/views\/layouts\/default folder, create an <em>oro_demolayout_default_showaboutlayouts<\/em> folder to define a page route name.<\/p>\n<p>Inside that folder, create a <em>page.yml<\/em> file with an <em>@add<\/em> action that defines a new layout element and nests it inside the block with the specified parentId (use the block name from the layout tree as parentId, for example, <em>content<\/em>):<\/p>\n<pre class=\"lang:php decode:true \">layout:\r\n    actions:\r\n        - '@add':\r\n            id:        demo_page_content\r\n            parentId:  content\r\n            blockType: text\r\n            options:\r\n                text: 'Detailed information about using layouts...'<\/pre>\n<p>Refresh the web page to view the changes.<\/p>\n<h4>@remove existing layout block<\/h4>\n<p>To eliminate an unwanted element of the page layout, use <em>@remove<\/em> action in the <em>page.yml<\/em> with an id of the block to be removed. For example, you can drop the main menu:<\/p>\n<pre class=\"lang:php decode:true \">        - '@remove':\r\n            id: main_menu_container<\/pre>\n<h4>Rearrange a layout with @move action<\/h4>\n<p>Use <em>@move<\/em> action in the <em>page.yml<\/em> to change the parent of the layout block and append it to the bottom of the children list.<\/p>\n<p>For example, take the following layout tree:<\/p>\n<pre class=\"lang:php highlight:0 decode:true\">content\r\n|--section-a\r\n|--section-b\r\nfooter<\/pre>\n<p>If in the <em>page.yml<\/em> you move the footer node into the content node using the following action:<\/p>\n<pre class=\"lang:php decode:true \">        - '@move':\r\n            id: footer\r\n            parentId: content<\/pre>\n<p>The layout will change to the following one:<\/p>\n<pre class=\"lang:php highlight:0 decode:true\">content\r\n|--section-a\r\n|--section-b\r\n|--footer<\/pre>\n<p><strong>Note:<\/strong> When moved, the block gets to the bottom of the list of its siblings. To rearrange siblings, use series of @move actions. For example, to put the <em>footer<\/em> before the <em>section-b<\/em> use the following actions:<\/p>\n<pre class=\"lang:php decode:true \">        - '@move':\r\n            id: footer\r\n            parentId: content\r\n       - '@move':\r\n            id: section-b\r\n            parentId: content<\/pre>\n<p>Updated layout tree is:<\/p>\n<pre class=\"lang:php highlight:0 decode:true\">header\r\ncontent\r\n|--section-a\r\n|--footer\r\n|--section-b<\/pre>\n<h4>Using context variables in layout<\/h4>\n<p>Eventually, you may need multiple pages with a shared layout template to access the same static information, for example, a system-wide sub-menu configuration and maintenance announcement text.<\/p>\n<p><strong>Note:<\/strong> For an easier debug process, use oro:layout:debug &#8211;context command that shows how the context data-resolver is configured.<\/p>\n<p>To enable sharing context information, pass the <em>Layout context<\/em> as a parameter in <strong>layoutBuilder-&gt;getLayout<\/strong> method, like in the following example:<\/p>\n<pre class=\"lang:php decode:true \">    $layoutContext = new LayoutContext();\r\n    $layoutBuilder = $layoutManager-&gt;getLayoutBuilder();\r\n    $layoutBuilder-&gt;getLayout($layoutContext);<\/pre>\n<p>and add the context variables (e.g. <em>static_content<\/em>) and an algorythm that returns their value to the @Layout annotation in the controller:<\/p>\n<pre class=\"lang:php decode:true \">    \/**\r\n     * @Route(\"\/about-layouts\")\r\n     * @Layout(vars={\"static_content\"})\r\n     *\/\r\n    public function showAboutLayoutsAction()\r\n    {\r\n        return [\r\n            'static_content' =&gt; 'The selected product category is temporarily under maintenance. We apologize for any inconvenience. Please come back later.'\r\n        ];\r\n    }<\/pre>\n<p>As we have added a new <em>static_content<\/em> variable to the layout context, let&#8217;s use its value instead of the static text in the block we created earlier. In the <em>page.yml<\/em> file located in the <em>DemoLayoutBundle\/Resources\/views\/layouts\/default\/oro_demolayout_default_showaboutlayouts\/<\/em> folder, parameterize the <em>text<\/em> value with the <em>static_content<\/em> value in the layout context (<em>$context<\/em>):<\/p>\n<pre class=\"lang:php decode:true \">        - '@add':\r\n            id:        demo_page_content\r\n            parentId:  content\r\n            blockType: text\r\n            options:\r\n                text: { '@value': $context.static_content }<\/pre>\n<p>Now, if you hover over the Layout profiler, you can see a <em>static_content<\/em> context item and its value.<\/p>\n<h4>Using data providers in layout<\/h4>\n<p>Dynamic data may be bound to layout elements either via data collection in layout context or via dedicated data provider.<br \/>\nFor a quick illustration, let us use an existing category_tree service that returns an array of categories to populate the page title for our maintenance announcement.<br \/>\nThe category_tree service is defined in the <em>Oro\/Bundle\/CatalogBundle\/Resources\/config\/layout.yml<\/em> in a following manner:<\/p>\n<pre class=\"lang:php decode:true \">    orob2b_catalog.layout.data_provider.category_tree:\r\n        class: OroB2BBundleCatalogBundleLayoutDataProviderCategoryTreeProvider\r\n        arguments:\r\n            - '@orob2b_catalog.provider.category_tree_provider'\r\n            - '@doctrine'\r\n        tags:\r\n            - { name: layout.data_provider, alias: category_tree }<\/pre>\n<p>In the <em>page.yml<\/em> file, use @setOption action to populate the page title text with the first element of the category tree:<\/p>\n<pre class=\"lang:php decode:true \">        - '@setOption':\r\n            id: page_title\r\n            optionName: text\r\n            optionValue: {'@value': $data.category_tree[0] }<\/pre>\n<h2>Additional resources<\/h2>\n<p>To help you master the layout management actions, we&#8217;ve prepared a `DemoLayoutBundle` with most of the examples provided above. To add this bundle to your application please extract the content of the zip archive into a source code directory.<br \/>\nSee also:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/orocrm\/platform\/blob\/master\/src\/Oro\/Bundle\/LayoutBundle\/Resources\/doc\/example.md\" target=\"_blank\" rel=\"noopener noreferrer\">Using layouts with samples<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/orocrm\/platform\/blob\/master\/src\/Oro\/Bundle\/LayoutBundle\/Resources\/doc\/layout_context.md\">Layout context<\/a> documentation<\/li>\n<li><a href=\"https:\/\/github.com\/orocrm\/platform\/blob\/master\/src\/Oro\/Bundle\/LayoutBundle\/Resources\/doc\/layout_data.md\" target=\"_blank\" rel=\"noopener noreferrer\">Layout data<\/a> documentation<\/li>\n<li><a href=\"https:\/\/github.com\/orocrm\/platform\/blob\/master\/src\/Oro\/Bundle\/LayoutBundle\/Resources\/doc\/theme_definition.md\" target=\"_blank\" rel=\"noopener noreferrer\">Theme definition<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Changing any visual HTML part of a complex application like OroCommerce may easily become a challenge for designer or developer. When similar elements and blocks are reused throughout the system, you need a tool to visualize their mutual location without a distraction of the actual content. In OroCommerce, Layouts translate the structure of user interface [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":12469,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"ep_exclude_from_search":false,"footnotes":""},"categories":[132],"tags":[103],"class_list":{"0":"post-12468","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-developers-digest","8":"tag-orocommerce"},"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Debugging frontend layouts | OroCommerce<\/title>\n<meta name=\"description\" content=\"In this post, you will learn about the layout profiler that enables viewing layout structure and context using layouts for editing.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Debugging frontend layouts | OroCommerce\" \/>\n<meta property=\"og:description\" content=\"In this post, you will learn about the layout profiler that enables viewing layout structure and context using layouts for editing.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/\" \/>\n<meta property=\"og:site_name\" content=\"OroCommerce\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/OroCommerce-333319140210515\/\" \/>\n<meta property=\"article:published_time\" content=\"2017-02-14T21:59:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-21T03:08:29+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png\" \/>\n\t<meta property=\"og:image:width\" content=\"760\" \/>\n\t<meta property=\"og:image:height\" content=\"440\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Oro Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@orocommerce\" \/>\n<meta name=\"twitter:site\" content=\"@orocommerce\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Oro Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/\"},\"author\":{\"name\":\"Oro Team\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#\/schema\/person\/420bb6bc049bf6da18b714558557558c\"},\"headline\":\"Debugging frontend layouts\",\"datePublished\":\"2017-02-14T21:59:49+00:00\",\"dateModified\":\"2019-11-21T03:08:29+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/\"},\"wordCount\":1208,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#organization\"},\"image\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png\",\"keywords\":[\"OroCommerce\"],\"articleSection\":[\"Developers' Digest\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/\",\"url\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/\",\"name\":\"Debugging frontend layouts | OroCommerce\",\"isPartOf\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png\",\"datePublished\":\"2017-02-14T21:59:49+00:00\",\"dateModified\":\"2019-11-21T03:08:29+00:00\",\"description\":\"In this post, you will learn about the layout profiler that enables viewing layout structure and context using layouts for editing.\",\"breadcrumb\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#primaryimage\",\"url\":\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png\",\"contentUrl\":\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png\",\"width\":760,\"height\":440},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/oroinc.com\/b2b-ecommerce\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Developers' Digest\",\"item\":\"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/category\/developers-digest\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Debugging frontend layouts\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#website\",\"url\":\"https:\/\/oroinc.com\/b2b-ecommerce\/\",\"name\":\"OroCommerce\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/oroinc.com\/b2b-ecommerce\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#organization\",\"name\":\"Oro Inc.\",\"url\":\"https:\/\/oroinc.com\/b2b-ecommerce\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2019\/11\/Oro-OLogo.png\",\"contentUrl\":\"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2019\/11\/Oro-OLogo.png\",\"width\":40,\"height\":40,\"caption\":\"Oro Inc.\"},\"image\":{\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/OroCommerce-333319140210515\/\",\"https:\/\/x.com\/orocommerce\",\"https:\/\/www.youtube.com\/channel\/UClxsA8HS9KGEEsvFRn7JkvQ\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/oroinc.com\/b2b-ecommerce\/#\/schema\/person\/420bb6bc049bf6da18b714558557558c\",\"name\":\"Oro Team\",\"sameAs\":[\"http:\/\/www.orocrm.com\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Debugging frontend layouts | OroCommerce","description":"In this post, you will learn about the layout profiler that enables viewing layout structure and context using layouts for editing.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/","og_locale":"en_US","og_type":"article","og_title":"Debugging frontend layouts | OroCommerce","og_description":"In this post, you will learn about the layout profiler that enables viewing layout structure and context using layouts for editing.","og_url":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/","og_site_name":"OroCommerce","article_publisher":"https:\/\/www.facebook.com\/OroCommerce-333319140210515\/","article_published_time":"2017-02-14T21:59:49+00:00","article_modified_time":"2019-11-21T03:08:29+00:00","og_image":[{"width":760,"height":440,"url":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png","type":"image\/png"}],"author":"Oro Team","twitter_card":"summary_large_image","twitter_creator":"@orocommerce","twitter_site":"@orocommerce","twitter_misc":{"Written by":"Oro Team","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#article","isPartOf":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/"},"author":{"name":"Oro Team","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#\/schema\/person\/420bb6bc049bf6da18b714558557558c"},"headline":"Debugging frontend layouts","datePublished":"2017-02-14T21:59:49+00:00","dateModified":"2019-11-21T03:08:29+00:00","mainEntityOfPage":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/"},"wordCount":1208,"commentCount":2,"publisher":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#organization"},"image":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#primaryimage"},"thumbnailUrl":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png","keywords":["OroCommerce"],"articleSection":["Developers' Digest"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/","url":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/","name":"Debugging frontend layouts | OroCommerce","isPartOf":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#website"},"primaryImageOfPage":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#primaryimage"},"image":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#primaryimage"},"thumbnailUrl":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png","datePublished":"2017-02-14T21:59:49+00:00","dateModified":"2019-11-21T03:08:29+00:00","description":"In this post, you will learn about the layout profiler that enables viewing layout structure and context using layouts for editing.","breadcrumb":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#primaryimage","url":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png","contentUrl":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2018\/01\/7-4.png","width":760,"height":440},{"@type":"BreadcrumbList","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/debugging-frontend-layouts\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/oroinc.com\/b2b-ecommerce\/"},{"@type":"ListItem","position":2,"name":"Developers' Digest","item":"https:\/\/oroinc.com\/b2b-ecommerce\/blog\/category\/developers-digest\/"},{"@type":"ListItem","position":3,"name":"Debugging frontend layouts"}]},{"@type":"WebSite","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#website","url":"https:\/\/oroinc.com\/b2b-ecommerce\/","name":"OroCommerce","description":"","publisher":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/oroinc.com\/b2b-ecommerce\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#organization","name":"Oro Inc.","url":"https:\/\/oroinc.com\/b2b-ecommerce\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#\/schema\/logo\/image\/","url":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2019\/11\/Oro-OLogo.png","contentUrl":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-content\/uploads\/sites\/3\/2019\/11\/Oro-OLogo.png","width":40,"height":40,"caption":"Oro Inc."},"image":{"@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/OroCommerce-333319140210515\/","https:\/\/x.com\/orocommerce","https:\/\/www.youtube.com\/channel\/UClxsA8HS9KGEEsvFRn7JkvQ"]},{"@type":"Person","@id":"https:\/\/oroinc.com\/b2b-ecommerce\/#\/schema\/person\/420bb6bc049bf6da18b714558557558c","name":"Oro Team","sameAs":["http:\/\/www.orocrm.com\/"]}]}},"_links":{"self":[{"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/posts\/12468","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/comments?post=12468"}],"version-history":[{"count":1,"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/posts\/12468\/revisions"}],"predecessor-version":[{"id":80801,"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/posts\/12468\/revisions\/80801"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/media\/12469"}],"wp:attachment":[{"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/media?parent=12468"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/categories?post=12468"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oroinc.com\/b2b-ecommerce\/wp-json\/wp\/v2\/tags?post=12468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}