[{"data":1,"prerenderedAt":1438},["ShallowReactive",2],{"navigation_docs":3,"-drupal-custom-elements":221,"-drupal-custom-elements-surround":1433},[4,27,77,123,157,207],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":26},"Get started","majesticons:rocket-3-start-line","\u002Fget-started","1.get-started",[10,14,18,22],{"title":11,"path":12,"stem":13},"How it works","\u002Fget-started\u002Fhow-it-works","1.get-started\u002F10.how-it-works",{"title":15,"path":16,"stem":17},"Play online","\u002Fget-started\u002Fplay-online","1.get-started\u002F20.play-online",{"title":19,"path":20,"stem":21},"Create a new project","\u002Fget-started\u002Fcreate-new-project","1.get-started\u002F30.create-new-project",{"title":23,"path":24,"stem":25},"First steps","\u002Fget-started\u002Ffirst-steps","1.get-started\u002F40.first-steps",false,{"title":28,"icon":29,"path":30,"stem":31,"children":32,"page":26},"Guide","mdi:book-open-page-variant-outline","\u002Fguide","2.guide",[33,37,41,45,49,53,57,61,65,69,73],{"title":34,"path":35,"stem":36},"Customized API Output","\u002Fguide\u002Fcustomized-api-output","2.guide\u002F05.customized-api-output",{"title":38,"path":39,"stem":40},"Pages & Routing","\u002Fguide\u002Fpages-routing","2.guide\u002F10.pages-routing",{"title":42,"path":43,"stem":44},"Site layout & Menus","\u002Fguide\u002Fsite-layout-menus","2.guide\u002F20.site-layout-menus",{"title":46,"path":47,"stem":48},"Authentication","\u002Fguide\u002Fauthentication","2.guide\u002F40.authentication",{"title":50,"path":51,"stem":52},"Metatags & Local tasks","\u002Fguide\u002Fmetatags-local-tasks","2.guide\u002F50.metatags-local-tasks",{"title":54,"path":55,"stem":56},"Breadcrumbs & Messages","\u002Fguide\u002Fbreadcrumbs-messages","2.guide\u002F60.breadcrumbs-messages",{"title":58,"path":59,"stem":60},"Redirects","\u002Fguide\u002Fredirects","2.guide\u002F65.redirects",{"title":62,"path":63,"stem":64},"Editorial previews","\u002Fguide\u002Feditorial-previews","2.guide\u002F70.editorial-previews",{"title":66,"path":67,"stem":68},"Layout builder","\u002Fguide\u002Flayout-builder","2.guide\u002F80.layout-builder",{"title":70,"path":71,"stem":72},"Drupal Canvas","\u002Fguide\u002Fcanvas","2.guide\u002F90.canvas",{"title":74,"path":75,"stem":76},"Drupal CMS","\u002Fguide\u002Fdrupal-cms","2.guide\u002F95.drupal-cms",{"title":78,"icon":79,"path":80,"stem":81,"children":82,"page":26},"Advanced topics","bi:diagram-3","\u002Fadvanced-topics","3.advanced-topics",[83,87,91,95,99,103,107,111,115,119],{"title":84,"path":85,"stem":86},"Multi-frontend","\u002Fadvanced-topics\u002Fmulti-frontend","3.advanced-topics\u002F05.multi-frontend",{"title":88,"path":89,"stem":90},"Listings, Views","\u002Fadvanced-topics\u002Flistings-views","3.advanced-topics\u002F10.listings-views",{"title":92,"path":93,"stem":94},"Searches","\u002Fadvanced-topics\u002Fsearches","3.advanced-topics\u002F20.searches",{"title":96,"path":97,"stem":98},"JSON-API & GraphQL","\u002Fadvanced-topics\u002Fjsonapi-graphql","3.advanced-topics\u002F30.jsonapi-graphql",{"title":100,"path":101,"stem":102},"Caching","\u002Fadvanced-topics\u002Fcaching","3.advanced-topics\u002F40.caching",{"title":104,"path":105,"stem":106},"Error pages","\u002Fadvanced-topics\u002Ferror-pages","3.advanced-topics\u002F50.error-pages",{"title":108,"path":109,"stem":110},"Drupal forms","\u002Fadvanced-topics\u002Fdrupal-forms","3.advanced-topics\u002F60.drupal-forms",{"title":112,"path":113,"stem":114},"Site Templates","\u002Fadvanced-topics\u002Fsite-templates","3.advanced-topics\u002F65.site-templates",{"title":116,"path":117,"stem":118},"Block layout","\u002Fadvanced-topics\u002Fblock-layout","3.advanced-topics\u002F70.block-layout",{"title":120,"path":121,"stem":122},"Debugging API requests","\u002Fadvanced-topics\u002Fdebugging","3.advanced-topics\u002F80.debugging",{"title":124,"icon":125,"path":126,"stem":127,"children":128,"page":26},"Drupal","simple-icons:drupal","\u002Fdrupal","4.drupal",[129,133,137,141,145,149,153],{"title":130,"path":131,"stem":132},"Key modules","\u002Fdrupal\u002Fkey-modules","4.drupal\u002F10.key-modules",{"title":134,"path":135,"stem":136},"Custom elements","\u002Fdrupal\u002Fcustom-elements","4.drupal\u002F20.custom-elements",{"title":138,"path":139,"stem":140},"Routes","\u002Fdrupal\u002Froutes","4.drupal\u002F30.routes",{"title":142,"path":143,"stem":144},"Providing blocks","\u002Fdrupal\u002Fproviding-blocks","4.drupal\u002F40.providing-blocks",{"title":146,"path":147,"stem":148},"Custom Element Processors","\u002Fdrupal\u002Fcustom-element-processors","4.drupal\u002F50.custom-element-processors",{"title":150,"path":151,"stem":152},"Adding Drupal forms","\u002Fdrupal\u002Fadd-drupal-forms","4.drupal\u002F60.add-drupal-forms",{"title":154,"path":155,"stem":156},"Providing themes","\u002Fdrupal\u002Fthemes","4.drupal\u002F70.themes",{"title":158,"icon":159,"path":160,"stem":161,"children":162,"page":26},"Nuxt","simple-icons:nuxtdotjs","\u002Fnuxt","5.nuxt",[163,167,171,175,179,183,187,191,195,199,203],{"title":164,"path":165,"stem":166},"Introduction","\u002Fnuxt\u002Fintroduction","5.nuxt\u002F10.introduction",{"title":168,"path":169,"stem":170},"Setup","\u002Fnuxt\u002Fsetup","5.nuxt\u002F20.setup",{"title":172,"path":173,"stem":174},"Rendering Custom Elements","\u002Fnuxt\u002Frender-custom-elements","5.nuxt\u002F30.render-custom-elements",{"title":176,"path":177,"stem":178},"Default components","\u002Fnuxt\u002Fdefault-components","5.nuxt\u002F32.default-components",{"title":180,"path":181,"stem":182},"Composables","\u002Fnuxt\u002Fcomposables","5.nuxt\u002F35.composables",{"title":184,"path":185,"stem":186},"Custom Routes","\u002Fnuxt\u002Fcustom-routes","5.nuxt\u002F40.custom-routes",{"title":188,"path":189,"stem":190},"Page Layouts","\u002Fnuxt\u002Fpage-layouts","5.nuxt\u002F50.page-layouts",{"title":192,"path":193,"stem":194},"Component Previews","\u002Fnuxt\u002Fcomponent-previews","5.nuxt\u002F55.component-previews",{"title":196,"path":197,"stem":198},"Rendering modes","\u002Fnuxt\u002Frendering-modes","5.nuxt\u002F60.rendering-modes",{"title":200,"path":201,"stem":202},"Deployment options","\u002Fnuxt\u002Fdeployment","5.nuxt\u002F70.deployment",{"title":204,"path":205,"stem":206},"Resources","\u002Fnuxt\u002Fresources","5.nuxt\u002F90.resources",{"title":208,"icon":209,"path":210,"stem":211,"children":212,"page":26},"Deployment","solar:server-square-cloud-linear","\u002Fdeployment","6.deployment",[213,217],{"title":214,"path":215,"stem":216},"Deployment Strategies","\u002Fdeployment\u002Fdeployment-strategy","6.deployment\u002F10.deployment-strategy",{"title":218,"path":219,"stem":220},"Unified Hosting","\u002Fdeployment\u002Funified-hosting","6.deployment\u002F20.unified-hosting",{"id":222,"title":134,"body":223,"description":247,"extension":1428,"links":1429,"meta":1430,"navigation":293,"path":135,"seo":1431,"stem":136,"__hash__":1432},"docs\u002F4.drupal\u002F20.custom-elements.md",{"type":224,"value":225,"toc":1413},"minimark",[226,231,240,587,590,734,739,753,757,760,764,779,806,809,813,820,824,827,922,929,936,1045,1049,1060,1064,1067,1179,1183,1186,1278,1282,1291,1315,1319,1322,1358,1361,1398,1409],[227,228,230],"h2",{"id":229},"creating-custom-elements","Creating custom elements",[232,233,234,235,239],"p",{},"The ",[236,237,238],"code",{},"CustomElement"," class helps modelling a tree of custom elements. The class provides an API for creating and nesting custom elements as shown the following example:",[241,242,248],"pre",{"className":243,"code":244,"filename":245,"language":246,"meta":247,"style":247},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C?php\n   use \\Drupal\\custom_elements\\CustomElement;\n\n   class NewsController extends ControllerBase {\n    public function buildNewsListing() {\n\n      $articles[] = CustomElement::create('article-teaser')\n        ->setAttribute('href', 'https:\u002F\u002Fexample.com\u002Fnews\u002F1')\n        ->setAttribute('excerpt', 'The excerpt of the news entry.');\n\n      $articles[] = CustomElement::create('article-teaser')\n        ->setAttribute('href', 'https:\u002F\u002Fexample.com\u002Fnews\u002F2')\n        ->setAttribute('excerpt', 'The excerpt of another news entry.');\n\n      return CustomElement::create('teaser-listing')\n        ->setSlotFromNestedElements('default', $articles);\n    }\n  }\n","Controller\u002FNews.php","php","",[236,249,250,263,288,295,315,333,338,377,408,436,441,468,494,520,525,549,575,581],{"__ignoreMap":247},[251,252,255,259],"span",{"class":253,"line":254},"line",1,[251,256,258],{"class":257},"sMK4o","\u003C?",[251,260,262],{"class":261},"sTEyZ","php\n",[251,264,266,270,273,275,278,281,283,285],{"class":253,"line":265},2,[251,267,269],{"class":268},"sbssI","   use",[251,271,272],{"class":257}," \\",[251,274,124],{"class":261},[251,276,277],{"class":257},"\\",[251,279,280],{"class":261},"custom_elements",[251,282,277],{"class":257},[251,284,238],{"class":261},[251,286,287],{"class":257},";\n",[251,289,291],{"class":253,"line":290},3,[251,292,294],{"emptyLinePlaceholder":293},true,"\n",[251,296,298,302,306,309,312],{"class":253,"line":297},4,[251,299,301],{"class":300},"spNyl","   class",[251,303,305],{"class":304},"sBMFI"," NewsController",[251,307,308],{"class":300}," extends",[251,310,311],{"class":304}," ControllerBase",[251,313,314],{"class":257}," {\n",[251,316,318,321,324,328,331],{"class":253,"line":317},5,[251,319,320],{"class":300},"    public",[251,322,323],{"class":300}," function",[251,325,327],{"class":326},"s2Zo4"," buildNewsListing",[251,329,330],{"class":257},"()",[251,332,314],{"class":257},[251,334,336],{"class":253,"line":335},6,[251,337,294],{"emptyLinePlaceholder":293},[251,339,341,344,347,350,353,356,359,362,365,368,372,374],{"class":253,"line":340},7,[251,342,343],{"class":257},"      $",[251,345,346],{"class":261},"articles",[251,348,349],{"class":257},"[]",[251,351,352],{"class":257}," =",[251,354,355],{"class":304}," CustomElement",[251,357,358],{"class":257},"::",[251,360,361],{"class":326},"create",[251,363,364],{"class":257},"(",[251,366,367],{"class":257},"'",[251,369,371],{"class":370},"sfazB","article-teaser",[251,373,367],{"class":257},[251,375,376],{"class":257},")\n",[251,378,380,383,386,388,390,393,395,398,401,404,406],{"class":253,"line":379},8,[251,381,382],{"class":257},"        ->",[251,384,385],{"class":326},"setAttribute",[251,387,364],{"class":257},[251,389,367],{"class":257},[251,391,392],{"class":370},"href",[251,394,367],{"class":257},[251,396,397],{"class":257},",",[251,399,400],{"class":257}," '",[251,402,403],{"class":370},"https:\u002F\u002Fexample.com\u002Fnews\u002F1",[251,405,367],{"class":257},[251,407,376],{"class":257},[251,409,411,413,415,417,419,422,424,426,428,431,433],{"class":253,"line":410},9,[251,412,382],{"class":257},[251,414,385],{"class":326},[251,416,364],{"class":257},[251,418,367],{"class":257},[251,420,421],{"class":370},"excerpt",[251,423,367],{"class":257},[251,425,397],{"class":257},[251,427,400],{"class":257},[251,429,430],{"class":370},"The excerpt of the news entry.",[251,432,367],{"class":257},[251,434,435],{"class":257},");\n",[251,437,439],{"class":253,"line":438},10,[251,440,294],{"emptyLinePlaceholder":293},[251,442,444,446,448,450,452,454,456,458,460,462,464,466],{"class":253,"line":443},11,[251,445,343],{"class":257},[251,447,346],{"class":261},[251,449,349],{"class":257},[251,451,352],{"class":257},[251,453,355],{"class":304},[251,455,358],{"class":257},[251,457,361],{"class":326},[251,459,364],{"class":257},[251,461,367],{"class":257},[251,463,371],{"class":370},[251,465,367],{"class":257},[251,467,376],{"class":257},[251,469,471,473,475,477,479,481,483,485,487,490,492],{"class":253,"line":470},12,[251,472,382],{"class":257},[251,474,385],{"class":326},[251,476,364],{"class":257},[251,478,367],{"class":257},[251,480,392],{"class":370},[251,482,367],{"class":257},[251,484,397],{"class":257},[251,486,400],{"class":257},[251,488,489],{"class":370},"https:\u002F\u002Fexample.com\u002Fnews\u002F2",[251,491,367],{"class":257},[251,493,376],{"class":257},[251,495,497,499,501,503,505,507,509,511,513,516,518],{"class":253,"line":496},13,[251,498,382],{"class":257},[251,500,385],{"class":326},[251,502,364],{"class":257},[251,504,367],{"class":257},[251,506,421],{"class":370},[251,508,367],{"class":257},[251,510,397],{"class":257},[251,512,400],{"class":257},[251,514,515],{"class":370},"The excerpt of another news entry.",[251,517,367],{"class":257},[251,519,435],{"class":257},[251,521,523],{"class":253,"line":522},14,[251,524,294],{"emptyLinePlaceholder":293},[251,526,528,532,534,536,538,540,542,545,547],{"class":253,"line":527},15,[251,529,531],{"class":530},"s7zQu","      return",[251,533,355],{"class":304},[251,535,358],{"class":257},[251,537,361],{"class":326},[251,539,364],{"class":257},[251,541,367],{"class":257},[251,543,544],{"class":370},"teaser-listing",[251,546,367],{"class":257},[251,548,376],{"class":257},[251,550,552,554,557,559,561,564,566,568,571,573],{"class":253,"line":551},16,[251,553,382],{"class":257},[251,555,556],{"class":326},"setSlotFromNestedElements",[251,558,364],{"class":257},[251,560,367],{"class":257},[251,562,563],{"class":370},"default",[251,565,367],{"class":257},[251,567,397],{"class":257},[251,569,570],{"class":257}," $",[251,572,346],{"class":261},[251,574,435],{"class":257},[251,576,578],{"class":253,"line":577},17,[251,579,580],{"class":257},"    }\n",[251,582,584],{"class":253,"line":583},18,[251,585,586],{"class":257},"  }\n",[232,588,589],{},"This creates:",[241,591,595],{"className":592,"code":593,"language":594,"meta":247,"style":247},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cteaser-listing title=\"Latest news\" icon=\"news\">\n    \u003Carticle-teaser\n        href=\"https:\u002F\u002Fexample.com\u002Fnews\u002F1\"\n        excerpt=\"The excerpt of the news entry.\"\n    >\n    \u003C\u002Farticle-teaser>\n    \u003Carticle-teaser\n        href=\"https:\u002F\u002Fexample.com\u002Fnews\u002F2\"\n        excerpt=\"The excerpt of another news entry.\"\n    >\n    \u003C\u002Farticle-teaser>\n\u003C\u002Fteaser-listing>\n","html",[236,596,597,634,642,656,669,674,683,689,701,713,717,725],{"__ignoreMap":247},[251,598,599,602,605,608,611,614,617,619,622,624,626,629,631],{"class":253,"line":254},[251,600,601],{"class":257},"\u003C",[251,603,544],{"class":604},"swJcz",[251,606,607],{"class":300}," title",[251,609,610],{"class":257},"=",[251,612,613],{"class":257},"\"",[251,615,616],{"class":370},"Latest news",[251,618,613],{"class":257},[251,620,621],{"class":300}," icon",[251,623,610],{"class":257},[251,625,613],{"class":257},[251,627,628],{"class":370},"news",[251,630,613],{"class":257},[251,632,633],{"class":257},">\n",[251,635,636,639],{"class":253,"line":265},[251,637,638],{"class":257},"    \u003C",[251,640,641],{"class":604},"article-teaser\n",[251,643,644,647,649,651,653],{"class":253,"line":290},[251,645,646],{"class":300},"        href",[251,648,610],{"class":257},[251,650,613],{"class":257},[251,652,403],{"class":370},[251,654,655],{"class":257},"\"\n",[251,657,658,661,663,665,667],{"class":253,"line":297},[251,659,660],{"class":300},"        excerpt",[251,662,610],{"class":257},[251,664,613],{"class":257},[251,666,430],{"class":370},[251,668,655],{"class":257},[251,670,671],{"class":253,"line":317},[251,672,673],{"class":257},"    >\n",[251,675,676,679,681],{"class":253,"line":335},[251,677,678],{"class":257},"    \u003C\u002F",[251,680,371],{"class":604},[251,682,633],{"class":257},[251,684,685,687],{"class":253,"line":340},[251,686,638],{"class":257},[251,688,641],{"class":604},[251,690,691,693,695,697,699],{"class":253,"line":379},[251,692,646],{"class":300},[251,694,610],{"class":257},[251,696,613],{"class":257},[251,698,489],{"class":370},[251,700,655],{"class":257},[251,702,703,705,707,709,711],{"class":253,"line":410},[251,704,660],{"class":300},[251,706,610],{"class":257},[251,708,613],{"class":257},[251,710,515],{"class":370},[251,712,655],{"class":257},[251,714,715],{"class":253,"line":438},[251,716,673],{"class":257},[251,718,719,721,723],{"class":253,"line":443},[251,720,678],{"class":257},[251,722,371],{"class":604},[251,724,633],{"class":257},[251,726,727,730,732],{"class":253,"line":470},[251,728,729],{"class":257},"\u003C\u002F",[251,731,544],{"class":604},[251,733,633],{"class":257},[735,736,738],"h3",{"id":737},"slots","Slots",[232,740,741,742,744,745,748,749,752],{},"Slots are used for passing nested, arbitrary content. Slots are named and can have one or multiple child elements. The child elements keep their ordering, unless a custom weight is passed. The ",[236,743,563],{}," slot is a special slot name, which is used for nested markup without a given slot-name, e.g. ",[236,746,747],{},"\u003Cthe-element>some-nested-content\u003C\u002Fthe-element>",", which is the same as ",[236,750,751],{},"\u003Cthe-element>\u003Cslot name=\"default\">some-nested-content\u003C\u002Fslot>\u003C\u002Fthe-element>",".",[735,754,756],{"id":755},"attributes","Attributes",[232,758,759],{},"Besides slot, an element may contain any number of attributes, which are key value pairs. Attribute values can be scalars and arrays, which - when rendered into markup format - become a JSON-encoded string.",[735,761,763],{"id":762},"cache-metadata","Cache Metadata",[232,765,766,767,774,775,778],{},"Custom elements integrate with Drupal's ",[768,769,773],"a",{"href":770,"rel":771},"https:\u002F\u002Fwww.drupal.org\u002Fdocs\u002F8\u002Fapi\u002Fcache-api\u002Fcacheabledependencyinterface-friends",[772],"nofollow","cache API",", by allowing to define their caching dependencies via cache tags and their cache context. They implement the ",[236,776,777],{},"CacheableDependencyInterface",", so their cache dependencies can be easily added as usual, for example entities:",[241,780,782],{"className":243,"code":781,"language":246,"meta":247,"style":247},"$custom_element->addCacheableDependency($entity);\n",[236,783,784],{"__ignoreMap":247},[251,785,786,789,792,795,798,801,804],{"class":253,"line":254},[251,787,788],{"class":257},"$",[251,790,791],{"class":261},"custom_element",[251,793,794],{"class":257},"->",[251,796,797],{"class":326},"addCacheableDependency",[251,799,800],{"class":257},"($",[251,802,803],{"class":261},"entity",[251,805,435],{"class":257},[232,807,808],{},"When a tree of elements is rendered, cache metadata of individual elements is aggregated and bubbled up to the page, just as with Drupal's traditional render system.",[735,810,812],{"id":811},"api-documentation","API documentation",[232,814,815,816,819],{},"For detailed API documentation please refer to the in-code API documentation of the ",[236,817,818],{},"\\Drupal\\custom_elements\\CustomElement"," class.",[227,821,823],{"id":822},"rendering-into-custom-elements","Rendering into custom elements",[232,825,826],{},"For rendering entities, and more generally any kind of data, into custom elements, the module provides the custom element generator service:",[241,828,830],{"className":243,"code":829,"language":246,"meta":247,"style":247},"    \u003C?php\n    class SomeClass {\n      use CustomElementGeneratorTrait;\n      public function someMethod() {\n        $custom_element = $this->getCustomElementGenerator()\n          ->generate($entity, $view_mode);\n      }\n    }\n",[236,831,832,839,849,859,873,892,913,918],{"__ignoreMap":247},[251,833,834,837],{"class":253,"line":254},[251,835,836],{"class":257},"    \u003C?",[251,838,262],{"class":261},[251,840,841,844,847],{"class":253,"line":265},[251,842,843],{"class":300},"    class",[251,845,846],{"class":304}," SomeClass",[251,848,314],{"class":257},[251,850,851,854,857],{"class":253,"line":290},[251,852,853],{"class":268},"      use",[251,855,856],{"class":261}," CustomElementGeneratorTrait",[251,858,287],{"class":257},[251,860,861,864,866,869,871],{"class":253,"line":297},[251,862,863],{"class":300},"      public",[251,865,323],{"class":300},[251,867,868],{"class":326}," someMethod",[251,870,330],{"class":257},[251,872,314],{"class":257},[251,874,875,878,881,883,886,889],{"class":253,"line":317},[251,876,877],{"class":257},"        $",[251,879,880],{"class":261},"custom_element ",[251,882,610],{"class":257},[251,884,885],{"class":257}," $this->",[251,887,888],{"class":326},"getCustomElementGenerator",[251,890,891],{"class":257},"()\n",[251,893,894,897,900,902,904,906,908,911],{"class":253,"line":335},[251,895,896],{"class":257},"          ->",[251,898,899],{"class":326},"generate",[251,901,800],{"class":257},[251,903,803],{"class":261},[251,905,397],{"class":257},[251,907,570],{"class":257},[251,909,910],{"class":261},"view_mode",[251,912,435],{"class":257},[251,914,915],{"class":253,"line":340},[251,916,917],{"class":257},"      }\n",[251,919,920],{"class":253,"line":379},[251,921,580],{"class":257},[232,923,924,925,928],{},"This will render into custom elements as configured for the entity. Refer to ",[768,926,927],{"href":35},"Customized API output"," for an overview.",[232,930,931,932,935],{},"For other kind of data, for some field items, the data may be processed via \"automatic processing\" which makes use of ",[768,933,934],{"href":147},"custom element processors",":",[241,937,939],{"className":243,"code":938,"language":246,"meta":247,"style":247},"    \u003C?php\n    class SomeClass {\n      use CustomElementGeneratorTrait;\n      public function someMethod() {\n        $element = CustomElement::create('some-element');\n        $this->getCustomElementGenerator()\n          ->process($items, $element, $view_mode);\n      }\n    }\n",[236,940,941,947,955,963,975,1001,1010,1037,1041],{"__ignoreMap":247},[251,942,943,945],{"class":253,"line":254},[251,944,836],{"class":257},[251,946,262],{"class":261},[251,948,949,951,953],{"class":253,"line":265},[251,950,843],{"class":300},[251,952,846],{"class":304},[251,954,314],{"class":257},[251,956,957,959,961],{"class":253,"line":290},[251,958,853],{"class":268},[251,960,856],{"class":261},[251,962,287],{"class":257},[251,964,965,967,969,971,973],{"class":253,"line":297},[251,966,863],{"class":300},[251,968,323],{"class":300},[251,970,868],{"class":326},[251,972,330],{"class":257},[251,974,314],{"class":257},[251,976,977,979,982,984,986,988,990,992,994,997,999],{"class":253,"line":317},[251,978,877],{"class":257},[251,980,981],{"class":261},"element ",[251,983,610],{"class":257},[251,985,355],{"class":304},[251,987,358],{"class":257},[251,989,361],{"class":326},[251,991,364],{"class":257},[251,993,367],{"class":257},[251,995,996],{"class":370},"some-element",[251,998,367],{"class":257},[251,1000,435],{"class":257},[251,1002,1003,1006,1008],{"class":253,"line":335},[251,1004,1005],{"class":257},"        $this->",[251,1007,888],{"class":326},[251,1009,891],{"class":257},[251,1011,1012,1014,1017,1019,1022,1024,1026,1029,1031,1033,1035],{"class":253,"line":340},[251,1013,896],{"class":257},[251,1015,1016],{"class":326},"process",[251,1018,800],{"class":257},[251,1020,1021],{"class":261},"items",[251,1023,397],{"class":257},[251,1025,570],{"class":257},[251,1027,1028],{"class":261},"element",[251,1030,397],{"class":257},[251,1032,570],{"class":257},[251,1034,910],{"class":261},[251,1036,435],{"class":257},[251,1038,1039],{"class":253,"line":379},[251,1040,917],{"class":257},[251,1042,1043],{"class":253,"line":410},[251,1044,580],{"class":257},[227,1046,1048],{"id":1047},"serializing-to-markup-or-json","Serializing to markup or JSON",[232,1050,1051,1052,1055,1056,1059],{},"A tree of custom elements can be output in ",[236,1053,1054],{},"markup"," or ",[236,1057,1058],{},"JSON"," format:",[735,1061,1063],{"id":1062},"serializing-to-json","Serializing to JSON",[232,1065,1066],{},"For serializing a tree of custom elements into JSON make use of the provided normalizer:",[241,1068,1070],{"className":243,"code":1069,"language":246,"meta":247,"style":247},"    \u003C?php\n      $custom_element_normalizer = \\Drupal::service('custom_elements.normalizer');\n      $bubbleable_metadata = BubbleableMetadata::createFromObject($custom_element);\n      $json = $custom_element_normalizer->normalize($custom_element, NULL, ['cache_metadata' => $bubbleable_metadata]);\n",[236,1071,1072,1078,1107,1130],{"__ignoreMap":247},[251,1073,1074,1076],{"class":253,"line":254},[251,1075,836],{"class":257},[251,1077,262],{"class":261},[251,1079,1080,1082,1085,1087,1089,1091,1093,1096,1098,1100,1103,1105],{"class":253,"line":265},[251,1081,343],{"class":257},[251,1083,1084],{"class":261},"custom_element_normalizer ",[251,1086,610],{"class":257},[251,1088,272],{"class":257},[251,1090,124],{"class":304},[251,1092,358],{"class":257},[251,1094,1095],{"class":326},"service",[251,1097,364],{"class":257},[251,1099,367],{"class":257},[251,1101,1102],{"class":370},"custom_elements.normalizer",[251,1104,367],{"class":257},[251,1106,435],{"class":257},[251,1108,1109,1111,1114,1116,1119,1121,1124,1126,1128],{"class":253,"line":290},[251,1110,343],{"class":257},[251,1112,1113],{"class":261},"bubbleable_metadata ",[251,1115,610],{"class":257},[251,1117,1118],{"class":304}," BubbleableMetadata",[251,1120,358],{"class":257},[251,1122,1123],{"class":326},"createFromObject",[251,1125,800],{"class":257},[251,1127,791],{"class":261},[251,1129,435],{"class":257},[251,1131,1132,1134,1137,1139,1141,1144,1146,1149,1151,1153,1155,1158,1161,1163,1166,1168,1171,1173,1176],{"class":253,"line":297},[251,1133,343],{"class":257},[251,1135,1136],{"class":261},"json ",[251,1138,610],{"class":257},[251,1140,570],{"class":257},[251,1142,1143],{"class":261},"custom_element_normalizer",[251,1145,794],{"class":257},[251,1147,1148],{"class":326},"normalize",[251,1150,800],{"class":257},[251,1152,791],{"class":261},[251,1154,397],{"class":257},[251,1156,1157],{"class":257}," NULL,",[251,1159,1160],{"class":257}," [",[251,1162,367],{"class":257},[251,1164,1165],{"class":370},"cache_metadata",[251,1167,367],{"class":257},[251,1169,1170],{"class":257}," =>",[251,1172,570],{"class":257},[251,1174,1175],{"class":261},"bubbleable_metadata",[251,1177,1178],{"class":257},"]);\n",[735,1180,1182],{"id":1181},"serializing-to-markup","Serializing to markup",[232,1184,1185],{},"For generating markup for a tree of custom elements, simply render it via the Drupal's traditional render API:",[241,1187,1189],{"className":243,"code":1188,"language":246,"meta":247,"style":247},"  \u003C?php\n    $render = $custom_element->toRenderArray();\n    $renderer = \\Drupal::service('renderer');\n    $markup = $renderer->renderRoot($customElement);\n  ?>\n",[236,1190,1191,1198,1220,1248,1273],{"__ignoreMap":247},[251,1192,1193,1196],{"class":253,"line":254},[251,1194,1195],{"class":257},"  \u003C?",[251,1197,262],{"class":261},[251,1199,1200,1203,1206,1208,1210,1212,1214,1217],{"class":253,"line":265},[251,1201,1202],{"class":257},"    $",[251,1204,1205],{"class":261},"render ",[251,1207,610],{"class":257},[251,1209,570],{"class":257},[251,1211,791],{"class":261},[251,1213,794],{"class":257},[251,1215,1216],{"class":326},"toRenderArray",[251,1218,1219],{"class":257},"();\n",[251,1221,1222,1224,1227,1229,1231,1233,1235,1237,1239,1241,1244,1246],{"class":253,"line":290},[251,1223,1202],{"class":257},[251,1225,1226],{"class":261},"renderer ",[251,1228,610],{"class":257},[251,1230,272],{"class":257},[251,1232,124],{"class":304},[251,1234,358],{"class":257},[251,1236,1095],{"class":326},[251,1238,364],{"class":257},[251,1240,367],{"class":257},[251,1242,1243],{"class":370},"renderer",[251,1245,367],{"class":257},[251,1247,435],{"class":257},[251,1249,1250,1252,1255,1257,1259,1261,1263,1266,1268,1271],{"class":253,"line":297},[251,1251,1202],{"class":257},[251,1253,1254],{"class":261},"markup ",[251,1256,610],{"class":257},[251,1258,570],{"class":257},[251,1260,1243],{"class":261},[251,1262,794],{"class":257},[251,1264,1265],{"class":326},"renderRoot",[251,1267,800],{"class":257},[251,1269,1270],{"class":261},"customElement",[251,1272,435],{"class":257},[251,1274,1275],{"class":253,"line":317},[251,1276,1277],{"class":257},"  ?>\n",[735,1279,1281],{"id":1280},"custom-element-markup-styles","Custom Element markup styles",[232,1283,1284,1285,1290],{},"Custom elements use \"slots\" for handling content distribution, i.e. for passing\nnested content to an element. However, the concrete syntax used for handling\nslots may differ by various frameworks. Thus, the module supports rendering to\ndifferent markup styles while it defaults to the Web component style syntax. In addition,\nthe module supports the ",[768,1286,1289],{"href":1287,"rel":1288},"https:\u002F\u002Fvuejs.org\u002Fv2\u002Fguide\u002Fcomponents-slots.html#Named-Slots-Shorthand",[772],"Vue2 and Vue 3"," syntax which can be enabled via config:",[241,1292,1296],{"className":1293,"code":1294,"language":1295,"meta":247,"style":247},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","drush config:set custom_elements.settings  markup_style vue-3\n","bash",[236,1297,1298],{"__ignoreMap":247},[251,1299,1300,1303,1306,1309,1312],{"class":253,"line":254},[251,1301,1302],{"class":304},"drush",[251,1304,1305],{"class":370}," config:set",[251,1307,1308],{"class":370}," custom_elements.settings",[251,1310,1311],{"class":370},"  markup_style",[251,1313,1314],{"class":370}," vue-3\n",[227,1316,1318],{"id":1317},"traditional-render-arrays","Traditional render arrays",[232,1320,1321],{},"Custom elements may be rendered using Drupal's traditional render API:",[241,1323,1325],{"className":243,"code":1324,"language":246,"meta":247,"style":247},"  \u003C?php\n    $render[] = $custom_element->toRenderArray();\n  ?>\n",[236,1326,1327,1333,1354],{"__ignoreMap":247},[251,1328,1329,1331],{"class":253,"line":254},[251,1330,1195],{"class":257},[251,1332,262],{"class":261},[251,1334,1335,1337,1340,1342,1344,1346,1348,1350,1352],{"class":253,"line":265},[251,1336,1202],{"class":257},[251,1338,1339],{"class":261},"render",[251,1341,349],{"class":257},[251,1343,352],{"class":257},[251,1345,570],{"class":257},[251,1347,791],{"class":261},[251,1349,794],{"class":257},[251,1351,1216],{"class":326},[251,1353,1219],{"class":257},[251,1355,1356],{"class":253,"line":290},[251,1357,1277],{"class":257},[232,1359,1360],{},"On the other hand, it's possible to wrap a traditional render array into a custom element:",[241,1362,1364],{"className":243,"code":1363,"language":246,"meta":247,"style":247},"  \u003C?php\n    $custom_element = CustomElement::createFromRenderArray($render_array);\n  ?>\n",[236,1365,1366,1372,1394],{"__ignoreMap":247},[251,1367,1368,1370],{"class":253,"line":254},[251,1369,1195],{"class":257},[251,1371,262],{"class":261},[251,1373,1374,1376,1378,1380,1382,1384,1387,1389,1392],{"class":253,"line":265},[251,1375,1202],{"class":257},[251,1377,880],{"class":261},[251,1379,610],{"class":257},[251,1381,355],{"class":304},[251,1383,358],{"class":257},[251,1385,1386],{"class":326},"createFromRenderArray",[251,1388,800],{"class":257},[251,1390,1391],{"class":261},"render_array",[251,1393,435],{"class":257},[251,1395,1396],{"class":253,"line":290},[251,1397,1277],{"class":257},[232,1399,1400,1401,1404,1405,1408],{},"The resulting element can be further customized, but by default it simply renders the ",[236,1402,1403],{},"$render_array"," and wraps it into a ",[236,1406,1407],{},"\u003Cdrupal-markup>"," element, that the frontend may simply output.",[1410,1411,1412],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":247,"searchDepth":265,"depth":265,"links":1414},[1415,1421,1422,1427],{"id":229,"depth":265,"text":230,"children":1416},[1417,1418,1419,1420],{"id":737,"depth":290,"text":738},{"id":755,"depth":290,"text":756},{"id":762,"depth":290,"text":763},{"id":811,"depth":290,"text":812},{"id":822,"depth":265,"text":823},{"id":1047,"depth":265,"text":1048,"children":1423},[1424,1425,1426],{"id":1062,"depth":290,"text":1063},{"id":1181,"depth":290,"text":1182},{"id":1280,"depth":290,"text":1281},{"id":1317,"depth":265,"text":1318},"md",null,{},{"title":134,"description":247},"4HMNLtZsEjRREvp6Bi5ROCvVm4c6B3XB1F4zvsa0pvo",[1434,1436],{"title":130,"path":131,"stem":132,"description":1435,"children":-1},"Lupus Decoupled Drupal builds upon the following two key modules:",{"title":138,"path":139,"stem":140,"description":1437,"children":-1},"The Lupus CE Renderer module takes care of rendering routes of the format custom_elements via Drupal's regular routing system. That means a route can be defined as usual in Drupal, additionally define the _format to be custom_elements:",1776084718159]