After clearing caches, the aggregated CSS is not loading properly, which disrupts the layout of the first PDF.

Created on 18 October 2023, about 1 year ago
Updated 13 September 2024, 2 months ago

Problem/Motivation

The PDF's layout is not loading correctly when submitting a webform, after having cleared the cache.

As a result, when a PDF attachment is sent out via email, it has a wrong layout (see screenshots).

After viewing the PDF once, the sites/files/css folder appears, and then when I refresh the PDF, it load correctly (see screenshot).

I suspect that something is wrong with the loading of the aggregated CSS file in the {{ entity_print_css }} variable.

I managed to resolve the issue by copying the styles contained in the aggregated css and putting in them in $variables['entity_print_css'], inside a hook_preprocess_entity_print():

/**
 * Implements hook_preprocess_entity_print().
 */
function custom_webform_preprocess_entity_print(array &$variables) {
  // For some reason, the entity_print_css variable does not load the
  // aggregated file correctly. Here, we are hard coding the
  // entity_print_css variable by putting the styles contained in the
  // aggregated css.
  $html = '<style>
    body{font-family:"DejaVu Sans",Helvetica,Arial,sans-serif;}.page{padding:20px;}.page img{max-width:100%;height:auto;}.page td img{max-width:none;}
    details{border:1px solid #ccc;margin-top:1em;margin-bottom:1em;}.details-wrapper{padding:0 1em;}summary{font-size:1.2em;font-weight:bold;padding:.5em .5em 0 .5em;}.form-item{margin-top:1em;margin-bottom:1em;}label{display:block;font-weight:bold;}.webform-submission-table{width:100%;border-collapse:collapse;border-spacing:0;}.webform-submission-table th{width:33%;min-width:100px;}.webform-submission-table th,.webform-submission-table td{text-align:left;padding:10px 12px;}.webform-submission-table tr{border-top:1px solid #ccc;border-bottom:1px solid #ccc;padding:0.1em 0.6em;}
  </style>';
  $variables['entity_print_css'] = Markup::create($html);
}

Steps to reproduce

1. Clear the cache
2. Submit a webform
3. Go to https://yoursite.com/nl/admin/structure/webform/manage/your_webform/resu...
4. Click on the pdf link of your latest submission

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Needs work

Version

2.13

Component

Code

Created by

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

Comments & Activities

  • Issue created by @gpapadas
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    This is likely due to the changes in 10.1 around dynamic aggregation

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    I ran into the same issue (and came to the same conclusion as larowlan). Here is the change record: https://www.drupal.org/node/3301716 β†’

    Be aware this this is not limited to webforms, but to every generated pdf (I am using DOMpdf).
    It looks like entity_print (or DOMpdf) does not wait long enough for the dynamic aggregates to be created. Bumping to major as this might affect a lot of sites.

  • πŸ‡§πŸ‡ͺBelgium stijnd Belgium

    Had the same issue. Each time cache is cleared the first generated PDF has no style.
    The hook_preprocess_entity_print() suggestion of @gpapadas did the trick.

    Here's my fix. It reads the CSS file and adds its content as a style-tag

    /**
     * Implements hook_preprocess_HOOK().
     */
    function custom_module_preprocess_entity_print(&$variables) {
      $css = file_get_contents(\Drupal::service('extension.path.resolver')->getPath('module', 'custom_module') . '/css/entity-print-style.css');
      $variables['#attached']['html_head'][] = [
        [
          '#tag' => 'style',
          '#value' => $css,
        ],
        'custom_module',
      ];
    }
    
    
  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    I have temporarily disabled the CSS optimization by overriding line 132 of entity_print/src/PrintBuilder.php:

    $print_engine->addPage($renderer->generateHtml($entities, $render, $use_default_css, FALSE));

    This last property determines if the CSS should be optimized. This value moves through the Renderer to the AssetRenderer to Drupal Core's AssetResolver. From there, the asset.css.collection_optimizer service is called to optimize all CSS files. This old service now uses the new CssCollectionOptimizerLazy class.
    CssCollectionOptimizerLazy cleary states that it does not write the optimized files to disk, but assumes that they wil be created once the URL is requested.

    For all other people watching this issue, are you using DOMpdf? Could it be that DOMpdf simply does not wait long enough for the optimized content to be created or are you using other rendering engines?

    Attaching a hotfix with the above change, so that PDFs shoud work again.

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    Upon further investigation I have discovered that DOMpdf does not load the CSS resource because the mimetype of the realtime generated CSS is text/html instead of the expected text/css.

    Drupal's CssAssetController does set a content type of text/css. But for the first request this gets cleared somewhere.

    Still not sure if this is an issue with Drupal, Symfony or dompdf though... It does not appear to originate from this module though.

  • πŸ‡«πŸ‡·France flocondetoile Lyon

    Same issue here. Since I upgrade Drupal Core to 10.1.6 (from 9.5.11) CSS are not loaded anymore by entity print when printing node or commerce_order to a PDF (with DomPDF). Hotfix in #5 doesn't resolved the issue.

  • πŸ‡«πŸ‡·France flocondetoile Lyon

    Also PDF are well rendered on local instance and on a dev instance located on a simple server.
    PDFs are broken for preprod and production sites which are behind a reverse proxy.

  • πŸ‡«πŸ‡·France flocondetoile Lyon

    From #6

    Still not sure if this is an issue with Drupal, Symfony or dompdf though... It does not appear to originate from this module.

    Or may be the stack on the server (apache / nginx / haproxy, etc.)

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    @flocondetoile, I am not sure if you are having the same issue. This issue is specifically about the PDF layout being broken only once after clearing the cache.

    From your comment #7 it looks like your PDFs are always broken. Did you follow the instructions in the changelog https://www.drupal.org/node/2888767 β†’ ?

  • πŸ‡«πŸ‡·France flocondetoile Lyon

    Yes you're right. Mine are always broken. I investigate how the reverse proxy is configured (they are managed by IT, but theorically they only dispatch requests whithout managing dynamic/static assets), and I have an HAProxy in front of the apache web server.

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    I have found the (my) root cause. The Redirect module's "Enforce clean and canonical URLs." option does not (yet) play nice with the optimized CSS files and adds a redirect. This redirect has the text/html Content-Type with causes DOMpdf to break. There is already a patch in that module's queue: πŸ› Setting 'Enforce clean and canonical URLs.' breaks CSS aggregation on multilingual Drupal 10.1.x with browser caching enabled RTBC .

    I think this can be Closed (works as designed)?

  • Status changed to RTBC 11 months ago
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 8.0 & MySQL 5.7
    last update 11 months ago
    Patch Failed to Apply
  • πŸ‡¦πŸ‡ΊAustralia VladimirAus Brisbane, Australia

    I can confirm that #5 hotfix works for Drupal 10.1 and and Entity Print 2.13.
    Event after fixing redirects the css was still not attaching until patch was attached.

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    I am not sure about the RTBC. It was not my intention to have the hotfix committed. Just to have something while we are looking for the cause of the problem.

    But I must say that after I discovered the issue from #12 I can do without the hotfix.

  • πŸ‡¦πŸ‡ΊAustralia VladimirAus Brisbane, Australia

    @Neograph734 that's what I thought. I never had issues locally and on stage.
    However, production (which I assume is a bit slower) doesn't work without the hotfix.

  • Status changed to Needs work 11 months ago
  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    I don't think disabling aggregation is the best way forward - is there anything we can do to wait for aggregation to complete here?

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    From what I have been able to debug, this has nothing to do with a race condition or waiting. It was DOMpdf simply skipping the provided css file because it's content type was wrong (because of a redirect).

    It could be that others are facing another issue with similar effect, but I would encourage them to disable the mentioned option in the redirect module first and see if that fixes the pdfs.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Can we use the http_client to request those URLs in advance?

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    Possibly, but that would cause overhead for all other request? Note that this only occurs for the first PDF after clearing the cache.
    Or you should keep track of when the cache was last cleared and when each URL was prefetched. I don't think you want to go that route...

    I honestly don't think there is anything to fix in this module.

  • πŸ‡¦πŸ‡ΊAustralia larowlan πŸ‡¦πŸ‡ΊπŸ.au GMT+10

    Should we be fixing the mime-type in core then?

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    Please have a look at the the related issue of the Redirect module ( πŸ› Setting 'Enforce clean and canonical URLs.' breaks CSS aggregation on multilingual Drupal 10.1.x with browser caching enabled RTBC ). It tampers with the newly introduced routes for lazy built css and js files causing issues.

    You can't replicate the issue with core and entity print. Only when you add redirect and enable the "enforce clean urls" option you will start to see the issue.

  • Bingo! Thanks for the hotfix in #5 which brought back the CSS coded tables for my Commerce Invoice invoices from modules/contrib/commerce_invoice/css/commerce_invoice.entityprint.css. For lack of coding knowledge I cannot help fixing the bug but maybe my setup details can help:

    From the saved invoice PDFs I can clearly state that our low frequency web shop lost its invoice CSS some time in fall or winter 2023/2024. The redirect module is active, but I seemed not to have had a problem with it, and neither redirect nor entity_print seem to have had an upgrade in the time window mentioned. Perhaps something broke when I upgraded from D10.1 to 10.2 which may have taken place back then.

    The invoices were legible though, I didn't notice the difference, the customers didn't complain, so I was unaware of the loss until two days ago. Currently I am on D10.3.5, with up to date entity_print 8.x-2.15 and redirect 8.x-1.10. I'll be happy to help pinpointing stuff in my setup if needed. What I can also say is that timing in relation to having cleared caches doesn't make any difference here.

  • πŸ‡³πŸ‡±Netherlands neograph734 Netherlands

    Now that Redirect 8.x-1.10 is out, the issue in the redirect module should be fixed and there should no longer be a need for this hotfix.

    At least in my environment everything is working without additional patches.

Production build 0.71.5 2024