Hi there,

I've installed emogrifier as instructed, but when I enable it for a text format, the resulting email has had the html, head and body tags stripped from it, including the styles from the head, and there are no embedded styles on any of the tags.

Under status report everything is good, eg all libraries found etc...

Any ideas or suggestions?

Comments

pillarsdotnet’s picture

Assigned: Unassigned » pillarsdotnet
Status: Active » Postponed (maintainer needs more info)

Check your status page. Are you sure the third-party emogrifier library is loading properly?

Check your admin/reports/dblog (watchdog, or error messages) page. Are there any error messages there?

bensey’s picture

Thanks for the reply pillarsdotnet,

Library placed in /libraries/emogrifier/emogrifier.php.

yes, status page says all the right things:
Emogrifier class library: Available: The Emogrifier class library was found.
DOM extension : Enabled

No errors or issues logged in watchdog.

When I add emogrifier to an input format used for sending emails, as mentioned above, the email arrives without head or body tags, instead wrapped in a div.

The css within the style tag inside head is all gone with those tags.

I don't have many classes on tags, the styles are more defining html tags, the body font, headings, paragraph margins etc, keeping it all pretty simple.

On a thorough inspection, the one class I'm using on some paragraph tags have had their class attributes removed from the tags. Other than that the HTML seems the same.

So it seems to be doing something, but not what's expected, baffled..!

aangel’s picture

Same thing happening for me with the 6.x version. Doesn't appear to be working correctly (all libraries loading, etc.).

pillarsdotnet’s picture

I've been offline for some time but will try to troubleshoot this. Perhaps it would help if I made a screencast of setting up HTMLMail, MailMIME, MailSystem, Emogrifier, etc. from a clean install. Then you could watch the screencast and identify what, if anything, we're doing differently.

lmeurs’s picture

I am not sure whether this is the solution, but I'm going to give it a try.

In emogrifier.module (7.x-1.17) at line 101 the script searches for <style>-tags and checks the type and media attributes. If the style block contains @import rules, the URL's are stored in an array. But the rest of the rules in the block seem to be ignored. Is this supposed to happen?

A quick fix might be adding $styles[] = $blocks[3][$block]; at line 109, which results in:

  // Match style blocks, possibly with @imports.
  if (
    preg_match_all(
      '#(<style[^>]*>)\s*(<!--)?\s*(.*?)\s*(-->)?\s*</style>\s*#si',
      $text, $blocks
    )
  ) {
    foreach ($blocks[1] as $block => $tag) {
      if ( preg_match('#\s+type\s*=\s*(["\']?)text/css\1#si', $tag)
        && preg_match('#\s+media\s*=\s*(["\']?)all\1#si', $tag) ) {
        $styles[] = $blocks[3][$block]; // <- this line is added!
        if (
          preg_match_all('#@import\s+url\s*\(\s*(["\']?)([^?' . ']*)(\?.*?)?\1\s*\)\s*;#si', // <- I divided this string in two since it brakes the Drupal Forum PHP tag
            $blocks[3][$block], $imports
          )
        ) {
          $urls = array_merge($urls, $imports[2]);
          $rules = trim(str_replace($imports[0], '', $blocks[3][$block]));
          if (!empty($rules)) {
            $styles[] = $rules;
          }
        }
      }
    }
    $text = str_replace($blocks[0], '', $text);
  }

Maybe the @import rules need to be removed before storing the block in the $styles array, I don't know if they can hurt anyone... :-)

And while I am at it, a simple script like this

echo _emogrifier_process("

<style type='text/css' media='all'>
h3 {
  background: red;
}
</style>

<h3>asd</h3>

");

results in the next HTML:

 
 
<h3 style="background:red;">asd</h3>
 
</html>
  

By removing the PCRE_UNGREEDY modifier (U) and adding trim() at line 160 (or 161 with earlier modification),

$text = trim(preg_replace('#^.*<body>(.*)</body>.*$#si', '\1', $text));

the new HTML looks like:

<h3 style="background:red;">asd</h3>

without <html>-tag and extra newlines.

Anyone knows why this PCRE_UNGREEDY modifier (U) is here?

henrijs.seso’s picture

StatusFileSize
new7.37 KB

Same in 6.x-1.17

@pillarsdotnet why do you mention MailMIME in #4?

pillarsdotnet’s picture

Status: Postponed (maintainer needs more info) » Active

@#5 Posted by lmeurs on March 7, 2012 at 11:53am:

Thanks so much. Because I am lazy, could you please express that change as a patch?

lmeurs’s picture

I'd love to, but do not know how. Still have to take the time learn all about patches...

jmonma’s picture

Are you all using emogrifier with htmlmail? The issue might be with that module: http://drupal.org/node/1439658

plepe’s picture

I found a bug in the Emogrifier module. If no @import is found, the content of

is being discarded. Check the attached patch for details.
pillarsdotnet’s picture

Version: 7.x-1.7 » 7.x-1.9
Component: Miscellaneous » Code
Category: support » bug
Status: Active » Needs review

Thanks.

tchopshop’s picture

I have been attempting to get emogrifier working for an entire day... Nothing works! I have tried both patches above. I am using the latest html mail, mail system, simplenews. I have the emogrifier.php in a directory in libraries/emogrifier. I'm not using echo or mail mime. I have a custom mail theme in which I have the htmlmail--simplenews.tpl.php template, mail.info and mail.css, which is referenced by the .info file. I have an email text format that uses Emogrifier, Pathologic, Transliteration, and the Wysiwyg Filter -- because I need to screen out video in the node body.

I also have a simplenews-newsletter-body.tpl.php in the admin theme "Seven", because that's the only way I could get it to recognize the theme. The htmlmail--simplenews.tpl.php prints a wrapper around echo $body; , and the simplenews template does the rest.

Originally I had everything outputting from the htmlmail--simplenews.tpl.php but after many hours failing to get emogrifier to work, I added the simplenews template in an attempt to more easily extract the field variables, since it's more direct from the Simplenews template than from the htmlmail template. I thought I would extract the variables and theme them inline. But I failed at extracting these Drupal 7 variables... it's just taking too long to figure out each one.

If emogrifier were working, I could simple target the design in the css file. But I can't seem to get anywhere. It's very frustrating.

I'm used to using Mime Mail with Simplenews, which works much more easily in terms of embedding CSS inline. But I have to use the SMTP module this time, and evidently Mime Mail does not work with SMTP.

I need to be able to target the fields inside my node somehow!

Also where should the CSS file be? I have it in my mail theme, my seven theme and in my default theme (just for good measure).

Or do I need to put the styles in the head not in a stylesheet? Or do I need to link to the stylesheet from the head? I assumed you just link to the stylesheet from the .info file in the custom mail theme. I've tried many variations of all these things.

Please help.

nzcodarnoc’s picture

I was having the same problem, here's what I did to resolve it in my instance.

Instead of including the styles in the template, I put them in a separate .css file, and included the file using the following syntax:

<html>
  <head>
    <style type='text/css' media='all'>
      @import url("/<?php print drupal_get_path('theme', 'my_theme_name') ?>/css/email.css");
    </style>  
  </head>
  <body>
    <div class="htmlmail-body">
      <p>Email content.</p>
    </div>
    <?php
    if ($debug)
    {
      // debugging could go here
    }
    ?>
  </body>
</html>
tchopshop’s picture

Thank you, that finally gave me a break through. Although I couldn't get the @import working... I simply created a hardcoded stylesheet link.

pasqualle’s picture

Status: Needs review » Needs work

#10 works, just the whitespace issues should be fixed
- replace tabs with 2 spaces
- add space around the '=' character

then the patch should look like this

+    else {
+      $styles[] = $blocks[3][$block];
+    }
alexh58’s picture

Status: Needs work » Needs review
StatusFileSize
new1.32 KB

I'm surprised this isn't resolved yet—Spent a good chunk of time pulling my hair out over check_plain not working with this filter.

Anyways, I've encompassed both of lmeurs' edits in a patch attached here. The one in http://drupal.org/node/1336106#comment-6048704 doesn't resolve the PCRE_UNGREEDY modifier needing removal (otherwise you still end up with that lonely closing html tag).

Please review! I don't like walking around with a patched module ;-)

alexh58’s picture

And for my purposes, here is a backport for D6.

-Alex

raekjaer’s picture

I am using commerce invoice receipt, which uses emogrifier to prepare invoice for email. The problem with missing HTML, HEAD and BODY also appears here.

The attached patch clones the original string and inserts emogrified text into it before returning. But only if there is a BODY tag in the original string - otherwise we bypass the insertion.

This approach is only tested in my limited setup - and it only addresses half of the original issue.

Casper

geek-merlin’s picture

Version: 7.x-1.9 » 7.x-1.x-dev
StatusFileSize
new3.71 KB

WOW. Puzzled together the different patches.
While wrapping my head around these i also added some comments to make things reviewable.

Some remarks:
* Regexp parsing is bullshit, this should be refactored to use a HTML parser.
* We should really have split this issue.
* We should #1824562: Prepare some tests to be added

Now please everyone test this so we can get this in.

jonne.freebase’s picture

StatusFileSize
new3.16 KB

Patch #19 worked for me, but generated a few warnings in my case because I didn't use media queries in my template (i assume). I basically added the following to axel.rutz' patch:

if($has_media){
geek-merlin’s picture

Status: Needs review » Reviewed & tested by the community

exactly what i had to add and now works without warnings.
so setting to reviewed.

roball’s picture

Priority: Normal » Critical
Status: Reviewed & tested by the community » Needs work

Can't believe this critical bug is still in the current production releases 7.x-1.18 and 6.x-1.18 and no fix has yet been committed. I have also hit this bug with 6.x-1.18, having the following simple HTML source:

<html>
<head>
<style type="text/css">
<!--
div, p {
   font-family: Arial, sans-serif;
   font-size: 11px;
   line-height: 16px;
}
-->
</style>
</head>
<body>

<div class="htmlmail-body">
...some content...
</div>

</body>
</html>

The Emogrifier module will break this complete and styled HTML page to the following incomplete and unstyled HTML:

<div>

<div>
...some content...
</div>


</div>

The workaround is to modify the style tag to contain:

<html>
<head>
<style type="text/css" media="all">
<!--
@import url("");
div, p {
   font-family: Arial, sans-serif;
   font-size: 11px;
   line-height: 16px;
}
-->
</style>
</head>
<body>

<div class="htmlmail-body">
...some content...
</div>

</body>
</html>

The media="all" and @import url(""); must be added. This results in the styled, but still uncomplete HTML page:

<div style="font-family: Arial, sans-serif; font-size:  
11px; line-height: 16px;">

<div style="font-family: Arial, sans-serif; font-size:  
11px; line-height: 16px;">
...some content...
</div>


</div>

The latest patch in #20 for D7 is not a valid patch; the latest D6 patch from #17 does not solve the problem. This problem needs urgent attention by the module author (his last contribution was 7 months ago, just saying "Thanks", but not taking any action).

roball’s picture

Title: Emogrifier strips tags, and is not embedding styles... » Emogrifier removes styles instead of embedding them!

The solution is to apply the latest patch posted at #1842946: Modify HTML code only by the Emogrifier library - forget all patch attempts posted here! There is no need to additionally process the HTML code by this module at all - this is just useless, complicated and error-prone.

After applying that patch (for D6), the resulting HTML page is complete, valid and inline-styled properly, looking like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"  
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head></head>
<body>

<div class="htmlmail-body">
<p style="font-family: Arial, sans-serif;
   font-size: 11px;
   line-height: 16px;">...some sub content...</p>
...remaining content...
</div>


</body>
</html>
</!doctype>

:-)

roball’s picture

Status: Needs work » Needs review

Changing the status of this issue back to "needs review" since it has been solved in the other issue (#1842946: Modify HTML code only by the Emogrifier library). Once that other issue has been confirmed to be reviewed & tested, this issue can be closed.

roball’s picture

Issue summary: View changes

fixing tags in body, as they were stripped...

colepacak’s picture

Issue summary: View changes

I created a separate module using a stripped-down version of the Emogrifier module. It seemed like all the regex was the culprit.

Created a new text format using this new filter and selected the text format within the HTML Mail module post-filtering settings.

No changes made on htmlmail.tpl.php.

<?php

/**
 * Implements hook_filter_info().
 */
function my_module_filter_info() {
  return array(
    'filter_my_module_emogrifier' => array(
      'title' => t('My Module Emogrifier'),
      'description' => t('Converts stylesheet rules to inline style attributes - fixes the original Emogrifier.'),
      'process callback' => 'my_module_emogrifier_process',
    ),
  );
}

/**
 * Implements hook_filter_FILTER_process().
 * @see my_module_filter_info()
 */
function my_module_emogrifier_process($text, $filter, $format, $langcode, $cache, $cache_id) {
  if (empty($text)) {
    return '';
  }
  // include emogrifier library, pay attention to upper or lowercase of install file
  include_once libraries_get_path('emogrifier') . "/emogrifier.php";
  // Load the html text and style rules.
  $emogrifier = new Emogrifier();
  $emogrifier->setHtml($text);
  // includes pages.css stylesheet from theme directory
  $styles = file_get_contents(path_to_theme() . "/css/pages.css");
  $emogrifier->setCss($styles);
  // Apply the rules to create inline style attributes.
  $text = @$emogrifier->emogrify();
  return $text;
}
jacob.embree’s picture

Version: 7.x-1.x-dev » 7.x-2.x-dev
Assigned: pillarsdotnet » Unassigned
Status: Needs review » Fixed
Related issues: +#1842946: Modify HTML code only by the Emogrifier library

The fix for this is to switch to version 2.

geek-merlin’s picture

Status: Fixed » Active

Does this mean 1.x is discontinued? in this case it must be unpublished from the module page.

socialnicheguru’s picture

Status: Active » Needs review

The last submitted patch, 16: emogrifier-strips_tags-1336106-15.patch, failed testing.

The last submitted patch, 17: emogrifier-strips_tags_D6_backport-1336106-15.patch, failed testing.

The last submitted patch, 18: emogrifier-emogrifier_strips_tags-1336106-18.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 20: emogrifier.patch, failed testing.

roball’s picture

Status: Needs work » Closed (duplicate)

The bug has been fixed in the issue #1842946: Modify HTML code only by the Emogrifier library, thus I am closing this one as a duplicate.