When editing a custom elements page view php errors are produced by renderer

Created on 21 August 2024, 29 days ago
Updated 18 September 2024, about 13 hours ago

Problem/Motivation

User error: "current" is an invalid render array key in Drupal\Core\Render\Element::children() (Zeile 98 in /app/web/core/lib/Drupal/Core/Render/Element.php) #0 /app/web/core/includes/bootstrap.inc(164): _drupal_error_handler_real() #1 [internal function]: _drupal_error_handler() #2 /app/web/core/lib/Drupal/Core/Render/Element.php(98): trigger_error() #3 /app/web/core/lib/Drupal/Core/Render/Renderer.php(451): Drupal\Core\Render\Element::children() #4 /app/web/core/lib/Drupal/Core/Render/Renderer.php(493): Drupal\Core\Render\Renderer->doRender() #5 /app/web/core/lib/Drupal/Core/Render/Renderer.php(240): Drupal\Core\Render\Renderer->doRender() #6 /app/web/core/lib/Drupal/Core/Template/TwigExtension.php(475): Drupal\Core\Render\Renderer->render() #7 /app/files/public/php/twig/66c34be9ce8a5_views-ui-view-preview-sec_R4Lu2fL_DwddDSbeJW6zDMV9A/hyDakoD_a3SoCXz-3CZyiTc9EtvBLxEznSweLH5KAJQ.php(53): Drupal\Core\Template\TwigExtension->escapeFilter() #8 /app/vendor/twig/twig/src/Template.php(394): __TwigTemplate_dfebbeee6d7ee9dac90233a7e9bcec36->doDisplay() #9 /app/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling() #10 /app/vendor/twig/twig/src/Template.php(379): Twig\Template->display() #11 /app/vendor/twig/twig/src/TemplateWrapper.php(38): Twig\Template->render() #12 /app/web/core/themes/engines/twig/twig.engine(39): Twig\TemplateWrapper->render() #13 /app/web/core/lib/Drupal/Core/Theme/ThemeManager.php(348): twig_render_template() #14 /app/web/core/lib/Drupal/Core/Render/Renderer.php(480): Drupal\Core\Theme\ThemeManager->render() #15 /app/web/core/lib/Drupal/Core/Render/Renderer.php(240): Drupal\Core\Render\Renderer->doRender() #16 /app/web/core/lib/Drupal/Core/Template/TwigExtension.php(475): Drupal\Core\Render\Renderer->render() #17 /app/files/public/php/twig/66c34be9ce8a5_views-view.html.twig_2OpeE5BICqayh_oKYRMjemu0J/1XG_hB2O6JDb1wPqx9ui7IbuvUmBXiXrxTPCjZIHvzo.php(110): Drupal\Core\Template\TwigExtension->escapeFilter() #18 /app/vendor/twig/twig/src/Template.php(394): __TwigTemplate_3df5a23c0c1ad5e281e11fbd1090d8fb->doDisplay() #19 /app/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling() #20 /app/vendor/twig/twig/src/Template.php(379): Twig\Template->display() #21 /app/vendor/twig/twig/src/TemplateWrapper.php(38): Twig\Template->render() #22 /app/web/core/themes/engines/twig/twig.engine(39): Twig\TemplateWrapper->render() #23 /app/web/core/lib/Drupal/Core/Theme/ThemeManager.php(348): twig_render_template() #24 /app/web/core/lib/Drupal/Core/Render/Renderer.php(480): Drupal\Core\Theme\ThemeManager->render() #25 /app/web/core/lib/Drupal/Core/Render/Renderer.php(493): Drupal\Core\Render\Renderer->doRender() #26 /app/web/core/lib/Drupal/Core/Render/Renderer.php(493): Drupal\Core\Render\Renderer->doRender() #27 /app/web/core/lib/Drupal/Core/Render/Renderer.php(493): Drupal\Core\Render\Renderer->doRender() #28 /app/web/core/lib/Drupal/Core/Render/Renderer.php(240): Drupal\Core\Render\Renderer->doRender() #29 /app/web/core/lib/Drupal/Core/Render/Renderer.php(153): Drupal\Core\Render\Renderer->render() #30 /app/web/core/lib/Drupal/Core/Render/Renderer.php(627): Drupal\Core\Render\Renderer->Drupal\Core\Render\{closure}() #31 /app/web/core/lib/Drupal/Core/Render/Renderer.php(154): Drupal\Core\Render\Renderer->executeInRenderContext() #32 /app/web/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php(66): Drupal\Core\Render\Renderer->renderRoot() #33 /app/web/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\AjaxRenderer->renderResponse() #34 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray() #35 /app/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func() #36 /app/vendor/symfony/http-kernel/HttpKernel.php(186): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() #37 /app/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw() #38 /app/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle() #39 /app/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle() #40 /app/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle() #41 /app/web/modules/contrib/lupus_decoupled/modules/lupus_decoupled_ce_api/src/BackendApiRequest.php(107): Drupal\Core\StackMiddleware\ContentLength->handle() #42 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\lupus_decoupled_ce_api\BackendApiRequest->handle() #43 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass() #44 /app/web/modules/drunomics/ldp-core/modules/ldp_cdn/src/FixedBaseUrlMiddleware.php(85): Drupal\page_cache\StackMiddleware\PageCache->handle() #45 /app/vendor/asm89/stack-cors/src/Cors.php(53): Drupal\ldp_cdn\FixedBaseUrlMiddleware->handle() #46 /app/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Asm89\Stack\Cors->handle() #47 /app/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() #48 /app/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() #49 /app/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle() #50 /app/web/core/lib/Drupal/Core/DrupalKernel.php(704): Drupal\Core\StackMiddleware\StackedHttpKernel->handle() #51 /app/web/index.php(19): Drupal\Core\DrupalKernel->handle() #52 {main}.

Steps to reproduce

Edit a custom elements page in views.

Findings and proposed resolution

The Custom Elements row style plugin is creating an invalid render array. (The 'rows' and 'pager' elements are not renderable by 'stock' Drupal.) Its data structure is set up to be only valid for/renderable by the lupus_decoupled controller route.

The Custom Elements row style plugin should be fixed to create a valid Drupal render array, which preview (and 'regular' display plugins) can handle without producing errors.

Then, any extra data that the lupus_decoupled controller route needs, should be added to it in a way that does not make the array invalid. (Update: this seems unnecessary; the controller can pick the data from the render array.)

Bonus: move Custom Elements specific code from the controller route into the CustomElementsPage display plugin. The route is only applied to views with that plugin, so it makes sense.

🐛 Bug report
Status

RTBC

Version

1.0

Component

Code

Created by

🇸🇮Slovenia useernamee Ljubljana

Live updates comments and jobs are added and updated live.
  • views

    Involves, uses, or integrates with views. In Drupal 8 core, use the “VDC” tag instead.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @useernamee
  • Status changed to Postponed: needs info 24 days ago
  • 🇦🇹Austria fago Vienna

    Which version of core / lupus-decoupeld are affected?

  • Status changed to Needs work 22 days ago
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    I'm getting the same issue on Core 10.3.1 and Lupus decoupled 1.0.0-beta6 and custom elements 2.5.0

    The problem seems to be occurring because a paragraphs views reference field is causing a view to be rendered on the node edit form (this is the desired behaviour) and the lupus_decoupled_views modules is adding things to the render array that Drupal's renderer cannot process. It's adding things in \Drupal\lupus_decoupled_views\Plugin\views\style\CustomElements::render() and \Drupal\lupus_decoupled_views\Plugin\views\style\CustomElements::render() that will cause errors in \Drupal\Core\Render\Element::children()... I would have expected some sort of pre_render callback to process them but I don't know enough about how the custom elements module works at the moment.

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    This has only been causing issues on Drupal 10.3 due to 📌 Replace calls to ::expectError*() from Drupal\Tests\Core\Render\ElementTest Fixed which changed an E_USER_ERROR to an exception in the renderer. I think \Drupal\lupus_decoupled_views\Plugin\views\style\CustomElements::render() needs changing to use render arrays rather than just dumping stuff into the render array. However this module has always been cause notices like User error: "total_items" is an invalid render array key in Drupal\Core\Render\Element::children() in the logs.

  • 🇸🇮Slovenia useernamee Ljubljana

    I was only testing this with custom elements v3.

    I'll open a PR with a fix, and hopefully it will work for you as well @alexpott.

  • 🇸🇮Slovenia useernamee Ljubljana

    I'm not sure how good this solution is, but the errors are gone and there is a simple preview of what custom element view will show.

    Other option would be, to disable the preview or maybe write a nice template to print out the custom elements render array.

  • 🇦🇹Austria fago Vienna

    Not sure why/how the CustomElement style plugin gets called for a view that - as I understand - is not related to custom elements?

    Anyway, as pointed out there are errors produced else as well, so we definitely have an issue here. As it seems, the render() method is supposed to return a render array, and we aren't, what leads to the problem.

    At the same time, it's also not completing the rendering atm, we have the code that puts the final touches on it in \Drupal\lupus_decoupled_views\Controller\ViewsController::viewsView. So what about moving that final touches

    
        // Build a view as a custom element.
        $custom_element = new CustomElement();
        $custom_element->setTag('drupal-view');
        $custom_element->setAttribute('title', $view->getTitle());
        $custom_element->setAttribute('view_id', $view_id);
        $custom_element->setAttribute('display_id', $display_id);
        $custom_element->setAttribute('args', $args);
        $custom_element->setAttribute('pager', $result['#rows']['pager'] ?? []);
        $custom_element->setSlotFromNestedElements('rows', $result['#rows']['rows'] ?? []);
        $custom_element->addCacheableDependency(BubbleableMetadata::createFromRenderArray($result));
    
        // Allow other modules to change the custom element without replacing the
        // entire method.
        $this->moduleHandler()->alter('lupus_decoupled_views_page_alter', $custom_element);
    

    to the render() method and returning the expected renderable via $element->toRenderArray()? That would solve the code-reusing issue I commented on the MR above as well.

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    @fago yes \Drupal\lupus_decoupled_views\Plugin\views\style\CustomElements::render() is supposed to to return a renderable array - but it doesn't in 2 two ways:

    • $result['rows'][] = $custom_element; - $custom_element is not a renderable. I think this should be $result['rows'][] = $custom_element->toRenderArray();
    • And then there's $result['pager'] = $this->pagination($result['rows']); this also cause issues that are harder to see how to fix because of what \Drupal\lupus_decoupled_views\Controller\ViewsController::viewsView() is expecting.
  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    Not sure why/how the CustomElement style plugin gets called for a view that - as I understand - is not related to custom elements?

    In our case the view definitely is supposed to use CustomElements - it's just not using \Drupal\lupus_decoupled_views\Plugin\views\display\CustomElementsPage or \Drupal\lupus_decoupled_views\Controller\ViewsController::viewsView. It's a views reference field in a paragraph.

  • Assigned to useernamee
  • 🇸🇮Slovenia useernamee Ljubljana

    I was mostly investigating the view preview (/admin/structure/view/). There is an issue that renderer doesn't know how to render custom element object or #custom_elements render array. That's why I did convert it to #markup render array.

    I did investigate the render method, but overriding it, to return render array of #type custom_element did not produce good results.

    I'm not sure why we even need the override with ViewsController. Seems like \Drupal\views\Routing\ViewPageController::handle only calls buildResponse and buildBasicRenderable so I think we should add our logic in these two methods in CustomElementsPage views plugin and there's no need for the ViewsController.

      /**
       * Builds a basic render array which can be properly render cached.
       *
       * In order to be rendered cached, it includes cache keys as well as the data
       * required to load the view on cache misses.
       *
       * @param string $view_id
       *   The view ID.
       * @param string $display_id
       *   The display ID.
       * @param array $args
       *   (optional) The view arguments.
       *
       * @return array
       *   The view render array.
       */
      public static function buildBasicRenderable($view_id, $display_id, array $args = []);

    and

      /**
       * Builds up a response with the rendered view as content.
       *
       * @param string $view_id
       *   The view ID.
       * @param string $display_id
       *   The display ID.
       * @param array $args
       *   (optional) The arguments of the view.
       *
       * @return \Symfony\Component\HttpFoundation\Response
       *   The built response.
       */
      public static function buildResponse($view_id, $display_id, array $args = []);
  • 🇸🇮Slovenia useernamee Ljubljana

    I did try to test out the second approach as well by implementing Drupal\views\Plugin\views\display\ResponseDisplayPluginInterface similar to what Feeds view display does, but I got problems with the early rendering that doesn't seem to easy to resolve:

    LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Ensure you are not rendering content too early. Returned object class: Drupal\Core\Cache\CacheableJsonResponse. in Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (line 154 of core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php).

    So this PR 90 is non working concept.

    ---

    @fago could you review PR 89?

  • 🇦🇹Austria fago Vienna

    > I'm not sure why we even need the override with ViewsController.

    We might need it for the Lupus-CE-Renderer to pickup the responses cleanly. I'm not sure it does so with a custom element render array, we might need to return the CE-object. If it supports the CE-render array also we might be fine without the controller.

    Anyway, if the controller does not cause issues in general, let's better keep it and solely focus on fixing the bug.

  • 🇸🇮Slovenia useernamee Ljubljana

    @alexpott

    So, I've ran some tests on custom_elements 3.x and lupus_decoupled_views. Having my PR 89 active, the issue in view preview is resolved. I wasn't able to reproduce the issue in referenced entities while checking the views, but I only tested with view configured in a way to show a Content with viewmode that has custom elements display enabled.

  • Assigned to fago
  • Status changed to Needs review 14 days ago
  • 🇸🇮Slovenia useernamee Ljubljana
  • 🇳🇱Netherlands roderik Amsterdam,NL / Budapest,HU

    @alexpott / @useernamee

    The 'v2 way of rendering' (Processors) is still the same in v3, so there should be no need to test on v3. We should even be able to test these issues (that don't trigger any use of v3-style Custom Elements Displays) by temporarily copying v2 code back over v3.... for the moment at least.

    I'm just noting this befause updating to v3 is explicitly non-trivial.

    If possible / for the moment, any fix that comes out of this will be applied to the v2 branch also.

  • 🇬🇧United Kingdom alexpott 🇪🇺🌍

    PR89 is not going to solve my problem because \Drupal\lupus_decoupled_views\Plugin\views\style\CustomElements::render() adds things to a render array array that are not renderable. As long as the module continues to do that anything that embeds the view is going to have problems. The fix in PR89 is a workaround for this only for preview but there are other cases we this occurs.

    I far as I can see, if \Drupal\lupus_decoupled_views\Plugin\views\style\CustomElements::render() continues to return a non-renderable array, you'll continue to have unexpected issues due to the approach.

  • Status changed to Needs work 13 days ago
  • 🇦🇹Austria fago Vienna

    I don't see why this issue is related to the custom elements version, the APIs used did not change at all. So the fix should apply to both just fine.

    Anyway, I very much agree with alex pott that we need to fix render() to return a proper render array.
    Also added some comments to the MR.

  • 🇸🇮Slovenia useernamee Ljubljana

    If I return render_array of type #custom_elements, this is returned in preview (browser does not display it):

    <div class="preview-section"><drupal-view title="" view-id="te" display-id="custom_elements_page" :pager="{&quot;total_pages&quot;:2,&quot;current&quot;:0}"><template #rows="">
    <teaser-wide href="http://devblog.ldp-project.localdev.space/drupal/custom-elements-our-solution-soft-decoupled-drupal-57" title="Custom Elements: A solution for soft-decoupled Drupal!" category="Thunder core" excerpt="When it comes to decoupling, it turns out there are many options on how to decouple. Not only are there many technology choices in choosing the right frontend framework and APIs involved, the questions become also more foundational: Which system should be in charge for handing different aspects of the applicaiton, e.g. routing, placing blocks or authentication?" :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/chocolate-brownie-umami.jpg?itok=jcNG8O0W&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Alt Placeholder&quot;,&quot;title&quot;:&quot;\u00a9 GPL v2+\nSource: Drupal core umami installprofile&quot;}" published-at="27. March 2021"></teaser-wide>
    <teaser-wide href="http://devblog.ldp-project.localdev.space/drupal/der-splash-award-der-kategorie-verlage-medien-geht-zum-dritten-mal-folge-drunomics" title="Der Splash Award in der Kategorie Verlage / Medien geht 2020 zum dritten Mal in Folge an drunomics" category="Thunder core" excerpt="Die ExpertInnen für performante Webanwendungen von drunomics wurden heuer für das Drupal-Projekt „Wirtschaftsverlag Contentpool und Media Satellite-Sites“ ausgezeichnet." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/new_logo.jpg?itok=QNBwEvK_&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Alt Placeholder&quot;,&quot;title&quot;:&quot;\u00a9 drupal.org\nSource: https:\/\/www.drupal.org\/files\/Wordmark2_blue_RGB%281%29.png&quot;}" published-at="27. March 2021"></teaser-wide>
    <teaser-wide href="http://devblog.ldp-project.localdev.space/drupal/nuxtjs-frontend-framework-decoupled-drupal-custom-elements-55" title="Nuxt.js - The frontend framework for decoupled Drupal with Custom Elements" category="Thunder core" excerpt="Nuxt.js is an intuitive, Vue.js based framework. It's the perfect choice for the frontend of our decoupled Drupal stack using custom elements markup." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/d8rules_funded_0.png?itok=Q_z-6VIf&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Alt Placeholder&quot;,&quot;title&quot;:&quot;\u00a9 drunomics Gmbh\nSource: https:\/\/drunomics.com\/files\/d8rules_funded_0.png&quot;}" published-at="27. March 2021"></teaser-wide>
    <teaser-wide href="http://devblog.ldp-project.localdev.space/drupal/drupalcon-2021-presentation-54" title="DrupalCon Europe 2021 Presentation: XML-sitemap optimizations for large sites: a case study." category="Thunder core" excerpt="Today (Oct 5) Liopold Novelli and I will give a presentation at DrupalCon Europe 2021 entitled XML-sitemap optimizations for large sites: a case study." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/drupal_8_logo.jpg?itok=lQClTh_4&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Alt Placeholder&quot;,&quot;title&quot;:&quot;\u00a9 drunomics Gmbh\nSource: https:\/\/drunomics.com\/files\/styles\/sidebar_small\/public\/drupal_8_logo.jpg?itok=8DhABSqA&quot;}" published-at="27. March 2021"></teaser-wide>
    <teaser-wide href="http://devportal.ldp-project.localdev.space/science/importance-ecology-32" title="The importance of ecology" category="Technology" excerpt="Ecology is the study of organisms and how they interact with the environment around them. An ecologist studies the relationship between living things and their habitats. ... To find the answers to these questions, ecologists must study and observe all forms of life and their ecosystems throughout our world." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/the_earth.jpg?itok=vdyij4pF&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;The Earth seen from Apollo 17&quot;,&quot;title&quot;:&quot;\u00a9 NASA\nSource: https:\/\/en.wikipedia.org\/wiki\/Ecology#\/media\/File:The_Earth_seen_from_Apollo_17.jpg&quot;}" published-at="18. March 2021"></teaser-wide>
    <teaser-wide href="http://devportal.ldp-project.localdev.space/science/computer-virus-31" title="Computer virus" category="Technology" excerpt="A computer virus is a piece of code which is capable of copying itself and typically has a detrimental effect, such as corrupting the system or destroying data." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/computer_virus.jpeg?itok=aIGRMzHw&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Black flat screen computer monitor&quot;,&quot;title&quot;:&quot;\u00a9 Jake Walker\nSource: https:\/\/images.unsplash.com\/photo-1608742213509-815b97c30b36&quot;}" published-at="18. March 2021"></teaser-wide>
    <teaser-wide href="http://devportal.ldp-project.localdev.space/science/biological-viruses-30" title="Biological Viruses" category="Technology" excerpt="A virus is a small parasite that cannot reproduce by itself. Once it infects a susceptible cell, however, a virus can direct the cell machinery to produce more viruses. Most viruses have either RNA or DNA as their genetic material. The nucleic acid may be single- or double-stranded." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/bio_virus.jpg?itok=IOTRJIpe&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Biological virus&quot;,&quot;title&quot;:&quot;\u00a9 Alexey Solodovnikov, Valeria Arkhipova\nSource: https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thu\u2026SARS-CoV-2.png\/1024px-Coronavirus._SARS-CoV-2.png&quot;}" published-at="18. March 2021"></teaser-wide>
    <teaser-wide href="http://devportal.ldp-project.localdev.space/science/central-processing-unit-29" title="Central processing unit" category="Technology" excerpt="The computer's central processing unit (CPU) is the portion of a computer that retrieves and executes instructions. The CPU is essentially the brain of a CAD system. It consists of an arithmetic and logic unit (ALU), a control unit, and various registers. The CPU is often simply referred to as the processor." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/intel_cpu.jpg?itok=Dg62blLN&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Intel 80486DX2 top&quot;,&quot;title&quot;:&quot;\u00a9 Solipsist~commonswiki, Andrew Dunn\nSource: https:\/\/upload.wikimedia.org\/wikipedia\/commons\/d\/dc\/Intel_80486DX2_top.jpg&quot;}" published-at="17. March 2021"></teaser-wide>
    <teaser-wide href="http://devportal.ldp-project.localdev.space/science/magnetism-28" title="Magnetism" category="Technology" excerpt="Magnetism is the force exerted by magnets when they attract or repel each other. Magnetism is caused by the motion of electric charges. Every substance is made up of tiny units called atoms. Their movement generates an electric current and causes each electron to act like a microscopic magnet." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/magnets.png?itok=xSB3O017&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;A magnetic quadrupole&quot;,&quot;title&quot;:&quot;\u00a9 K. Aainsqatsi \nSource: https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/9\/93\/Magnetic_quadrupole_moment.svg\/1024px-Magnetic_quadrupole_moment.svg.png&quot;}" published-at="17. March 2021"></teaser-wide>
    <teaser-wide href="http://devportal.ldp-project.localdev.space/science/electricity-explained-27" title="Electricity explained" category="Technology" excerpt="Electricity is the flow of electrical power or charge. It is a secondary energy source which means that we get it from the conversion of other sources of energy, like coal, natural gas, oil, nuclear power and other natural sources, which are called primary sources." :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/lightning.jpg?itok=aPuvfNK0&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Multiple lightning strikes on a city at night&quot;,&quot;title&quot;:&quot;\u00a9 U.S. Air Force photo by Edward Aspera Jr\nSource: https:\/\/upload.wikimedia.org\/wikipedia\/commons\/thumb\/4\/4b\/Lightning3.jpg\/1024px-Lightning3.jpg&quot;}" published-at="17. March 2021"></teaser-wide>
    </template>
    </drupal-view>
    </div>
    

    That's why I converted array to string, pretty print it and show it as markup.

  • 🇦🇹Austria fago Vienna

    replied in drupal issue, but I think the problem is that view's renderer doesn't know how to render custom elements.

    This rendering is good, it's correctly rendering the custom element using markup serialization:

    <div class="preview-section"><drupal-view title="" view-id="te" display-id="custom_elements_page" :pager="{&quot;total_pages&quot;:2,&quot;current&quot;:0}"><template #rows="">
    <teaser-wide href="http://devblog.ldp-project.localdev.space/drupal/custom-elements-our-solution-soft-decoupled-drupal-57" title="Custom Elements: A solution for soft-decoupled Drupal!" category="Thunder core" excerpt="When it comes to decoupling, it turns out there are many options on how to decouple. Not only are there many technology choices in choosing the right frontend framework and APIs involved, the questions become also more foundational: Which system should be in charge for handing different aspects of the applicaiton, e.g. routing, placing blocks or authentication?" :image="{&quot;aspect-ratio&quot;:133.33000000000001,&quot;src&quot;:&quot;http:\/\/admin--example.ldp-project.localdev.space\/sites\/example\/files\/styles\/300_225\/public\/2024-09\/chocolate-brownie-umami.jpg?itok=jcNG8O0W&quot;,&quot;srcset&quot;:null,&quot;alt&quot;:&quot;Alt Placeholder&quot;,&quot;title&quot;:&quot;\u00a9 GPL v2+\nSource: Drupal core umami installprofile&quot;}" published-at="27. March 2021"></teaser-wide>
    ...
    </template>
    </drupal-view>
    </div>
    

    So all seems fine to me. Yes, it's not a frontend rendering, but that's another story.

    That's why I converted array to string, pretty print it and show it as markup.

    Why are you dumping the literal object when the above rendering is already good? Imo, we should simply add <pre> tags around the above custom element rendering (e.g. with #prefix #suffix) to make he markup readable / visible in the browser.

    Yes, that's not a visual preview rendered in the frontend, but that would be a bit more complex and require iframes to correctly go via the decoupled frontend. There is code doing so in the issue 📌 Frontend-rendered layout-builder previews Needs work , so that would be a great addition, but that is clearly out of scope here. Let's have correctly rendered markup shown in the preview for now. We could open a follow-up for a nicely rendered preview via iframes though!

    Also I'm a bit unsure what to do with the pager. So far, I translated it into the custom element, and slot on the view, but I guess we could also leave it as attribute.

    So far the code did:

    $custom_element->setAttribute('pager', $result['#rows']['pager'] ?? []);

    Changing that would be an API break. Why would we do that? Are there issues with the pager?

    Generally speaking, a slot should be used for nested content that may be composed for any kind of content, not for passing data - use attributes for that. So the pager being an attribute is good, so the drupal-view component stays in control of how to render the pager.

  • 🇸🇮Slovenia useernamee Ljubljana

    Changing that would be an API break. Why would we do that? Are there issues with the pager?

    Because of #9 🐛 When editing a custom elements page view php errors are produced by renderer Needs work .

    I'll try out the proposal.

  • 🇸🇮Slovenia useernamee Ljubljana

    @fago I've followed your advice, but the pager is now (again) producing errors on pre-view:

     	User error: "current" is an invalid render array key in…
            User error: "total_pages" is an invalid render array…
    

    Another issue I get now is that markup format is producing an error:
    https://admin--example.ldp-project.localdev.space/admin/test-ce?_content...

    The website encountered an unexpected error. Try again later.<br><br><em class="placeholder">TypeError</em>: strlen(): Argument #1 ($string) must be of type string, array given in <em class="placeholder">strlen()</em> (line <em class="placeholder">395</em> of <em class="placeholder">core/lib/Drupal/Component/Utility/Unicode.php</em>). <pre class="backtrace">Drupal\Component\Utility\Unicode::validateUtf8(Array) (Line: 65)
    Drupal\Component\Utility\Xss::filter(Array, Array) (Line: 830)
    Drupal\Core\Render\Renderer-&gt;ensureMarkupIsSafe(Array) (Line: 427)
    Drupal\Core\Render\Renderer-&gt;doRender(Array) (Line: 493)
    Drupal\Core\Render\Renderer-&gt;doRender(Array, ) (Line: 240)
    Drupal\Core\Render\Renderer-&gt;render(Array) (Line: 475)
    Drupal\Core\Template\TwigExtension-&gt;escapeFilter(Object, Array, &#039;html&#039;, NULL, 1) (Line: 48)
    __TwigTemplate_f87dc8cf16e7d60f6d3486e533c81d7b-&gt;doDisplay(Array, Array) (Line: 394)
    Twig\Template-&gt;displayWithErrorHandling(Array, Array) (Line: 367)
    Twig\Template-&gt;display(Array) (Line: 379)
    Twig\Template-&gt;render(Array) (Line: 38)
    Twig\TemplateWrapper-&gt;render(Array) (Line: 39)
    twig_render_template(&#039;modules/contrib/custom_elements/templates/custom-element.html.twig&#039;, Array) (Line: 348)
    Drupal\Core\Theme\ThemeManager-&gt;render(&#039;custom_element&#039;, Array) (Line: 480)
    Drupal\Core\Render\Renderer-&gt;doRender(Array, 1) (Line: 240)
    
  • 🇦🇹Austria fago Vienna

    From a quick check the MR looks mostly good, except for my remark related to PluginException being the wrong exception is not yet addressed.

    > It works if I don't transform rows in render arrays but leave them as custom elements objects here. The issue is that render transforms render array into markup, but then the value is not string or MakupInterface which it expects.

    hm, not sure I get that. You mean custom elements produces an invalid render array, that cannot be correctly rendered? If so, we should open an issue for fixing that and get that fixed. Returning Markup instead of a plain string would make sense to me. Please work with roderik as necessary to get it addressed.

  • Issue was unassigned.
  • 🇦🇹Austria fago Vienna
  • Status changed to Needs review 3 days ago
  • 🇳🇱Netherlands roderik Amsterdam,NL / Budapest,HU

    I did not know this code yet, and/so could not make out from the discussion, what to do... so I needed to just tinker with it myself.

    End conclusion: yes, this solution is already good. (Updated issue summary, with my understanding of what we are doing.) It just needed bugs fixed:

    Another issue I get now is that markup format is producing an error:

    That's because the controller was still doing $custom_element->setSlotFromNestedElements('rows', VALUE);, while VALUE was changed from $custom_element to $custom_element->toRenderArray(). The setSlotFromNestedElements() is now fixed.

    the pager is now (again) producing errors on pre-view:

    The preexisting code in the row style plugin just put an array of values into $result['pager']. That is not OK / not a valid render array.

    I moved the code into the CustomElementsPage display plugin, because it's only needed there. Now we're not setting $result['pager'] anymore -- error is gone.

  • Status changed to RTBC about 15 hours ago
  • 🇸🇮Slovenia useernamee Ljubljana

    Tested locally, found a small issue when no results are provided and fixed it.

    Moving to RTBC.

  • 🇸🇮Slovenia useernamee Ljubljana

    I fixed some pipeline cspell errors, but we have more issues with phpstan and phpunit to for next major version.

  • 🇸🇮Slovenia useernamee Ljubljana

    I did found another issue with the pager:

    /admin/test-ce?_content_format=json&page=0 or without page query param

        "pager": {
          "totalPages": 2,
          "current": 0
        },
    

    /admin/test-ce?_content_format=json&page=1

        "pager": {
          "totalPages": 3,
          "current": 1
        },
    

    /admin/test-ce?_content_format=json&page=2

        "pager": {
          "totalPages": 4,
          "current": 2
        },
    

    /admin/test-ce?_content_format=json&page=3 and /admin/test-ce?_content_format=json&page=4

        "pager": {
          "totalPages": 4,
          "current": 3
        },
    

    page=5 ...

      "content": {
        "element": "drupal-view",
        "title": "CE page",
        "viewId": "lupus_decoupled_view",
        "displayId": "custom_elements_page",
        "pager": {
          "totalPages": 5,
          "current": 4
        },
        "rows": []
      },
    
  • 🇸🇮Slovenia useernamee Ljubljana

    I guess that this is just the mini pager behavior.

    I tested out the full pager and it looked better except that it starts page count with zero ... which means if total pages are 4, the last page is page 3.

Production build 0.71.5 2024