My colleague is extremely 'hot' on properly formatted and indented html being delivered to the client browser. This is so that the page source is easily readable by a human.
Firstly, if I have a partial view that is used in a number of different areas in my site, should the rendering engine be automatically formatting the indentations for me (ala setting the Formatting property on an XmlTextWriter)?
Secondly, my colleague has created a number of HtmlHelper extension methods for writing to the response. These all require a CurrentIndent parameter to be passed to them. This smells wrong to me.
Can anyone help with this?
This sounds difficult to maintain. If someone removed an outer element from the HTML, would anyone bother to update the CurrentIndent values in the code? These days most developers usually view their HTML through Firebug anyway, which formats the markup automatically with indentation.
If you really want to post-process HTML through a formatting filter then try a .NET port of HTML Tidy.
Browsers absolutely don't care how beautiful the HTML indentation is. What's even more, deeply nested (and thus heavily indented) HTML adds a slight overhead to the page (in terms of bytes to download). Granted, you can always compress response and well-indented HTML is nicer to support.
Even if for some crazy reason it HAS TO be indented "properly", it shouldn't be done the way your colleague suggests.
An HttpModule attached to ReleaseRequestState event of the HttpApplication object should do the trick. And of course, you're going to need to come up with a filter that handles this indenting.
public class IndentingModule: IHttpModule {
public void Dispose() {
}
public void Init(HttpApplication context) {
context.ReleaseRequestState +=
new EventHandler(context_ReleaseRequestState);
}
void context_ReleaseRequestState(object sender, EventArgs e) {
HttpApplication app = (HttpApplication)sender;
app.Response.Filter = new IndentingFilter(app.Response.Filter)
}
}
Rather than waste time implementing a proper indenting solution which would affect all HTTP requests (thus adding CPU and bandwidth overhead), just suggest to your colleague that he use an HTML beautifier. That way the one person that cares about it is the one person that pays the cost of it.
This Firefox plugin is an HTML validator that also includes a beautification function. See the documentation here.
Related
I'm developing an application using GWT (first-timer) and am now at the stage where I want to establish a central structure to provide actual text-based content to my views.
Even though it's obviously possible to define those text-values inline (using UiBinder or calling the appropriate methods on the corresponding objects), I'd be much more comfortable storing them in a central place as is possible using GWT's Constants. Indeed, my application will only be available in one language (for now), so all-the-way i18n may seem overkill, but I'm assuming that those facilities might be best-suited for what I require, seeing how they, too, must have been designed with providing all (constant) text content in mind.
However, my application features several passages of text that are somewhat longer and more complex than your average label text, meaning they could span several lines and might require basic text formatting. I have come up with several ideas on how to fix those issues, but I'm far from satisfied.
First problem: Lengthy string values.
import com.google.gwt.i18n.client.Constants;
public interface AppConstants extends Constants {
#Constants.DefaultStringValue("User Administration")
String userAdministrationTitle();
// ...
}
The sample above contains a very simple string value, defined in the manner that static string internationalization dictates (as far as I know). To add support for another language, say, German, one would provide a .properties file containing the translation:
userAdministrationTitle = Benutzeradministration
Now, one could easily abuse this pattern to a point and never provide a DefaultStringValue, leaving an empty string instead. Then, one could create a .properties file for the default language and add text like one would with a translation. Even then, however, it is (to my knowledge) not possible to apply line-breaks for long values simply to keep the file somewhat well-formatted, like this:
aVeryLongText = This is a really long text that describes some features of the
application in enough detail to allow the user to act on a basis
of information rather than guesswork.
Second problem: Formatting parts of the text.
Since the values are plain strings, there isn't much room for formatting there. Instinctively, I would do the same thing as I would if I were writing the text straight into the regular HTML document and add HTML-tags like <strong> or <em>.
Further down the road, at the point where the strings are read and applied to the widget that's going to display them, there is a problem though: setting the value using a method like setText(String) causes that string to be escaped and the HTML-tags to be printed alongside the rest of the text rather than to be interpreted as formatting instructions. So no luck.
A way to solve this would be to disect the string provided by the i18n file and isolate any HTML-tags, then baking the mess together again using a SafeHtmlBuilder and using that to set the value of the widget, which would indeed result in a formatted text being displayed. That sounds like much of an overcomplication though, so I don't quite like that idea.
So what am I looking for now, dear user who actually read this all the way through (thanks!)? I'm looking for solutions that don't require hacks like the ones described above and provide the functionality that I'm looking for. Alternatively, I welcome any guidance if I'm on the wrong path entirely (GWT first-timer, as I mentioned one eternity ago :-) ). Or basically anything that's on topic and might help find a solution. An acceptable solution, for example, would be a system like the string value files used in Android development (which allows for HTML-styling the texts but obviously requires the containing UI elements to accept that).
Fortunately, there is a standard solution that you can use. First, you need to create a ClientBundle:
public interface HelpResources extends ClientBundle {
public static final HelpResources INSTANCE = GWT.create(HelpResources.class);
#Source("account.html")
public ExternalTextResource account();
#Source("organization.html")
public ExternalTextResource organization();
}
You need to put this bundle into its own package. Then you add HTML files to the same package - one for each language:
account.html
account_es.html
organization.html
organization_es.html
Now, when you need to use it, you do:
private HelpResources help = GWT.create(HelpResources.class);
...
try {
help.account().getText(new ResourceCallback<TextResource>() {
#Override
public void onError(ResourceException e) {
// show error message
}
#Override
public void onSuccess(TextResource r) {
String text = r.getText();
// Pass this text to HTML widget
}
} catch (ResourceException e) {
e.printStackTrace();
}
You need to use HTML widget to display this text if it contains HTML tags.
If you're using UiBinder, i18n support is built-in. Otherwise, use Messages and Constants and use the value with setHTML rather than setText.
For long lines, you should be able to use multiline values in properties files by ending lines with a backslash.
I've searched the internet for days now with no luck finding this.
My model has a property which holds a chunk of html containing Razor markup.
exmaple:
public class ViewModel
{
public string Content = "<div>#Html.TextBox(\"UserName\")</div>";
}
In the view, I display that with
#Html.Raw(Server.HtmlDecode(Model.Content).toString())
I need to be able to convert the Razor markup into html, although because the Content is dropped in through the model, the view engine doesn't process it.
I have tried simply dropping in the Content, using just .Raw(Model.Content), .Encode(Model.Content), nothing works.
Any thoughts?
You could use the RazorEngine package which allows you to parse and execute Razor code. This being said I would not recommend you giving your users the power of editing directly Razor templates. You are opening a huge security hole in your website.
There are other templating engines such as DotLiquid for example which are better suited for scenarios where you don't trust user input.
I was wondering what the best approach is on Android to retrieve information from a HTML page hosted on the internet?
For example I'd like to be able to get the text from the following page at the start of each day:
http://www.met.ie/forecasts/sea-area.asp
I have been downloading and parsing XML files but I have never tried to parse information from a HTML type file before.
Is there a native way to parse the information I want?
Or do I need a third party library?
Or do I need to look into screen scraping?
If you are parsing HTML, regardless of how you do it, you are screen scraping. Techniques run the gambit from regular expressions to 3rd party libraries like jTidy. Only problem is does jTidy work on Android? I don't know. You'll have to research it.
I'd suggest using regular expressions, compile them, and cache the Pattern object for performance.
If you can't get a proper webservice API for the data you want then you always run the risk of the author changing the layout and moving the data on you and breaking your code. That's why screen scraping is generally frowned upon and only used as a last ditch effort.
If you don't want to go the third party way - you could use a webview and inject javascript to it to extract the information you want.
Example code:
WebView webview = new WebView(context);
webView.addJavascriptInterface(new jsInterface() {
public void parseForcast(String html){
// do something with html
}
}, "Foo");
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url){
if (url.equals(FORECAST_URL){
loadUrl("javascript:window.Foo.parseForecast(document.getElementById('content').innerHTML);");
}
});
webview.loadUrl(FORECAST_URL);
Is there a native way to parse the information I want?
No.
Or do I need a third party library?
Yes.
Or do I need to look into screen scraping?
What you are looking to do fits the term "screen scraping" as it is used with respect to Web sites. As I wrote in a previous question on this topic, to parse HTML, you use an HTML parser. There are several open source ones, and it is reasonably likely that one or more will work on Android with few modifications if any.
In my WPF project I need to render HTML-based content, where the content is stored in a resource assembly referenced by my WPF project.
I have looked at the WPF Frame and WebBrowser controls. Unfortunately, they both only expose Navigation events (Navigating, Navigated), but not any events that would allow me, based on the requested URL, to return HTML content retrieved from the resource assembly.
I can intercept navigation requests and serve up HTML content using the Navigating event and the NavigateToString() method. But that doesn't work for intercepting load calls for images, CSS files, etc.
Furthermore, I am aware of an HTML to Flowdocument SDK sample application that might be useful, but I would probably have to extend the sample considerably to deal with images and style sheets.
For what it is worth, we also generate the HTML content to be rendered (via Wiki pages) so the source HTML is somewhat predictable (e.g., maybe no JavaScript) in terms for referenced image locations and CSS style sheets used. We are looking to display random HTML content from the internet.
Update:
There is also the possibility to create an MHT file for each HTML page, which would 'inline' all images as MIME-types and alleviate the need to have finer-grained callbacks.
If you're okay with using a 28 meg DLL, you may want to take a look at BerkeliumSharp, which is a managed wrapper around the awesome Berkelium library. Berkelium uses the chromium browser at its core to provide offscreen rendering and a delegated eventing model. There are tons of really cool things you can do with this, but for your particular problem, in Berkelium there is an interface called ProtocolHandler. The purpose of a protocol handler is to take in a URL and provide the HTTP headers and body back to the underlying rendering engine.
In the BerkeliumSharp test app (one of the projects available in the source), you can see one particular use of this is the FileProtocolHandler -- it handles all the file IO for the "file://" protocol using .NET managed classes (System.IO). You could do the same thing for a made up protocol like "resource://". There's really only one method you have to override called HandleRequest that looks like this:
bool HandleRequest (string url, ref byte[] responseBody, ref string[] responseHeaders)
So you'd take a URL like "resource://path/to/my/html" and do all the necessary Assembly.GetResourceStream etc. in that method. It should be pretty easy to take a look at how FileProtocolHandler is used to adapt your own.
Both berkelium and berkelium sharp are open source with a BSD license.
The WebBrowser exposes a NavigateToStream(Stream) method that might work for you:
If your content is then stored as an embedded resource, you could use:
var browser = new WebBrowser();
var source = Assembly.Load("ResourceAssemblyName");
browser.NavigateTo(source.GetManifestResourceStream("ResourceNamespace.ResourceName"));
There is also a NavigateToString(string) method that expects the string content of the document.
Note: I have never used this in anger, so I have no idea how much help it will be!
I'm just curious if anyone has any tricks on how to keep source code looking good when you "View Source." I'm militant about keeping my code well formatted and spaced while I'm developing and I tend to "View Source" a lot to double check the output (when firebug is overkill). When I start using RenderPartials and RenderActions and anything in the tag it gets pretty messy.
I don't want to send too many extra characters to the browser to keep file size efficient but is there a way to force the xhtml/html to do a newline or tab? I tried a couple of things that didn't work. Thanks!
Get over it.
Don't worry about how it looks in 'view source'; worry about how it looks in csharp :) If you get worried about the efficiency of the HTML you can gzip it, and other such things.
I use firefox's ViewSourceWith extension to view the source in a code editor (in my case SciTe) in which I have a macro programmed so that when I press Ctrl-1 it reformats the HTML using a script I've written.
If validation is the goal then consider using a HTML validator rather than your eyeballs. Total Validator looks good.
Just send a \n and it should come out as a newline in the "view-source" section of the browser.
Example:
public static String Etc(...)
{
TagBuilder myTag = new TagBuilder("span");
myTag.SetInnerText("I'm mr. tag-content!");
return myTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
}