Render re-written title fields

Created on 22 October 2024, 2 months ago

I'm not 100% sure this is a child issue for #3480941 as I don't fully understand it.

Problem/Motivation

When you edit the title field and re-write its content (for example, to display a location or an event status next to the title) the calendar always shows the original title, not the re-written one.

Steps to reproduce

  1. Create or modify a calendar.
  2. Edit the view title field and change it to anything.
  3. Check if the title changed on the calendar page.

Data model changes

πŸ› Bug report
Status

Active

Version

3.0

Component

Code

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @mpractic
  • πŸ‡ΊπŸ‡ΈUnited States erutan

    I'll second this, and also add that being able to use non-string fields would also be good.

    Tested on beta6.

    If I change the title field to an int field I get an ajax error. Changing it back to a string and saving stops it from occuring. This is a brand new mostly empty view created just to test this out, so there's nothing overly fancy going on.

    fc/preview/page_1?_wrapper_format=drupal_ajax:1 
            
            
           Failed to load resource: the server responded with a status of 500 (Internal Server Error)
    ajax.js?v=10.3.6:1219 Uncaught Drupal.AjaxErrormessage: "\nAn AJAX HTTP error occurred.\nHTTP Result Code: 500\nDebugging information follows.\nPath: /admin/structure/views/view/fc/preview/page_1\nStatusText: Internal Server Error\nResponseText: The website encountered an unexpected error. Try again later.TypeError: htmlspecialchars_decode(): Argument #1 ($string) must be of type string, Drupal\\Core\\Field\\Plugin\\Field\\FieldType\\IntegerItem given in htmlspecialchars_decode() (line 545 of modules/contrib/fullcalendar/src/Plugin/views/style/FullCalendar.php)."name: "AjaxError"stack: "Error\n    at http://FOOBAR.lndo.site/core/misc/ajax.js?v=10.3.6:196:32\n    at http://FOOBAR.lndo.site/core/misc/ajax.js?v=10.3.6:1921:3"[[Prototype]]: Error
        at http://FOOBAR.lndo.site/core/misc/ajax.js?v=10.3.6:196:32
        at http://FOOBAR.lndo.site/core/misc/ajax.js?v=10.3.6:1921:3

    I think it's hardcoded to look for a string, changing it to a date gives me a similar error and if I directly visit the rendered view the following:

    The website encountered an unexpected error. Try again later.
    
    TypeError: htmlspecialchars_decode(): Argument #1 ($string) must be of type string, Drupal\datetime\Plugin\Field\FieldType\DateTimeItem given in htmlspecialchars_decode() (line 545 of modules/contrib/fullcalendar/src/Plugin/views/style/FullCalendar.php).

    Changing this to another string field works (and it will fall back to name if empty, which is good and bad I suppose) but rewrites are still being ignored. Being able to rewrite a field seems like it'd be a fairly common use case.

  • πŸ‡¨πŸ‡¦Canada mandclu

    I appreciate the follow-up issue here. It is correct that the change in πŸ› Render re-written title fields Active allows for a different field to be specified as the value to use for the title that will be passed into the FullCalendar library. It is entirely possible that any field configuration (including rewriting) is not being respected.

    My hunch is that making sure the field is rendered should fix any issues with other field types, but it's worth testing. Also,we will need to strip out any tags from the result, since the library only accepts strings.

    It seems as though I wasn't really thinking wide enough in terms of what was needed in the original issue. Could someone take a stab about updating the issue summary to include accepting non-text fields and anything else we should anticipate / accommodate?

  • πŸ‡ΊπŸ‡ΈUnited States erutan

    Taking a stab at expanding the title and issue summary.

  • πŸ‡ΊπŸ‡ΈUnited States erutan
  • Merge request !44Render the specified title field β†’ (Merged) created by mandclu
  • πŸ‡¨πŸ‡¦Canada mandclu

    The code in the MR works (for me) to honour field rewrites in the view field config. It seems to display as expected, but throws an error in the view edit preview. I will continue to poke away at this, but if anyone wants to test that these changes work for various edge cases, feedback would be appropriate. I will note that the AFAIK the FullCalendar library will only accept text for the title, so don't expect anything more than that to make its way through to the calendar display.

  • πŸ‡¨πŸ‡¦Canada mandclu

    Oh and for the record, here is the error being thrown in the view edit preview:

    LogicException: Render context is empty, because render() was called outside of a renderRoot() or renderInIsolation() call. Use renderInIsolation()/renderRoot() or #lazy_builder/#pre_render instead. in Drupal\Core\Render\Renderer->doRender() (line 258 of /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php).
    
    #0 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(203): Drupal\Core\Render\Renderer->doRender()
    #1 /var/www/html/web/core/modules/views/src/Plugin/views/field/EntityField.php(970): Drupal\Core\Render\Renderer->render()
    #2 /var/www/html/web/core/modules/views/src/Plugin/views/field/FieldPluginBase.php(1214): Drupal\views\Plugin\views\field\EntityField->render_item()
    #3 /var/www/html/web/modules/custom/fullcalendar/src/Plugin/views/style/FullCalendar.php(381): Drupal\views\Plugin\views\field\FieldPluginBase->advancedRender()
    #4 /var/www/html/web/modules/custom/fullcalendar/src/Plugin/views/style/FullCalendar.php(310): Drupal\fullcalendar\Plugin\views\style\FullCalendar->prepareEvents()
    #5 /var/www/html/web/modules/custom/fullcalendar/src/Plugin/views/style/FullCalendar.php(257): Drupal\fullcalendar\Plugin\views\style\FullCalendar->prepareSettings()
    #6 /var/www/html/web/modules/custom/fullcalendar/src/Plugin/views/style/FullCalendar.php(245): Drupal\fullcalendar\Plugin\views\style\FullCalendar->prepareAttached()
    #7 /var/www/html/web/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php(2177): Drupal\fullcalendar\Plugin\views\style\FullCalendar->render()
    #8 /var/www/html/web/core/modules/views/src/ViewExecutable.php(1592): Drupal\views\Plugin\views\display\DisplayPluginBase->render()
    #9 /var/www/html/web/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php(2467): Drupal\views\ViewExecutable->render()
    #10 /var/www/html/web/core/modules/views/src/ViewExecutable.php(1721): Drupal\views\Plugin\views\display\DisplayPluginBase->preview()
    #11 /var/www/html/web/core/modules/views_ui/src/ViewUI.php(617): Drupal\views\ViewExecutable->preview()
    #12 /var/www/html/web/core/modules/views_ui/src/ViewPreviewForm.php(63): Drupal\views_ui\ViewUI->renderPreview()
    #13 /var/www/html/web/core/lib/Drupal/Core/Entity/EntityForm.php(107): Drupal\views_ui\ViewPreviewForm->form()
    #14 /var/www/html/web/core/modules/views_ui/src/ViewFormBase.php(42): Drupal\Core\Entity\EntityForm->buildForm()
    #15 [internal function]: Drupal\views_ui\ViewFormBase->buildForm()
    #16 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(528): call_user_func_array()
    #17 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(370): Drupal\Core\Form\FormBuilder->retrieveForm()
    #18 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(625): Drupal\Core\Form\FormBuilder->rebuildForm()
    #19 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(321): Drupal\Core\Form\FormBuilder->processForm()
    #20 /var/www/html/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm()
    #21 /var/www/html/web/core/modules/layout_builder/src/Controller/LayoutBuilderHtmlEntityFormController.php(39): Drupal\Core\Controller\FormController->getContentResult()
    #22 [internal function]: Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController->getContentResult()
    #23 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
    #24 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(593): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
    #25 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext()
    #26 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
    #27 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(183): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
    #28 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
    #29 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle()
    #30 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
    #31 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
    #32 /var/www/html/web/core/modules/big_pipe/src/StackMiddleware/ContentLength.php(32): Drupal\Core\StackMiddleware\ContentLength->handle()
    #33 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\big_pipe\StackMiddleware\ContentLength->handle()
    #34 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
    #35 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
    #36 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
    #37 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
    #38 /var/www/html/web/modules/custom/whoops/src/StackMiddleware/WhoopsMiddleware.php(49): Drupal\Core\StackMiddleware\AjaxPageState->handle()
    #39 /var/www/html/web/modules/custom/cloudflare/src/CloudFlareMiddleware.php(124): Drupal\whoops\StackMiddleware\WhoopsMiddleware->handle()
    #40 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\cloudflare\CloudFlareMiddleware->handle()
    #41 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(709): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
    #42 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle()
    #43 {main}

    If anyone wants to take a stab at resolving this, I would be grateful.

  • First commit to issue fork.
  • πŸ‡©πŸ‡ͺGermany jurgenhaas Gottmadingen

    I've cleaned-up the MR with these steps:

    • The methods setTitle and getTitle can not be used as they don't exist in EntityInterface. Instead, let's forward the optionally rewritten title as an argument.
    • Remove the unused $fields variable.
    • Make sure we have a fieldable entity before calling hasField
    • Replace method_exists as this would fail if title is either a string or NULL. This part is only required if the advanced render returns Markup, so let's test for that.

    This is still working OK, except for the preview. To my surprise, the preview gets rendered without having a render context at that point. It does have a render context, though, when rendered on the page then.

    There have been issues about this before, the closest is #2564475: LogicException: Render context is empty in views ui preview β†’ but it got closed as not reproducible. @mandclu as we now have a reproducible case, should we try and report this upstream and see if core can either fix this or tell us what we need to change?

  • πŸ‡¦πŸ‡ΉAustria roromedia Linz

    I now looked into the issue with the rendering of the title field which is set to "Rewrite Results". In the current implementation it doesn't work as expected as the advancedRender() method doesn't respect this option.

    You can change the following in line 378 in src/Plugin/fullcalendar/type/FullCalendar.php:
    $title = $this->view->field[$title_field]->advancedRender($row);

    to:

    $row_index = $this->view->row_index;
    $title = $this->view->style_plugin->getField($row_index, $title_field);
    

    With this change the above mentioned error goes away and the rewritten results are populated as expected.

  • πŸ‡¨πŸ‡¦Canada mandclu

    @roromedia Thanks! That is indeed exactly what was needed.

  • Pipeline finished with Skipped
    about 1 month ago
    #341351
    • mandclu β†’ committed b0395412 on 3.0.x
      Issue #3482579 by mandclu, jurgenhaas, roromedia: Calendar entry title...
  • πŸ‡¨πŸ‡¦Canada mandclu

    Merged in, and will roll a new release with this shortly.

    • mandclu β†’ committed b0395412 on 3.1.x
      Issue #3482579 by mandclu, jurgenhaas, roromedia: Calendar entry title...
  • I've tried the new release and it's a great improvement. Great job! Thanks a lot.

    Do you think it will be possible at some point to include html tags on event titles?

    I used to rewrite the title for something like:

    <b>{{ title }}</b><br>
    {{ field_status }}

    And the status with something like:
    <span class="badge badge-pill badge-status badge-{{ field_status__target_id }}">{{ field_status}}</span>

    The result is something like this:

    Instead of this:

    If it helps I can open another issue.

  • I've tried the new release and it's a great improvement. Great job! Thanks a lot.

    Do you think it will be possible at some point to include html tags on event titles?

    I used to rewrite the title for something like:

    <b>{{ title }}</b><br>
    {{ field_status }}

    And the status with something like:
    <span class="badge badge-pill badge-status badge-{{ field_status__target_id }}">{{ field_status}}</span>

    The result is something like this:

    Instead of this:

    If it helps I can open another issue.

  • I've tried the new release and it's a great improvement. Great job! Thanks a lot.

    Do you think it will be possible at some point to include html tags on event titles?

    I used to rewrite the title for something like:

    <b>{{ title }}</b><br>
    {{ field_status }}

    And the status with something like:
    <span class="badge badge-pill badge-status badge-{{ field_status__target_id }}">{{ field_status}}</span>

    The result is something like this:

    Instead of this:

    If it helps I can open another issue.

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

Production build 0.71.5 2024