Code Monkey home page Code Monkey logo

Comments (22)

martinnormark avatar martinnormark commented on June 6, 2024 2

Downloading external CSS files (specified as link href="..." elements are now possible, thanks to #67 merged in #109 and pushed to Nu Get as v1.5.4 yesterday.

from premailer.net.

martinnormark avatar martinnormark commented on June 6, 2024

Hi @jamesmanning

Only potential problem I see, is relative URLs and if it can't find the css file that the link refers to. But that should be possible to deal with, and just ignore the link and continue to the next one.

Do you have an example of usage?

from premailer.net.

jamesmanning avatar jamesmanning commented on June 6, 2024

Well, I guess it's a project-scope question perhaps - I'm hoping to use
PreMailer.Net as a replacement for my current premailer process which uses
the premailer ruby gem (invoking ruby as an external process).

https://github.com/alexdunae/premailer/

Is that (or should that be) the scope of PreMailer.Net? If it's not,
that's fine, I can look at other options (perhaps IronRuby invoking the
gem? not sure).

FWIW, since Alex has now put the premailer up as an API you can invoke, you
can see a sample of before/after by invoking it - I put up the linqpad
script I'm using for testing at https://gist.github.com/2875820

Thanks!

On Tue, Jun 5, 2012 at 10:13 AM, Martin H. Normark <
[email protected]

wrote:

Hi @jamesmanning

Only potential problem I see, is relative URLs and if it can't find the
css file that the link refers to. But that should be possible to deal
with, and just ignore the link and continue to the next one.

Do you have an example of usage?


Reply to this email directly or view it on GitHub:

#8 (comment)

from premailer.net.

martinnormark avatar martinnormark commented on June 6, 2024

I started the PreMailer.Net project in frustration after using the ruby gem from .Net -- so the scope of PM.Net should definitely be that of the ruby gem. Right now is it just a CSS inliner, and much more should be done.

I've been planning to add more features, but lack of time is a huge constraint.

I'm hoping to get some work done over the summer to raise the level of PM.Net to get closer to the ruby gem.

Keep the ideas coming!

BTW: I didn't know of the API for the ruby gem, that makes it a bit easier to invoke from other languages. But if you're pre-mailing lots of e-mails it might not scale in terms of performance.

from premailer.net.

jamesmanning avatar jamesmanning commented on June 6, 2024

If you don't mind, what approaches were you trying for using the gem from .Net? Just curious if you (or anyone) has gone down the IronRuby path for the premailer gem and already knows the problems (if any) trying to do so.

Thanks! :)

from premailer.net.

martinnormark avatar martinnormark commented on June 6, 2024

I was using the command line approach, as far as I remember. Haven't tried IronRuby.

from premailer.net.

GrimaceOfDespair avatar GrimaceOfDespair commented on June 6, 2024

Just like to hop in here. I tried two approaches some time ago. I'm now grabbing from my defect memory:

  • IronRuby: I believe that I stopped at the point where I had to fix package #423 to be able to run within IronRuby. It was an unpleasant type of depenceny hell. Whenever you fix a package, you bump on a dependency that you need to fix too.
  • IKVM.NET: I believe I was able to get it running, but the overhead is so huge, that it's probably even more performant to just invoke a Ruby process.

from premailer.net.

RomiPierre avatar RomiPierre commented on June 6, 2024

Matin, Can you suggest to add a option to an user add of the path to change the href, src and other links.
In this case the PreMailer take this parameter to change links or images.

PreMailer pr=new PreMailer();
pr.BaseUri =new Uri('http://domainname...');
pr.BaseImgUri= new Uri('http://amazon...bucket..') if not found keep BaseUri.
pr.Fixelinks=true;
pr.FixeImgSrc=true;
Other option to clean the code like hidden fields / viewstates / javascripting.
Great tool thanks.
regards.

from premailer.net.

martinnormark avatar martinnormark commented on June 6, 2024

@RomiPierre Just to verify that I understand correctly, you want to have the BaseUri and BaseImgUri applied to all links and images, respectively?

from premailer.net.

RomiPierre avatar RomiPierre commented on June 6, 2024

Yes in the case that you need to fix the links href values. I suggest pr.Fixelinks=true and pr.FixeImgSrc=true or false and the user found the BaseUri as parameter or similar. I have tried generating a page from my cms but the img and links was relatives. I haved fixed outside PremMailer with agility pack. Why not inside PreMailer?. Similar for ViewStates in inputs or hidden fields, javascripts that can result blocking your ip for spam, if your code is not clear. Regards.

from premailer.net.

RomiPierre avatar RomiPierre commented on June 6, 2024

I have another similar issue with the url path for styles that are relatives. But in this case the path isn't always a markup but and inline style. But same for a <style> markup and a relative path.

from premailer.net.

martinnormark avatar martinnormark commented on June 6, 2024

@RomiPierre PreMailer could definetly contain some proper "pre-mailing" features like processing URLs, cleaning up some mark-up elements etc.

Hidden fields and script blocks should always be removed.

Also, converting relative URLs would be useful since this allows for a better experience while actually developing HTML e-mails.

from premailer.net.

JustMaier avatar JustMaier commented on June 6, 2024

As a temporary workaround I'm reading my CSS file into a string, injecting it into a style tag in the html then feeding it into PreMailer. Seems to work fine...

from premailer.net.

albertbori avatar albertbori commented on June 6, 2024

This works:

public static class HtmlHelpers
{
    private static Dictionary<string, string> _linkedCssCache = new Dictionary<string, string>();

    /// <summary>
    /// Moves and embedded or linked CSS to inline styles
    /// </summary>
    /// <param name="html">The html to be converted (css links must have absolute uri's)</param>
    /// <returns></returns>
    public static string MakeCSSInline(string html)
    {
        string cssResolvedHtml = ResolveCSSLinks(html);
        var premailerResult = PreMailer.Net.PreMailer.MoveCssInline(cssResolvedHtml, true);
        return premailerResult.Html;
    }

    /// <summary>
    /// Replaces any &lt;link rel="stylesheet"&gt; tags with the actual css source.
    /// </summary>
    /// <param name="html">The html to be converted (css links must have absolute uri's)</param>
    /// <returns></returns>
    public static string ResolveCSSLinks(string html)
    {
        var matches = Regex.Matches(html, @"<link\s+rel=""stylesheet""\s+href=""([^""]+)""\s*/>", RegexOptions.IgnoreCase|RegexOptions.Multiline);

        foreach(Match match in matches)
        {
            try
            {
                string css;
                if (!_linkedCssCache.ContainsKey(match.Groups[1].Value))
                {
                    var webRequest = HttpWebRequest.Create(match.Groups[1].Value);

                    var webResponse = webRequest.GetResponse();

                    using (Stream stream = webResponse.GetResponseStream())
                    {
                        StreamReader sr = new StreamReader(stream);

                        css = RemovePremailerNetBrokenSelectorModifiers(sr.ReadToEnd());

                        _linkedCssCache.Add(match.Groups[1].Value, css);
                    }
                }
                else
                    css = _linkedCssCache[match.Groups[1].Value];

                html = html.Replace(match.Groups[0].Value, String.Format("<style type=\"text/css\">{0}</style>", css));
            }
            catch { }
        }

        return html;
    }

    private static string RemovePremailerNetBrokenSelectorModifiers(string css)
    {
        //Remove browser specific selector modifiers
        css = Regex.Replace(css, @"[:]+-[\-a-z0-9]+", String.Empty, RegexOptions.IgnoreCase);

        return css;
    }
}

from premailer.net.

AaronLS avatar AaronLS commented on June 6, 2024

Thanks albert. Made some modifications(maybe improvements, my regex skills are poor) to the code above. 1) Support <link tags where rel and href attributes may appear in any order, may include other attributes, may use single quotes instead of double quotes and may not be a trailing space. More aggressive removing of CSS that might cause CSQuery to blow up. Might be overly aggressive though and also remove CSS that might be supported, but it's what got it working for me such that it wouldn't cash, I.e. something is better than nothing.

/// <summary>
/// Replaces any &lt;link rel="stylesheet"&gt; tags with the actual css source.
/// </summary>
/// <param name="html">The html to be converted (css links must have absolute uri's)</param>
/// <returns></returns>
public static string ResolveCSSLinks(string html, string baseUrl= "")
{
    //find link tags that are of type stylesheet
    var matches = Regex.Matches(html, @"<link.*\s+rel=[""']stylesheet[""'].*/>", RegexOptions.IgnoreCase | RegexOptions.Multiline);

    foreach (Match match in matches)
    {
        //get href, we do this in a second step to allow the href attribute to appear before or after "rel" attribute
        var matchHref = Regex.Matches(match.Value, @"<link.*\s+href=[""']([^""]+)[""'].*/>", RegexOptions.IgnoreCase | RegexOptions.Multiline);

        string href = baseUrl.TrimEnd('/') + "/" + matchHref[0].Groups[1].Value.TrimStart('/');
        try
        {
            string css;
            if (!_linkedCssCache.ContainsKey(href))
            {
                var webRequest = HttpWebRequest.Create(href);

                var webResponse = webRequest.GetResponse();

                using (Stream stream = webResponse.GetResponseStream())
                {
                    StreamReader sr = new StreamReader(stream);

                    css = RemovePremailerNetBrokenSelectorModifiers(sr.ReadToEnd());

                    _linkedCssCache.Add(href, css);
                }
            }
            else
                css = _linkedCssCache[href];

            html = html.Replace(match.Value, String.Format("<style type=\"text/css\">{0}</style>", css));
        }
        catch { }
    }

    return html;
}

private static string RemovePremailerNetBrokenSelectorModifiers(string css)
{
    //Remove browser specific selector modifiers
    css = Regex.Replace(css, @"[:]+-.*{.*}", String.Empty, RegexOptions.IgnoreCase);

    //Some complex media query cause CSQuery to blow up
    css = Regex.Replace(css, @"@media\s.*{.*}", String.Empty, RegexOptions.IgnoreCase);
    return css;
}

from premailer.net.

hidegh avatar hidegh commented on June 6, 2024

If there would be a possibility to pass an entire CSS file content via PremailerNet API, you would:

  • get rid of relative/absolute url links
  • and we would get a possibility to use a single CSS to style every mail output...

from premailer.net.

edikep2000 avatar edikep2000 commented on June 6, 2024

Please has this issue been fixed? I am kind of in a fix with this issue and will really appreciate some light on this

from premailer.net.

martinnormark avatar martinnormark commented on June 6, 2024

Since the fix of #45 done in e375b9f you can specify a CSS string as a parameter when calling PreMailer:

PreMailer.MoveCssInline(input, false, css: ".test { background-color:#f1f1f1; }")

Part of the options.

from premailer.net.

edikep2000 avatar edikep2000 commented on June 6, 2024

I know about that, I am wondering if it is possible to do stuff like this

PreMailer.MoveCssInline(input, false, css: "~/pathToCss")

and If it is possible to pass in more than one CSS file if the aforementioned exists

from premailer.net.

martinnormark avatar martinnormark commented on June 6, 2024

It isn't. But it should be straight forward to load the files yourself into a string and pass that to PM.

from premailer.net.

edikep2000 avatar edikep2000 commented on June 6, 2024

Unfortunately, I cant find any information as to how this can be achieved. Any Pointers please

from premailer.net.

martinnormark avatar martinnormark commented on June 6, 2024

Check out the last comment in issue #67

from premailer.net.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.