I want to generate GSP templates for html emails. To support more mail clients it is recommended to use inline css in html style elements.
Here is a discussion on that topic: "Compile" CSS into HTML as inline styles
Is there a Grails plugin where I can specify certain GSP files for which the CSS should be compiled as inline?
If there is no plugin, how can I specify GSP files for which the css should be complied inline?
Here is an example. I have the following GSP templates for my html mails that I send with the Grails mail plugin.
/mail/signup_mail.gsp
/mail/welcome.gsp
/mail/newsletter.gsp
Each GSP file includes a style.css file. This should be compiled inline.
We do this with a free method on the Mailchimp API. You can also use Premailer.
http://apidocs.mailchimp.com/api/1.2/inlinecss.func.php
http://premailer.dialect.ca/
You can fit the following Java code in your grails application.
import java.io.IOException;
import java.util.StringTokenizer;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class AutomaticCssInliner {
public static void main(String[] args) throws IOException {
final String style = "style";
final String html = "<html>" + "<body> <style>"
+ "body{background:#FFC} \n p{background:red}"
+ "body, p{font-weight:bold} </style>"
+ "<p>...</p> </body> </html>";
// Document doc = Jsoup.connect("http://mypage.com/inlineme.php").get();
Document doc = Jsoup.parse(html);
Elements els = doc.select(style);// to get all the style elements
for (Element e : els) {
String styleRules = e.getAllElements().get(0).data().replaceAll(
"\n", "").trim(), delims = "{}";
StringTokenizer st = new StringTokenizer(styleRules, delims);
while (st.countTokens() > 1) {
String selector = st.nextToken(), properties = st.nextToken();
Elements selectedElements = doc.select(selector);
for (Element selElem : selectedElements) {
String oldProperties = selElem.attr(style);
selElem.attr(style,
oldProperties.length() > 0 ? concatenateProperties(
oldProperties, properties) : properties);
}
}
e.remove();
}
System.out.println(doc);// now we have the result html without the
// styles tags, and the inline css in each
// element
}
private static String concatenateProperties(String oldProp, String newProp) {
oldProp = oldProp.trim();
if (!newProp.endsWith(";"))
newProp += ";";
return newProp + oldProp; // The existing (old) properties should take precedence.
}
}
Related
my english is poor,sorry,i used mxGraph js front-end invoke java back-end servlet to export image,the graph contains html and css,the format of export is png,but the result of export lossed css,but the xml data contains css
To add the CSS in Java if using the export XML format, the createHtmlDocument(String, String) method can be overridden and the CSS can be added as an internal stylesheet (ie in the HEAD section inside a style tag) as follows:
protected String createHtmlDocument(String text, String style)
{
return "<html><head><style type=\"text/css\">.myStyle {color:blue;}</style></head><div style=\"" + style + "\">" + text + "</div></html>";
}
I am going to parse some web pages using Java program. For this purpose I wrote a small code for parsing page content by using xpath as selector. For parsing different sites you need to find the appropriate xpath per each site. The problem is for doing that you need an operator to find the write xpath for you. (for example using firepath firefox addon) Suppose you dont know what page you should parse or the number of sites get really big for operator to find right xpath. In this case you need a way for parsing pages without using any selector. (same scenario exist for CSS selector) Or there should be a way to find xpath automatically! I was wondering what is the method of parsing web pages in this way?
Here is the small code which I wrote for this purpose, please feel free to extend that in presenting your solutions.
public downloadHTML(String url) throws IOException{
CleanerProperties props = new CleanerProperties();
// set some properties to non-default values
props.setTranslateSpecialEntities(true);
props.setTransResCharsToNCR(true);
props.setOmitComments(true);
// do parsing
TagNode tagNode = new HtmlCleaner(props).clean(
new URL(url)
);
// serialize to xml file
new PrettyXmlSerializer(props).writeToFile(
tagNode, "c:\\TEMP\\clean.xml", "utf-8"
);
}
public static void testJavaxXpath(String pattern)
throws ParserConfigurationException, SAXException, IOException,
FileNotFoundException, XPathExpressionException {
DocumentBuilder b = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
org.w3c.dom.Document doc = b.parse(new FileInputStream(
"c:\\TEMP\\clean.xml"));
// Evaluate XPath against Document itself
javax.xml.xpath.XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xPath.evaluate(pattern,
doc.getDocumentElement(), XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); ++i) {
Element e = (Element) nodes.item(i);
System.out.println(e.getFirstChild().getTextContent());
}
}
I'm working with a wizard component. The navbar is in the botton but my boss wants me to put it in the top of the wizard,I thought that it was an attribute or tag to do it straight forward but I have been reviewing the documentation and I should be wrong (I only found the showNavBar tag).
Is there a way to do it without css or jquery? (we have some problems in the application setting css when working with some components so I would like to avoid it).
Thank you very much
You can achieve this in either of the two ways:
1 - Extending the WizardRenderer
By extending the WizradRenderer you can change the order of the encoding.
In the original Renderer the encodeContent(facesContext, wizard); is called before encodeNavigators(facesContext, wizard); so it's pretty much simple, extend you custom renderer, change the order of the calls.
public class ExNavWizardRenderer extends org.primefaces.component.wizard.WizardRenderer{
#Override
protected void encodeMarkup(FacesContext facesContext, Wizard wizard) throws IOException {
ResponseWriter writer = facesContext.getResponseWriter();
String clientId = wizard.getClientId(facesContext);
String styleClass = wizard.getStyleClass() == null ? "ui-wizard ui-widget" : "ui-wizard ui-widget " + wizard.getStyleClass();
writer.startElement("div", wizard);
writer.writeAttribute("id", clientId, "id");
writer.writeAttribute("class", styleClass, "styleClass");
if(wizard.getStyle() != null) {
writer.writeAttribute("style", wizard.getStyle(), "style");
}
if(wizard.isShowStepStatus()) {
encodeStepStatus(facesContext, wizard);
}
// encode the navigators before the content
if(wizard.isShowNavBar()) {
encodeNavigators(facesContext, wizard);
}
encodeContent(facesContext, wizard);
writer.endElement("div");
}
}
Update your faces-config.xml
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.WizardRenderer</renderer-type>
<renderer-class>com.projectPackage.ExNavWizardRenderer</renderer-class>
</renderer>
</render-kit>
2 - jQuery
In your document.ready you can change the DOM, for example this would do the same as the Renderer:
$('.ui-wizard-step-titles').after($('.ui-wizard-navbar'))
I'm attempting to use JSoup to generate HTML from nothing i.e. not parsing a file, but rather generating HTML output in order to display the data in an object. I'm brand new to JSoup and have been looking for some examples of how to use it to generate HTML but haven't found much useful content for this specific task so I've been tinkering, but with minimal success. Here's some [non-working] code:
package jsouptest;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class JSoupTest {
public static void main(String[] args) {
Document doc = new Document("");
Element headline = doc.body().appendElement("h1").text("Some text");
Element pTag = doc.body().appendElement("p").text("some text ...");
Element span = pTag.prependElement("span").text("MoarTxt");
}
}
This line:
Element headline = doc.body().appendElement("h1").text("Some text");
Throws a NullPointerException. Through some trial and error, I believe that I've determined the problem is that doc.body() isn't defined anywhere. I assumed (apparently, incorrectly) that a newly instantiated Document would come with an empty body. That doesn't seem to be the case, however. I can't figure out if I need to instantiate a new body element. I've read through the javadoc for the Document class but don't see any kind of factory or setter methods that would generate the body element for me.
Recommendations for resources beyond the JSoup API JavadDoc that might be helpful are welcome as well.
To append a <body> element to a newly created document, in its simplest form, use:
doc.appendElement("body");
Heres' your full code:
public static void main(String[] args) {
Document doc = new Document("");
doc.appendElement("body");
Element headline = doc.body().appendElement("h1").text("Some text");
Element pTag = doc.body().appendElement("p").text("some text ...");
Element span = pTag.prependElement("span").text("MoarTxt");
System.out.println(doc);
}
Output:
<body>
<h1>Some text</h1>
<p><span>MoarTxt</span>some text ...</p>
</body>
As for documentation, I believe you are already there, their official site is the best place. I'd also take a look at their cookbok.
I want to extract only the views and replies of the user and the title of the head from a forum. In this code when you supply a url the code returns everything. I just want only the thread heading which is defined in title tag and the user reply which is in between the div content tag. Help me how extract. Explain how to print this in a txt file
package extract;
import java.io.*;
import org.jsoup.*;
import org.jsoup.nodes.*;
public class TestJsoup
{
public void SimpleParse()
{
try
{
Document doc = Jsoup.connect("url").get();
doc.body().wrap("<div></div>");
doc.body().wrap("<pre></pre>");
String text = doc.text();
// Converting nbsp entities
text = text.replaceAll("\u00A0", " ");
System.out.print(text);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String args[])
{
TestJsoup tjs = new TestJsoup();
tjs.SimpleParse();
}
}
Why do you wrapt the body-Element in a div and a pre Tag?
The title-Element can be selected like this:
Document doc = Jsoup.connect("url").get();
Element titleElement = doc.select("title").first();
String titleText = titleElement.text();
// Or shorter ...
String titleText = doc.select("title").first().text();
Div-Tags:
// Document 'doc' as above
Elements divTags = doc.select("div");
for( Element element : divTags )
{
// Do something there ... eg. print each element
System.out.println(element);
// Or get the Text of it
String text = element.text();
}
Here's an overview about the whole Jsoup Selector API, this will help you finding any kind of element you need.
Well I used another code and I collected data from this specific tags.
Elements content = doc.getElementsByTag("blockquote");
Elements k=doc.select("[postcontent restore]");
content.select("blockquote").remove();
content.select("br").remove();
content.select("div").remove();
content.select("a").remove();
content.select("b").remove();