My understanding of drango templates is that everything happens on server side and then it generates an html out of the templates. After, generation, it is just plain text in the html. But for some reason, I am able to use django variables dynamically in javascript.
Here is a javascript example:
$("#smth").append("<li>{{djangoObject.0.id}}</li>");
Even if I put this in an event handler, meaning, it for sure will be called after the html generation, it works just fine.
How and most importantly, WHY does django keep the variable in the client-side?
It's not being used client side, it's just being rendered directly into the Javascript string. So if djangoObject[0].id were 12, for example, the resulting code would look like
$("#smth").append("<li>12</li>");
Which, obviously, would run just fine. It's not dynamic though, and be sure to keep that in mind - it doesn't fetch id at the point of the event happening. It fetches it at template rendering, which happens before the HTML (and embedded Javascript) is sent to the client (your browser).
This code rendered to something like $("#smth").append("<li>123</li>");. Of course this work without any problem after the html generation.
Related
Just a quick question here. I am trying to register a js file for script validation using
if (!Page.ClientScript.IsClientScriptBlockRegistered("strIncludeJSFile")) Page.ClientScript.RegisterClientScriptBlock(strIncludeJSFile.GetType(), "strIncludeJSFile", strIncludeJSFile);
code in C# and it works well for the js files. But, some js files are used in multiple pages, so I am unsure if the above code will be a good idea. As such, I want to do the same thing in the js file itself, instead of using the code behind. Is there any possibility to do that? Or is this thing specific to C#?
of course you can register a js file (or script block) from html by using a script tag. However, the main reason RegisterClientScriptBlock exists is because developers might need to generate (or modify) a script block dynamically from code behind or conditionally register a script file dynamically.
If you need any of the above...generate a script block dynamically, then you "might" be better off registering it from code behind, I mean, it depends on the whole solution itself, it's hard to recommend an approach without having some context. Either way, some options are:
register the script blocks from code behind if you need to generate based on some conditions that can only be evaluated from server side code
use a master page for better and register the script block from the master page. This will make it easier to maintain if you keep the logic in one place
similar to the option above, you can use a base page class if using a master page is not possible
use an html script element if what you need is to reference a static js file
use place holders such as js variables and fetch dynamic data from the server using ajax
use unobtrusive javascript, custom data attributes and ajax
Whatever the suitable option(s) is depends on too many factor that you have to assess
I am using HtmlUnit to read content from a web site.
Everything works perfectly to the point where I am reading the content with:
HtmlDivision div = page.getHtmlElementById("my-id");
Even div.asText() returns the expected String object, but I want to get the original HTML inside <div>...</div> as a String object. How can I do that?
I am not willing to change HtlmUnit to something else, as the web site expects the client to run JavaScript, and HtmlUnit seems to be capable of doing what is required.
If by original HTML you mean the HTML code that HTMLUnit has already formatted then you can use div.asXml(). Now, if you really are looking for the original HTML the server sent you then you won't find a way to do so (at least up to v2.14).
Now, as a workaround, you could get the whole text of the page that the server sent you with this answer: How to get the pure raw HTML of a page in HTMLUnit while ignoring JavaScript and CSS?
As a side note, you should probably think twice why you need the HTML code. HTMLUnit will let you get the data from the code, so there shouldn't be any need to store the source code but rather the information it is contained in it. Just my 2 cents.
Currently I am creating a website which is completely JS driven. I don't use any HTML pages at all (except index page). Every query returns JSON and then I generate HTML inside JavaScript and insert into the DOM. Are there any disadvantages of doing this instead of creating HTML file with layout structure, then loading this file into the DOM and changing elements with new data from JSON?
EDIT:
All of my pages are loaded with AJAX calls. But I have a structure like this:
<nav></nav>
<div id="content"></div>
<footer></footer>
Basically, I never change nav or footer elements, they are only loaded once, when loading index.html file. Then on every page click I send an AJAX call to the server, it returns data in JSON and I generate HTML code with jQuery and insert like this $('#content').html(content);
Creating separate HTML files, and then for example using $('#someID').html(newContent) to change every element with JSON data, will use even more code and I will need 1 more request to server to load this file, so I thought I could just generate it in browser.
EDIT2:
SEO is not very important, because my website requires logging in so I will create all meta tags in index.html file.
In general, it's a nice way of doing things. I assume that you're updating the page with AJAX each time (although you didn't say that).
There are some things to look out for. If you always have the same URL, then your users can't come back to the same page. And they can't send links to their friends. To deal with this, you can use history.pushState() to update the URL without reloading the page.
Also, if you're sending more than one request per page and you don't have an HTML structure waiting for them, you may get them back in a different order each time. It's not a problem, just something to be aware of.
Returning HTML from the AJAX is a bad idea. It means that when you want to change the layout of the page, you need to edit all of your files. If you're returning JSON, it's much easier to make changes in one place.
One thing that definitly matters :
How long will it take you to develop a new system that will send data as JSON + code the JS required to inject it as HTML into the page ?
How long will it take to just return HTML ? And how long if you can re-use some of your already existing server-side code ?
and check how much is the server side interrection of your pages...
also some advantages of creating pure HTML :
1) It's simple markup, and often just as compact or actually more compact than JSON.
2) It's less error prone cause all you're getting is markup, and no code.
3) It will be faster to program in most cases cause you won't have to write code separately for the client end.
4) The HTML is the content, the JavaScript is the behavior. You're mixing both for absolutely no compelling reason.
in javascript or nay other scripting language .. if you encountered a problem in between the rest of the code will not work
and also it is easier to debug in pure html pages
my opinion ... use scriptiong code wherever necessary .. rest of the code you can do in html ...
it will save the triptime of going to server then fetch the data and then displaying it again.
Keep point No. 4 in your mind while coding.
I think that you can consider 3 methods:
Sending only JSON to the client and rendering according to a template (i.e.
handlerbar.js)
Creating the pages from the server-side, usually faster rendering also you can cache the page.
Or a mixture of this would be to generate partial views from the server and sending them to the client, for example it's like having a handlebar template on the client and applying the data from the JSON, but only having the same template on the server-side and rendering it on the server and sending it to the client in the final format, on the client you can just replace the partial views.
Also some things to think about determined by the use case of the applicaton, is that if you are targeting SEO you should consider ColBeseder advice, of if you are targeting mobile users, probably you would better go with the JSON only response, as this is a more lightweight response.
EDIT:
According to what you said you are creating a single page application, if this is correct, then probably you can go with either the JSON or a partial views like AngularJS has. But if your server-side logic is written to handle only JSON response, then probably you could better use a template engine on the client like handlerbar.js, underscore, or jquery templates, and you can define reusable portions of your HTML and apply to it the data from the JSON.
If you cared about SEO you'd want the HTML there at page load, which is closer to your second strategy than your first.
Update May 2014: Google claims to be getting better at executing Javascript: http://googlewebmastercentral.blogspot.com/2014/05/understanding-web-pages-better.html Still unclear what works and what does not.
Further updates probably belong here: Do Google or other search engines execute JavaScript?
I'm usually a creative gal, but right now I just can't find any good solution. There's HTML (say form rows or table rows) that's both generated javascript-based and server-sided, it's exactly the same in both cases. It's generated server-sided when you open the page (and it has to stay server-sided for Google) and it's generated by AJAX, to show live updates or to extend the form by new, empty rows.
Problem is: The HTML generation routines are existing twice now, and you know DRY (don't repeat yourself), aye? Each time something's changed I have to edit 2 places and this just doesn't fit my idea of good software.
What's your best strategy to combine the javascript-based and server-sided HTML generation?
PS: Server-sided language is always different (PHP, RoR, C++).
PPS: Please don't give me an answer for Node.JS, I could figure that out on my own ;-)
Here's the Ruby on Rails solution:
Every model has its own partial. For example, if you have models Post and Comment, you would have _post.html.erb and _comment.html.erb
When you call "render #post" or "render #comment", RoR will look at the type of the object and decide which partial to use.
This means that you can redner out an object in the same way in many different views.
I.e. in a normal response or in an AJAX response you'd always just call "render #post"
Edit:
If you would like to render things in JS without connecting to the server (e.g. you get your data from a different server or whatever), you can make a JS template with the method I mentioned, send it to the client and then have the client render new objects using that template.
See this like for a JS templating plugin: http://api.jquery.com/category/plugins/templates/
Make a server handler to generate the HTML. Call that code from the server when you open the page, and when you need to do a live update, do an AJAX request to that handler so you don't have to repeat the code in the client.
What's your best strategy to combine the javascript-based and server-sided HTML generation?
If you want to stay DRY, don't try to combine them. Stick with generating the HTML only on the server (clearly the preferable option for SEO), or only on the client.
Make a page which generates the HTML on the server and returns it, e.g.:
http://example.com/serverstuff/generaterows?x=0&y=foo
If you need it on the server, access that link, or call the subroutine that accessing the link calls. If you need it on the client, access that link with AJAX, which will end up calling the same server code.
Or am I missing something? (I'm not sure what you mean by "generated by AJAX").
I don't see another solution if you have two different languages. Either you have a PHP/RoR/whatever to JavaScript compiler (so you have source written in one language and automatically generated in the others), or you have one generate output that the other reads in.
Load the page without any rows/data.
And then run your Ajax routines to fetch the data first time on page load
and then subsequently fetch updates/new records as and when required/as decided by your code.
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.