Comments (22)
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.
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.
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:
Only potential problem I see, is relative URLs and if it can't find the
css
file that thelink
refers to. But that should be possible to deal
with, and just ignore thelink
and continue to the next one.Do you have an example of usage?
Reply to this email directly or view it on GitHub:
from premailer.net.
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.
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.
I was using the command line approach, as far as I remember. Haven't tried IronRuby.
from premailer.net.
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.
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.
@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.
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.
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.
@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.
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.
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 <link rel="stylesheet"> 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.
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 <link rel="stylesheet"> 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.
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.
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.
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.
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.
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.
Unfortunately, I cant find any information as to how this can be achieved. Any Pointers please
from premailer.net.
Check out the last comment in issue #67
from premailer.net.
Related Issues (20)
- Breaking changes in dependencies / .NET Standard 2.0 support
- MoveCssInline returns self-closing title when empty HOT 5
- MoveCssInline encodes non-ASCII characters even when they should be valid HTML
- Regex in CssParser never ends and uses 100% cpu. HOT 1
- url embedded resources HOT 2
- Request to change colors defined with hsl/hsla to rgb/rgba HOT 1
- Anchor tags should be appended after analytics tags
- Performance issue when process email containing useless big Style tag to small body content HOT 1
- MoveCssInline is HTML encoding CSS HOT 2
- Inliner strips out vml from html tag HOT 1
- Configure continuous benchmark
- Add more example HTML emails to benchmark
- Automate contributors list in README
- Resolve css var's with their actual values?
- Ability to specify which classes should not be removed, like "preheader"
- How to keep html entities (such as ©) from being converted to special characters? HOT 3
- Are you looking for maintainers? HOT 23
- RobiniaDocs API Explorer
- Bug in comment regex, fix in issue description HOT 1
- Two same CSS properties on same dom element does not work HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from premailer.net.