– Cookforweb Apr 04 '19 at 08:51

3 Answers3

3

@Sephsekla comment gave me the idea below, about how to add a tag in email template overriding the default stripping.

Not a nice technique but it works!

The first part of the solution is to include the part of the CSS code inside another tag (even if this tag is not valid) than 'style' to avoid stripping in the first place, like the example below:

        <style-inline>
            @font-face {
                font-family: 'Montserrat';
                font-style: normal;
                font-weight: 400;
                src: url(http://fontdomain-example.com/Montserrat-Regular.woff) format('woff');
            }
        </style-inline>

If we leave it as is then our code will be rendering in our email code.

So the next thing is to add a hook to 'woocommerce_mail_content' filter (with low priority in order to be the last filter to be run) replacing the 'style-inline' with 'style' string.

add_filter( 'woocommerce_mail_content', 'woocommerce_mail_content_callback', 9999 );
public function woocommerce_mail_content_callback($mail_content){
            $mail_content = str_replace([
                '<style-inline>',
                '</style-inline>'
            ], [
                '<style>',
                '</style>'
            ], $mail_content);
            return $mail_content;
        }

The above technique worked for me allowing me add font-face successfully.

Cookforweb
  • 85
  • 11
0

I've done a bit of research on this and it looks like there is indeed a function that strips out style tags https://docs.woocommerce.com/wc-apidocs/source-class-WC_Email.html#495

Rather than trying to add a whole style block to the email you should be able to use the woocommerce_email_styles hook instead to add rules to the default style block.

I found a writeup of the process here, but the gist of it is something like this:


add_filter( 'woocommerce_email_styles', 'add_custom_styles_to_email' );

function add_custom_styles_to_email( $css ) {
    $css .= '@font-face {
                  font-family: "Montserrat";
                  font-style: normal;
                  font-weight: 300;
                  src: local("Montserrat Light"), local("Montserrat-Light"), url(https://fonts.gstatic.com/s/montserrat/v13/JTURjIg1_i6t8kCHKm45_cJD3gTD_u50.woff2) format("woff2");
                  unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
                };'
    return $css;
}

As a side note I've changed the single quotes into double quotes in the style string as otherwise they're not being escaped. That may cause some issues, as php might think you're trying to concatenate the string with some variables.

Sephsekla
  • 441
  • 2
  • 9
  • Hi Sephsekla. 'woocommerce_email_styles' filter converts the css to inline styling. For example the body{ background-color: #333333 } becoming ' . That's why your approach cannot work with @font-face which must be included in 'style' tag – Cookforweb Apr 03 '19 at 10:39
  • 1
    You're right, my mistake. I don't know if it's going to be possible to remove the function altogether, as it's called in the `send` function https://docs.woocommerce.com/wc-apidocs/source-class-WC_Email.html#553 rather than through a filter. Maybe you could try adding the styles to the message body by prepending/ appending them with the `woocommerce_mail_content` filter, which runs after it's had the styles inlined. `$message = apply_filters( 'woocommerce_mail_content', $this->style_inline( $message ) ); $return = wp_mail( $to, $subject, $message, $headers, $attachments );` – Sephsekla Apr 03 '19 at 10:47
  • Your answer gave me an idea how to fix this. It is not the right technique but it's the only way to do so far. I'm posting it on a separate answer. – Cookforweb Apr 04 '19 at 12:13
0

This is caused by Emogrifier, which tries to convert all <style> tags(and others) into inline styles. You can prevent this by changing the settings like so:

add_action('woocommerce_emogrifier', function($emogrifier){
    $emogrifier->disableStyleBlocksParsing();
});
passatgt
  • 4,234
  • 4
  • 40
  • 54
  • Dosn't work anymore, see this breaking change - https://developer.woocommerce.com/2022/04/04/breaking-change-notice-woocommerce_emogrifier-hook/ – user25794 Jun 17 '23 at 01:35