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.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

useernamee created an issue. See original summary.

fago’s picture

Status: Active » Postponed (maintainer needs more info)

Which version of core / lupus-decoupeld are affected?

alexpott’s picture

Status: Postponed (maintainer needs more info) » Needs work

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.

alexpott’s picture

This has only been causing issues on Drupal 10.3 due to #3427177: Replace calls to ::expectError*() from Drupal\Tests\Core\Render\ElementTest 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.

useernamee’s picture

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.

useernamee’s picture

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.

fago’s picture

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.

alexpott’s picture

@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.
alexpott’s picture

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.

useernamee’s picture

Assigned: Unassigned » useernamee

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 = []);

useernamee’s picture

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?

fago’s picture

> 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.

useernamee’s picture

@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.

When I'm showing Fields instead of content the preview is broken again due to TypeError: htmlspecialchars(): Argument #1 ($string) must be of type string, array given in htmlspecialchars() (line 437 of /app/web/core/lib/Drupal/Component/Utility/Html.php).
^^ Has own issue #3461874: Custom elements Views: Per-field formatters are not supported/working

To sum up: @alexpott would you consider upgrading custom elements to version 3.x and tell if you're still experiencing the php errors with the patch from this ticket applied. I can't reproduce it anymore (although for me it was only ever coming up on the view preview).

@fago, could you review PR89.

useernamee’s picture

Assigned: useernamee » fago
Status: Needs work » Needs review
roderik’s picture

@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.

alexpott’s picture

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 where 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.

fago’s picture

Status: Needs review » Needs work

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.

useernamee’s picture

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>
...
</template>
</drupal-view>
</div>

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

I've made view work (in the be) but it comes with a quirk: \Drupal\custom_elements\CustomElementNormalizer::normalizeSlots did not know how to normalize it, so I added another condition to the method:

diff --git a/src/CustomElementNormalizer.php b/src/CustomElementNormalizer.php
index e746289..af65e1c 100644
--- a/src/CustomElementNormalizer.php
+++ b/src/CustomElementNormalizer.php
@@ -3,6 +3,7 @@
 namespace Drupal\custom_elements;
 
 use Drupal\Component\Render\MarkupInterface;
+use Drupal\Core\Logger\LoggerChannelTrait;
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\Template\Attribute;
 use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
@@ -12,6 +13,8 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
  */
 class CustomElementNormalizer implements NormalizerInterface {
 
+  use LoggerChannelTrait;
+
   /**
    * {@inheritdoc}
    */
@@ -125,6 +128,14 @@ class CustomElementNormalizer implements NormalizerInterface {
             $slot_data[$index] = array_merge($slot_data[$index], $slot['attributes']->toArray());
           }
         }
+        elseif (is_array($slot['content']) && isset($slot['content']['#theme']) && $slot['content']['#theme'] == 'custom_element') {
+          if (!empty($slot['content']['#custom_element']) && $slot['content']['#custom_element'] instanceof CustomElement) {
+            $slot_data[$index] = $this->normalizeCustomElement($slot['content']['#custom_element'], $cache_metadata);
+          }
+        }
+        else {
+          $this->getLogger('custom_elements')->warning('Unrecognized slot @key.', ['@key' => $slot_key]);
+        }
 
         // Remove possible doubled slot attributes.
         unset($slot_data[$index]['slot']);

I'm not sure this is a general direction we'd like go into.

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.

@fago @alexpott - I kind of depend on your feedback here.

fago’s picture

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 #3338911: Frontend-rendered layout-builder previews, 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.

useernamee’s picture

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

Because of #9.

I'll try out the proposal.

useernamee’s picture

@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)

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.

fago’s picture

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.

fago’s picture

Assigned: fago » Unassigned
roderik’s picture

Issue summary: View changes
Status: Needs work » Needs review

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.

'custom_elements' format responses (i.e. anything using the "custom_elements_page" display plugin) still produces the same output.

useernamee’s picture

Status: Needs review » Reviewed & tested by the community

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

Moving to RTBC.

useernamee’s picture

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

useernamee’s picture

I did found another issue with the pager: (Is this normal mini pager behavior?)

/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": []
  },
useernamee’s picture

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.

fago’s picture

Status: Reviewed & tested by the community » Needs work

* The change looks good now and generally ready. However, the MR needs a re-roll and a resulting glitch to be resolved/updated. (see my comment)
* I suppose this pager issues are not new? Let's open dedicated bug reports for each of them please.
* It seems there is no test coverage for that feature at all, we really should add some. Let's add a follow-up for it.

useernamee’s picture

Status: Needs work » Fixed

- re-roll done, thus merging.
- creating a followup for tests: #3475738: Add tests for Lupus Decoupled views
- followup for mini pager: #3475740: Investigate view's mini pager inconsistency

useernamee’s picture

Assigned: Unassigned » fago
Status: Fixed » Needs review

Tried to merge MR89 but wasn't able to.

  • roderik committed cf9e36cd on 1.x
    Issue #3469398 by useernamee, roderik, alexpott, fago: When editing a...
roderik’s picture

Assigned: fago » Unassigned
Status: Needs review » Fixed

Thanks!

I couldn't merge either. (Happened to me more often.) And I seem to lack some git knowledge (about --no-ff and --squash not working together) so I can't really explain.

But I could reproduce a squashed commit locally and compare that it was equal to the branch, so all good.

roderik changed the visibility of the branch 3469398-remove-controller to hidden.

roderik changed the visibility of the branch 3469398-when-editing-a to active.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.