Maintaining proper CSS \ Javascript and using a Template Engine - a contradiction? - javascript

A template engine (Velocity, FreeMaker, etc.) lets you, among other things, split up your HTML into re-usable chunks. E.g. you have a <div> showing an ad that appears on lots of places in your site - you can compose a file containing that <div> and its contents once (with Velocity: a 'myAd.vm' file), and load it up into whatever page necessary (with Velocity: apply #parse('myAd.vm').
I like to think of these .vm files as functions, they get "invoked" (parsed) and spit out textual content. They can have "parameters" - in Velocity you can #set( $myParam = 'foo' ) just before parsing the 'myAd.vm' file, and use that variable inside that file.
My question is: How does the proper way of defining CSS and Javascript in their own files fit in with that?
The 'myAd.vm' needs CSS styling, you can define that CSS in that file itself with a <style> tag - which will result in an HTML document with a style tag in its <body> - not in its <head>, and certainly not in a separate file.
Or, you could define the CSS that 'myAd.vm' needs in a separate 'myAd.css' file, and demand that whatever HTML document that parses 'myAd.vm' will have a <LINK REL="StyleSheet" HREF="myAd.css" TYPE="text/css"> in its head tag. This is a problem since it makes things more complex and cumbersome, and - you may want to actually parse the 'myAd.vm' file depending on a conditional (in Velocity, for example, you could have #if(someCondition) #parse('myAd.vm') #end) - meaning you don't actually know in advance whether the head tag should link to that external CSS file.
Any thoughts?
Thanks.

Most frameworks that ive used give you the ability to make some kind of function call that kind of acts as an include for a css or js file, these are then output in the head to external files. In many casses i actually run all these through a minifier so in the end there is only one css and one js file.
This way you can add to the asset stack from within view partials and put stuff directly in the head.

Apache Wicket (a component-based framework) allows you to add what it calls "Header contributions" ("renderHead" method now in Wicket 1.5) as a part of its page composition through inheritance system. This means that, although a page only defines a chunk of the total HTML to be rendered, it can still add something to the <head> of the whole document and therefore include <link> tags for your javascript and CSS files in their correct places.
As for non-component-based frameworks, the Thymeleaf template engine (which can be used with Spring MVC), as a result of its "natural templating" ability, allows you to compose pages by including fragments from other pages (both in <head> and in <body>, which to some extent solves your issue), as opposed to the "inheritance-oriented" approach natural to composition frameworks like Sitemesh or Tiles.
Regards,
Daniel.

Related

How to duplicate HTML templates with different contents (text, picture)

I am making a website where I am going to use the same template for a lot of the same pages, only the text and picture needs to be changed. The only thing that is different from the different pages are the different sports, so I have a jumbotron picture that I want to change, as well as the text about the sport itself. I am wondering if there is any smart ways of doing this instead of making a .html file for every page?
Some file-hosting services allow for a base HTML template, but usually, you will need to create a HTML file for every page on a site. If you use Adobe Muse, for example, it will output the code with the least amount of white-space and with the most efficient size possible. But it will still output multiple HTML pages.
TLDR: You will need to make a HTML document for each page on your site, usually.
Yes, there is a way.
Don't use css in that page itself. Create another page containing only css codes and name it as "css.css" and place the file in same folder in which the html file is present.
Then use external link for css. Insert the code given below in the head part of the html document.
<link rel="stylesheet" type="text/css" href="css.css">
consider to use some templates instead of using plain html.
if you are doing server-side rendering then there are a lot of frameworks you can use for each language.Just google popular framework for the backend language you are using.
For frontend side you can use some Single page application framework for example angular, react, vue or something like handlebars. check them and pick one

How to encapsulate a reusable "control" for ASP.NET MVC 3 + Razor views

I am looking for best practices on how to create a reusable "control" for use on several MVC 3 views. I could make an Html helper extension method (programmatically or with the declarative helpers in razor) or I could create a partial view.
The trick, in my case is that I need to do more than just dump some HTML in precisely the spot that the view calls the helper/partial. In addition to putting some HTML markup in that spot, I also need to add some javascript code to make it work. Normally, I would put this code elsewhere in the page (e.g. the bottom). This is of course strictly not required. Also, note, the javascript is not control instance specific. In other words, it is possible to write javascript that finds all instances of the control HTMl markup on a page and "activates" it with appropriate events, etc.
I have thought of several possibilities.
Have the helper/partial dump out the HTML and a <script> tag right in the place it is called. This seems like a bad idea since it means the control could only be used once per page.
Have two helpers. One to output the HTML markup, and a second that spits out the javascript. The second would be called only ever once and would be called from the bottom of the page so that the script ends up in the right place. If I invented a second control that was like this, I would have 4 helpers (2 for HTML, 2 for Javascript).
Invent some kind of ScriptManager that controls can register javascript with. The scriptmanager would have some kind of helper that would be added to the bottom of pages and would dump out the javascript for all controls that had registered some snippet of script. The call to the scriptmanager helper could be in the _layout.cshtml so that it automatically happens on any page that needs it. It would do nothing when a page didn't need it. This doesn't seem very MVC-ish, I guess.
Just have a helper that spits out the HTML and then add the javascript to the site.js that is included on every page. The javascript would be smart enough to not do anything if it could not find any relevant markup on the page (markup would have a wrapper element with a particular class). There would be overhead of this search for markup on all pages though, including pages that don't have any of these controls.
Same as #4, but put the javascript in its own .js file and include it only on pages that use the control. This is more efficient for pages that don't use the control, but it is an additional .js file and associated HTTP request for pages that do.
I am leaning towards #4, but is this a solved problem? Is there a better, 6th option?
My company is employing MVCContrib portable areas to package the code into a DLL for reusable "components"
Each of these components can be called via an extension method. For example:
Html.Components().ShowPoll();
Within each of these components, there is a way to register multiple css/js files that are embedded resources. Our main site will extract the resource files and minify + combines them before serving it.
The component will also register any on page event that will be called during the Document.OnReady event of JQuery. This allows each of the components to be mini-sites, standalone functionality with its own routes, models, and views.
Across the entire site, the same zip up JS for all the components are served. One because the file will be cached, and two - removes the complexity of determining what components are on the page and the resources it needs.
Let me know if you want more information regarding this setup.
I managed this issue with a layout page that had a section called jsCode.
#RenderSection("jsCode",false)
Then when I need it, I create in the content page:
#section jsCode
{
<script type="text/JavaScript" src="myJsCode.js"></script>
}
you could also create a helper that spits out the scripts you need for a particular page and encapsulate it that way, like this:
#helper MyJSFunction(string FunctionName){
switch(FunctionName)
{
case "firstFN":
<text>
<script type="text/JavaScript">
function SaySomethingSilly()
{
var sillySaying="We are the knights who say 'ni'!";
alert(sillySaying);
}
</script>
</text>
break;
case "secondFN":
<text>
<script type="text/JavaScript">
function SaySomethingElse()
{ var sillySaying="We are looking for a shrubbery...";
alert(sillySaying);
}
</script>
</text>
break;
}
}
Then my content page (assuming I want both functions) looks like this:
#{
Page.Title="Using helpers to create scripts";}
#section jsCode
{
#JSHelpers.MyJSFunction("firstFN")
#JSHelpers.MyJSFunction("secondFN")
}
<p>It works!</p>
which produced the output:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Using helpers to create scripts</title>
<script type="text/JavaScript">
function SaySomethingSilly()
{
var sillySaying="We are the knights who say 'ni'!";
alert(sillySaying);
}
</script>
<script type="text/JavaScript">
function SaySomethingElse()
{ var sillySaying="We are looking for a shrubbery...";
alert(sillySaying);
}
</script>
</head>
<body>
<p>It works!</p>
</body>
</html>
Now if you wanted to get super-efficient, (though other words come to mind) you could pass the function a JSON array or a dictionary or even a string array with the names of the scripts you wanted to use, or the JavaScript to import, or whatever, and just use a single call to the helper. I think separate calls is easier to maintain, regardless of how you load the return values of the helper function, because you can see cleanly at a glance which scripts you are using on a given page, and to eliminate or add one is a simple one-line change rather than changing one element of an array.
As always, your mileage may vary, but I ran the sample based on this code in WebMatrix Beta 2 without any issues.
Lisa Z. Morgan
http://www.lairhaven.com

Add ASP.NET server script to mostly-static .JS / .CSS files without losing IntelliSense?

Using VS2008 and ASP.NET 3.5 (or VS 2010 / .NET 4.0?), how can I include a bit of dynamic ASP.NET server-side code in mostly-static JavaScript and CSS files?
I want to do this to avoid cloning entire JS or CSS files to vary just a small part of them multi-tenant sites. Later, I want to extend the solution to handle localization inside javascript/CSS, dynamic debugging/tracing support, and other cool things you can get by injecting stuff dynamically into JavaScript and CSS.
The hard part is that I don't want to lose all the cool things you get with static files, for example:
JS/CSS code coloring and intellisense
CSS-class "go to definition" support in the IDE
automatic HTTP caching headers based on date of underlying file
automatic compression by IIS
The server-side goodness of static files (e.g. headers/compression) can be faked via an HttpHandler, but retaining IDE goodness (intellisense/coloring/etc) has me stumped.
An ideal solution would meet the following requirements:
VS IDE provides JS/CSS intellisense and code coloring. Giving up server-code intellisense is OK since server code is usually simple in these files.
"go to defintion" still works for CSS classes (just like in static CSS files)
send HTTP caching headers, varying by modified date of the underlying file.
support HTTP compression like other static files
support <%= %> and <script runat=server> code blocks
URL paths (at least the ones that HTTP clients see) end with .JS or .CSS (not .ASPX). Optionally, I can use querystring or PathInfo to parameterize (e.g. choosing a locale), although in most cases I'll use vdirs for this. Caching should vary for different querystrings.
So far the best (hacky) solution I've come up with is this:
Switch the underlying CSS or JS files to be .ASPX files (e.g. foo.css.aspx or foo.js.aspx). Embed the underlying static content in a STYLE element (for CSS) or a SCRIPT element (for JS). This enables JS/CSS intellisense as well as allowing inline or runat=server code blocks.
Write an HttpHandler which:
looks at the URL and adds .aspx to know the right underlying ASPX to call
uses System.Net.HttpWebRequest to call that URL
strips out the containing STYLE or SCRIPT tags, leaving only the CSS or JS
adds the appropriate headers (caching, content type, etc.)
compresses the response if the client suports compression
Map *.CSS and *.JS to my handler.
(if IIS6) Ensure .JS and .CSS file extensions are mapped to ASP.NET
I'm already using a modified version of Darick_c's HttpCompression Module which handles almost all of above for me, so modifying it to support the solution above won't be too hard.
But my solution is hacky. I was wondering if anyone has a more lightweight approach for this problem which doesn't lose Visual Studio's static-file goodness.
I know I can also hack up a client-side-only solution where I split all JS and CSS into "vary" and "won't vary" files, but there's a performance and maintenance overhead to this kind of solution that I'd like to avoid. I really want a server-side solution here so I can maintain one file on the server, not N+1 files.
I've not tried VS10/.NET 4.0 yet, but I'm open to a Dev10/.net4 solution if that's the best way to make this scenario work.
Thanks!
I have handled a similar problem by having a master page output a dynamic generated JSON object in the footer of each page.
I needed to have my js popup login dialog box support localization. So using JSON.NET for serialization, I created a public key/value collection property of the master page that pages could access in order place key/values into such as phrase key/localized phrase pairs. The master page then renders a dynamic JSON object that holds these values so that static js files could reference these dynamic values.
For the js login box I have the masterpage set the localized values. This made sense because the masterpage also includes the login.js file.
I do commend you on your concern over the number of http requests being made from the client and the payload being returned. Too many people I know and work with overlook those easy optimizations. However, any time I run into the same issue you're having (which is actually quite often), I have found I've usually either taken a wrong turn somewhere or am trying to solve the problem the wrong way.
As far as your JS question goes, I think Frank Schwieterman in the comments above is correct. I'd be looking at ways to expose the dynamic parts of your JS through setters. A really basic example would be if you have want to display a customized welcome message to users on login. In your JS file, you can have a setMessage(message) method exposed. That method would then be called by the page including the script. As a result, you'd have something like:
<body onLoad="setMessage('Welcome' + <%= user.FirstName %>);">
This can obviously be expanded by passing objects or methods into the static JS file to allow you the functionality you desire.
In response to the CSS question, I think you can gain a lot from the approach Shawn Steward from the comments makes a good point. You can define certain static parts of your CSS in the base file and then redefine the parts you want to change in other files. As a result, you can then dictate the look of your website by which files you're including. Also, since you don't want to take the hit for extra http requests (keep in mind, if you set those files to be cached for a week, month, etc. it's a one time request), you can do something like combining the CSS files into a single file at compilation or runtime.
Something like the following links may be helpful in pointing you in the right direction:
http://geekswithblogs.net/rashid/archive/2007/07/25/Combine-Multiple-JavaScript-and-CSS-Files-and-Remove-Overheads.aspx
http://www.asp.net/learn/3.5-SP1/video-296.aspx?wwwaspnetrdirset=1
http://dimebrain.com/2008/04/resourceful-asp.html
By utilizing the combining at run or compile time you can gain the best of both world by allowing you to logically separate CSS and JS files, yet also gaining the reduction of payload and requests that comes with compressing and combining files.

Executing groovy statements in JavaScript sources in Grails

There are essentially 2 places to define JavaScript functions in Grails, directly in a element on the GSP, and within a separate javascript source file under /web-app/js (for example, application.js). We have defined a commonly reused javascript function within application.js, but we also need to be able to generate parts of the function dynamically using groovy code. Unfortunately, ${some groovy code} does not appear to be processed within separate javascript source files.
Is the only way to do this by defining the javascript function within a script tag on a GSP page, or is there a more general solution? Obviously we could define the javascript function in a script tag within a template GSP file which would be reused, but there is a lot of push to keep our javascript functions defined all together in one place (i.e. the external javascript source file). This has performance benefits as well (the javascript source files are usually just downloaded once by each client's browser, instead of reloading the same javascript functions within the source of every html page they visit). I have toyed around with the idea of breaking the function up into static and dynamic pieces, putting the static ones in the external source and putting the dynamic ones in the template GSP, then gluing them together, but this seems like an unnecessary hack.
Any ideas?
(edit: It may sound like the idea of dynamically generating parts of a JavaScript function, which is then downloaded once and used over and over again by the client, would be a bad idea. However, the piece which is "dynamic" only changes perhaps once a week or month, and then only very slightly. Mostly we just want this piece generated off the database, even if only once, instead of hard coded.)
An easy solution to keep your JavaScript unobtrusive is to create a JavaScriptController and map its actions "/js/*" by adding this to your UrlMappings.groovy file:
"/js/$action"{
controller = "javascript"
}
then just create an action for each dynamic JS file you want, include in in your layout <HEAD>, and presto, you've got a JS file that you can insert Grails snippets into! :)
Note: I've found that there's currently a bug in Grails that doesn't map file extensions to content-types properly, so you'll need to include <%# page contentType="text/javascript; UTF-8" %> at the top of your view files.
This is a great solution. I would like to offer a suggestion to use somthing other then a mapping of "/js/$action" because this is no longer going to allow you to access you javascript files in /web-app/js/. All your javascript files would have to be moved to a the directory your controller would point to.
I would use something like
"/dynjs/$action"
This way you still can point to files in the /web-app/js/ files with out conflict and enjoy the benifits of gsp tags in javascript files
Please correct me if I'm wrong.
Or this... have a tag/service/dynamic method that lets tags write out their JS+CSS+whatever else, to a "cache" which is used to build the JS+CSS resources by a different controller.
Full concept here: [http://www.anyware.co.uk/2005/2009/01/19/an-idea-to-give-grails-tags-esp/][1]
If you want to use models created by the controller (that rendered HTML page which reference the Javascript in which you intend to use groovy code) in the Javascript code, then you can use this technique:
This technique does not need to change URL mappings and does not require you to create extra controller.
In your view GSP add javascript as follows:
<script type="text/javascript">
<g:render template="/javascript/yourJavascriptFile"/>
</script>
In views folder create a "javascript" folder. And create a file named:
_yourJavascriptFile.gsp
You can not only use all the GSP code in your _yourJavascriptFile.gsp file, but you can also use all the models created in your controller (that is rendering the view).
NOTE: There is nothing special about javascript folder. You can name it anything you want OR use an existing view folder. This is just a matter of organizing and identifying your HTML spitting GSP from Javascript spitting GSPs. Alternatively, you can use some naming conventions like: _something.js.gsp etc.
Name your scripts like this
/wherever/the/js/files/are/thescript.js.gsp
The gsp code inside will be rendered correctly by grails. This works, but I have no idea if it's considered a Good Idea or not.
There is another way - pass in the generated code into a function that expects closures. Those closures is generated by the program of course. The generated code is of course inlined/script-tagged in the gsp page.
it may or may not work depending on the nature of the code being generated. But i suspect it will work, and if it doesnt, minor tweaking to the coding style of your javascript will definitely make it work. Though, if these 'generated' code doesnt change much, this quite overkill imo.

Is it possible to use Django to include CSS (here's the tricky part) from a JS file?

As far as I know, there's no way to use {% include %} within a dynamic JS file to include styles. But I don't want to have to make another call to the server to download styles.
Perhaps it would be possible by taking a stylesheet and injecting it into the head element of the document...has anyone does this before?
In your JS file:
var style = document.createElement('link');
style.setAttribute('rel', 'stylesheet');
style.setAttribute('type', 'text/css');
style.setAttribute('href', 'style.css');
document.getElementsByTagName('head')[0].appendChild(style);
Hope that helps.
With jquery...
$('head').append($('<link rel="stylesheet" type="text/css" href="style.css">'))
I can envision cases where you'd want to dynamically generate JS or CSS, but generally you're better off creating static files for each and making your code general enough to fulfill all your needs.
This goes beyond a simple matter of code reuse - if you're dynamically generating any of this, it will need to be re-downloaded each time it's used. You're wasting CPU time rendering the templates, and wasting bandwidth sending the same (or potentially the same) data over the wire over and over.
But if you have a good use case for meta-coding, there's no reason why you can't either:
a) put the JS or CSS in the header (or body, in the case of JS) of your rendered template
b) create a view for the JS or CSS, and use Django's template engine to render them.
The {% include %} tag will work fine for (a), and for (b) you'd just use normal HTML to reference the URL of your view.

Categories