How to version MVC JavaScript includes [duplicate] - javascript

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
force browsers to get latest js and css files in asp.net application
I'm working with someone else's code, so I don't know the whole picture, and I don't even know MVC that well, but here's the problem...
In Site.Master there's a
<%= Html.IncludeJs("ProductPartial")%>
which produces this line in the final mark-up
<script type="text/javascript" src="/Scripts/release/ProductPartial.js"></script>
I made some changes in the JS file, but the old one is obviously cached by the browser, so the changes won't show up until the user refreshes. The usual workaround is to add a version tag at the end of the script source path, but I'm not sure how to do that in this case.
Any suggestions?

Why not write your own Html helper extension method, and make it output the version number of your application assembly? Something along these lines should do the trick:
public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename)
{
var version = Assembly.GetExecutingAssembly().GetName().Version;
return MvcHtmlString.Create(filename + "?v=" + version);
}
You can then increment the version number of the assembly whenever you release a new version to your users, and their caches will be invalidated across the application.

I solved this by tacking a last modified timestamp as a query parameter to the scripts.
I did this with an extension method, and using it in my CSHTML files. Note: this implementation caches the timestamp for 1 minute so we don't thrash the disk quite so much.
Here is the extension method:
public static class JavascriptExtension {
public static MvcHtmlString IncludeVersionedJs(this HtmlHelper helper, string filename) {
string version = GetVersion(helper, filename);
return MvcHtmlString.Create("<script type='text/javascript' src='" + filename + version + "'></script>");
}
private static string GetVersion(this HtmlHelper helper, string filename)
{
var context = helper.ViewContext.RequestContext.HttpContext;
if (context.Cache[filename] == null) {
var physicalPath = context.Server.MapPath(filename);
var version = "?v=" +
new System.IO.FileInfo(physicalPath).LastWriteTime
.ToString("yyyyMMddhhmmss");
context.Cache.Add(physicalPath, version, null,
DateTime.Now.AddMinutes(1), TimeSpan.Zero,
CacheItemPriority.Normal, null);
context.Cache[physicalPath] = version;
return version;
}
else {
return context.Cache[filename] as string;
}
}
And then in the CSHTML page:
#Html.IncludeVersionedJs("/MyJavascriptFile.js")
In the rendered HTML, this appears as:
<script type='text/javascript' src='/MyJavascriptFile.ks?20111129120000'></script>

Here are some links already on this topic:
Why do some websites access specific versions of a CSS or JavaScript file using GET parameters?
force browsers to get latest js and css files in asp.net application

Your version strategy really isn't important. As long as the file name is different, the browser will be forced to get the new script. So even this would work:
<%= Html.IncludeJs("ProductPartialv1")%>
ProductPartialv1.js
I have been using this technique for important JavaScript and CSS changes (CSS is also cached by the browser) - so I update the template to use the newer version and I'm safe in the knowledge that if the new HTML is used, so is the new script and CSS file.
It is "in action" on http://www.the-mag.me.uk/ - where I just increment a numeric suffix on the files.

It turns out IncludeJs is a helper method for automatically including compressed JS files when in release mode: LINK.
So I just have to modify that method a bit to include a version number. Sorry about the confusion.

Related

Call a Java Function using Browser's Client Side JavaScript

Good morning!
I have been working on a client side browser based app using JavaScript that (all of a sudden) needs the capability to save and load files locally.
The saved files are plain text (.txt) files.
I have managed to get JavaScript to read existing text files. However, I am unable to find reliable information on how to create and edit the contents of these files.
Based on what I see online, I am under the impression that you can't do this with JavaScript alone.
I found out from another source that the best way to do this is outsource the file writing/editing to a Java file and let Java do the work.
I found a code snippet and tweaked it around a bit, but it is not working and I seem to be at a loss:
JAVASCRIPT
<!Doctype html>
<html>
<OBJECT ID="Test" height=0 width=0
CLASSID="CLSID:18F79884-E141-49E4-AB97-99FF47F71C9E" CODEBASE="JavaApplication2/src/TestJava.java" VIEWASTEXT>
</OBJECT>
<script language="Javascript">
var Installed;
Installed = false;
try
{
if (Test==null)
Installed = false;
else
Installed = true;
}
catch (e)
{
Installed = false;
}
alert ("Installed :- " + Installed);
TestStr = Test.SendStr("Basil");
alert (TestStr);
</script>
</html>
JAVA
import javax.swing.*;
public class TestJava {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
}
public String SendStr(String lStr)
{
return lStr + "!!!";
}
}
If someone could point me in the right direction or even just explain why this isn't working, I would appreciate it.
I believe the sandbox issue prevents all browsers from performing any and all local file writing, without an enormous amount of working around the access restrictions. It is easier to write files remotely on the server than to write them locally to the client. This is true across all browsers.
So while it may be possible to perform the load function, you cannot perform the 'save' function on the local machine.

CakePHP controller function with parameters doesn't show javascript

When I'm using controller function with parameters the rendered view just seems to forget every included .js files.
public function view($id = null) {
if(!$id) {
throw new NotFoundException(__('Invalid post'));
}
$post = $this->Post->findById($id);
if(!$post) {
throw new NotFoundException(__('Invalid post'));
}
$this->set('post', $post);
}
If I take parameters away and put variable '$id = 1' on function the view with postID 1 renders okay in 'posts/view'.
I included javascript files to default.ctp in traditional way:
echo "script type='text/javascript' SRC='../js/jquery-1.9.1.min.js'></script>";);
(it includes '<' but this text editor won't me type it for safety reasons I guess)
I don't have knowledge about 'js helpers' of cakePHP. Can't I use javascript in traditional way?
Site renders okay in every other view (e.g. posts/add) and .js files are included in source code of 'posts/view/1'
The problem
You're using relative paths to the javascript;
<script src='../js/jquery-1.9.1.min.js'></script>
In this url, ../ means '1 directory up from the current location`, so when you're currently visiting this URL;
http://mysite.com/home/
Then your browser will correctly try to load the script from;
http://mysite.com/js/jquery-1.9.1.min.js
However, if you're visiting this url;
http://mysite.com/home/and/some/more/
Then the browser will look for the JavaScript here:
http://mysite.com/home/and/some/js/jquery-1.9.1.min.js
How to fix the problem
Use absolute paths for all 'assets' (CSS, JavaScript, Images);
src='/js/jquery-1.9.1.min.js'
Output the script-tags using CakePHP Helpers (after all, that's what they are meant for: to simplify your work :), e.g. echo $this->Html->script('jquery-1.9.1.min');

JScript: Dynamically load JavaScript libraries

I am currently writing a JavaScript script for the Microsoft JScript Runtime Environment. It's not in a browser, but rather going to be run more like a SysAdmin would use VBScript. I've written a lot of code, and while some of it is specific for what needs to be accomplished, a majority of it is supporting framework for the script to do what it needs to do. I'd like to use this sum of code in other future scripting adventures, but as to my current knowledge, I would have to copy and paste these mini-libraries over and over again, and well, that's just an update nightmare for one and two, it's inefficient. I know it's possible to dynamically load JS when I have a window or document, I know it's possible to require() JS files in Node.js, but is this possible in the raw JScript Runtime for MS?
Look into the Windows Script File (*.wsf) format. One of its features is to allow for includes like you're describing. An example taken from the linked documentation:
<job id="IncludeExample">
<script language="JScript" src="FSO.JS"/>
<script language="VBScript">
' Get the free space for drive C.
s = GetFreeSpace("c:")
WScript.Echo s
</script>
</job>
where "FSO.JS" contains the JScript library.
Assuming your talking about the WSH, you can load a file and eval the contents, which is much the same as including it.
var incfso=new ActiveXObject("Scripting.FileSystemObject");
include = function(x) {
eval(incfso.OpenTextFile(x,1).ReadAll());
}
source: http://www.mailsend-online.com/blog/wsh-javascript-includes.html
I couldn't find a global object like "window" for jscript, but you can sort of create one.
var host = this;
var test = "hello-world";
var messagebox = new ActiveXObject("wscript.shell");
if (host.test) {
messagebox.Popup("host.test exists, value = " + host.test);
} else {
messagebox.Popup("host.test does not exist.");
}
I think "host" should now effectively be the global object. (the example works for me anyway)

How to add different Javascript in development and production wicket

I have a wicket application in which I have added the javascript files within the markup html:
<script src="script/jquery.min.js" type="text/javascript"></script>
My javascript files are not placed beside my .java or .html files, they are in different location in the server as can be seen on previous script declaration.
My question is: Is it possible to add these javascript files depending on the application mode? I.E. if the application is in development mode, load one javascript file, if it is in production load this other one.
Thanks!
PS: the idea is to load "min" version on production but the extended files on development so debugging becomes posible
NOTE: Watching different answers here I re-state: the problem is not finding when the wicket app is in development or deployment mode, I know that, but is about how to change html markup or adding different JavaScript resources
extendig the answer of #rotsch you can do it in wicket 1.5 with :
#Override
public void renderHead(IHeaderResponse response) {
if(DEVELOPMENT)
response.renderString("<script type=\"text/javascript\" src=\"url1\"></script>");
else
response.renderString("<script type=\"text/javascript\" src=\"url2\"></script>");
}
https://cwiki.apache.org/WICKET/migration-to-wicket-15.html#MigrationtoWicket1.5-RemovedHeaderContributorandfriends.
You can find out in which mode you are with the following code:
RuntimeConfigurationType.DEPLOYMENT.equals(getApplication().getConfigurationType())
or
RuntimeConfigurationType.DEVELOPMENT.equals(getApplication().getConfigurationType())
I use this directory layout:
resources
|---JQueryResource.java
|---jquery-1.6.4.js
|---jquery-1.6.4.min.js
With this class:
public class JQueryResource {
/**
* Must be called in a RequestCycle.
*
* #return Url for the jQuery library.
*/
public static String getURL() {
if (Application.get().usesDevelopmentConfig()) {
Url url =
RequestCycle.get().mapUrlFor(
new PackageResourceReference(JQueryResource.class, "jquery-1.6.4.js"),
null);
return url.toString();
} else {
Url url =
RequestCycle.get().mapUrlFor(
new PackageResourceReference(JQueryResource.class,
"jquery-1.6.4.min.js"), null);
return url.toString();
}
}
}
This is how I add the resource to my page.
#Override
public void renderHead(IHeaderResponse a_response) {
a_response.renderJavaScriptReference(JQueryResource.getURL());
}
You could use pack:tag to compress all your resources: http://sourceforge.net/projects/packtag/
In your web.xml/.properties file you can specify whether to pack it or not depending on your production mode.
I set a property in a properties file with I add to the path when starting the VM.
Then I do a if else similar to the PHP answer.

Tag images in the image itself? HOW-TO

How to tag images in the image itself in a web page?
I know Taggify, but... is there other options?
Orkut also does it to tag people faces... How is it done?
Anyone knows any public framework that is able to do it?
See a sample bellow from Taggify:
I know this isn't javascript but C# 3.0 has an API for doing this. The System.Windows.Media.Imaging namespace has a class called BitmapMetadata which can be used to read and write image metadata (which is stored in the image itself). Here is a method for retrieving the metadata for an image given a file path:
public static BitmapMetadata GetMetaData(string path)
{
using (Stream s = new System.IO.FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
var decoder = BitmapDecoder.Create(s, BitmapCreateOptions.None, BitmapCacheOption.OnDemand);
var frame = decoder.Frames.FirstOrDefault();
if (frame != null)
{
return frame.Metadata as BitmapMetadata;
}
return null;
}
}
The BitmapMetadata class has a property for tags as well as other common image metadata. To save metadata back to the image, you can use the InPlaceBitmapMetadataWriter Class.
There's a map tag in HTML that could be used in conjunction with Javascript to 'tag' different parts of an image.
You can see the details here.
I will re-activate this question and help a bit. Currently the only thing i have found about is http://www.sanisoft.com/downloads/imgnotes-0.2/example.html . A jQuery tagging implementation. If anyone knows about another way please tell us.
;)
You can check out Image.InfoCards (IIC) at http://www.imageinfocards.com . With the IIC meta-data utilities you can add meta-data in very user-friendly groups called "cards".
The supplied utilities (including a Java applet) allow you to tag GIF's, JPEG's and PNG's without changing them visually.
IIC is presently proprietary but there are plans to make it an open protocol in Q1 2009.
The difference between IIC and others like IPTC/DIG35/DublinCore/etc is that it is much more consumer-centric and doesn't require a CS degree to understand and use it...

Categories

Resources