Passing javascript variable to velocity variable templete - velocity

I have installed xwiki successfully and able to generate wiki pages using velocity template language.
Could anyone please tell me that how can I pass javascript varible to velocity templete. I have gone through few forums that I need to pass the parameter to server to get this but I have no idea. Please find the files below.
<script type="text/javascript">
function generateFunction()
{
var variable = document.getElementById('text').value;
}
</script>
#set($test = "variable")
$test

You have to make an ajax call from the client to the server.If you're using jquery, you would have something like:
$.post('/send/my/var', { 'variable' : value });
Without jquery, see this XmlHttpRequest documentation.
And then, on the server side, the /send/my/var URL should reach a template where you can do:
#set($test = $params.variable)
And you would do something useful with it on the server-side, like store it in the session, in the database, etc.
If you need to send back something from Velocity to Javascript, then you'll typically have to format JSON code, and add an asynchronous completion callback parameter to the ajax call:
$.post('/send/my/var', { 'variable' : value },
function(data)
{
// do something with data sent back from the server
});
It's also possible to have synchronous calls, that is to have javascript wait for the server response, but it's generally a bad idea to do so and I won't extrapolate on it here.
As a final note, you should also implement a proper error handling. With jQuery for instance, the syntax would be:
$(document).ajaxError(function(event, jqxhr, settings, message)
{
console.log(message);
});

It can't be done,
Apache Velocity template is a server side engine,
Meaning that on the server, Velocity will get the template and try to render, only after it finished to render the template, it will be returned to client which will execute client code as Javascript
Velocity alternative is freemarker, which I found similar question and answer , Question:
How to call freemarker function with param from javascript
Answer:
There's no way for the client side web browser code to call a server side Freemarker function

Related

Pass data across Hapi JS application

I want to detect current selected language from a domain (like es.domain.com, de.domain.com) so I need to pass it to all non static route handlers and to all views.
To detect a language I need a request object. But global view context it is possible to update where request object is not accessible (in server.views({})). Also server.bind (to pass data to route handler) works only where request object is not accessible.
Hapi version: 11.1.2
You could try something like this:
server.ext('onPreResponse', function (request, reply) {
if (request.response.variety === 'view') {
request.response.source.context.lang = request.path;
}
reply.continue();
});
This will attach a lang data point to the context that is being sent into the view. You'll have to extract the lang from the url as request.path is probably not what you actually want.
Also, if you look here you'll see a few pieces of request data is made available to every view via reply.view() If the locale/language is available directly in one of those data points, or can be derived from them, you can skip the extension point approach entirely.
Again, this is assuming version 10+ of hapi. If you're using an older version, the extension point method is your best bet.

Intercept Requests With Custom Responses in PhantomJS?

Is there a way to intercept a resource request and give it a response directly from the handler? Something like this:
page.onRequest(function(request){
request.reply({data: 123});
});
My use case is for using PhantomJS to render a page that makes calls to my API. In order to avoid authentication issues, I'd like to intercept all http requests to the API and return the responses manually, without making the actual http request.
onResourceRequest almost does this, but doesn't have any modification capabilities.
Possibilities that I see:
I could store the page as a Handlebars template, and render the data into the page and pass it off as the raw html to PhantomJS (instead of a URL). While this would work, it would make changes difficult since I'd have to write the data layer for each webpage, and the webpages couldn't stand alone.
I could redirect to localhost, and have a server there that listens and responds to the requests. This assumes that it would be ok to have an open, un-authenticated version of the API on localhost.
Add the data via page.evaluate to the page's global window object. This has the same problems as #1: I'd need to know a-priori what data the page needs, and write server side code unique to each page.
I recently needed to do this when generating pdfs with phantom js.
It's slightly hacky, but seems to work.
var page = require('webpage').create(),
server = require('webserver').create(),
totallyRandomPortnumber = 29522,
...
//in my actual code, totallyRandomPortnumber is created by a java application,
//because phantomjs will report the port in use as '0' when listening to a random port
//thereby preventing its reuse in page.onResourceRequested...
server.listen(totallyRandomPortnumber, function(request, response) {
response.statusCode = 200;
response.setHeader('Content-Type', 'application/json;charset=UTF-8');
response.write(JSON.stringify({data: 'somevalue'}));
response.close();
});
page.onResourceRequested = function(requestData, networkRequest) {
if(requestData.url.indexOf('interceptme') != -1) {
networkRequest.changeUrl('http://localhost:' + totallyRandomPortnumber);
}
};
In my actual application I'm sending some data to phantomjs to overwrite request/responses, so I'm doing more checking on urls both in server.listen and page.onResourceRequested.
This feels like a poor-mans-interceptor, but it should get you (or whoever this may concern) going.

intern test not using configured registry requestProvider in dojo

I'm following this article to mock response in dojo.
My mocker is very similar to the one in the article except this:
registry.register(/\/testIntern/, function (url, options) {
return when({
value: "Hello World"
});
In my understanding, this should map to any request that contains "/testIntern" on the address.
My testcase is quite simple:
// similar to example
var testRest= new Rest("/testIntern", true);
testRest("").then(lang.hitch(this, function (data) {
assert.deepEqual("Hello World", data.value, "Expected 'Hello World', but got" + data.value);
}));
It really should be quite simple. But when I run this test, I got 404 Not Found. It looks like the REST call in the test doesn't try to use the mocking service. Why?
You are generally correct in your thought that registering a URL with dojo/request/registry should pass anything referencing that URL via dojo/request through your handler.
Unfortunately, dojo/store/JsonRest uses the dojo/_base/xhr module which uses dojo/request/xhr directly, not dojo/request. Any registrations created with dojo/request/registry (and any setting of defaultProvider) will unfortunately be lost on JsonRest.
You might want to have a look at dstore - its Rest store implements the same server requests as dojo/store/JsonRest but it uses dojo/request instead of being hard-coded to a specific provider. (dojo/request defaults to dojo/request/xhr in browsers anyway, but can be overridden via dojoConfig.requestProvider.) dstore contains adapters for translating between dstore's API and the dojo/store API, if you need to use it with widgets that operate with the latter.

Mocking out AJAX calls with Dojo XHR

I'm attempting to mock the response of a dojo xhr request, but I haven't found a good solution.
Ideally, I'd like to see a solution similar to the jQuery mockjax plugin where I can set a specific call based on a url, e.g.:
$.mockjax({
url: '/restful/fortune',
responseTime: 750,
responseText: {
status: 'success',
fortune: 'Are you a turtle?'
}
});
My initial thought was to utilize the "/dojo/io/send" channel, but I haven't been able to get a modified response to be loaded after modifying the dojo Deferred object.
The other thought is to use a pass-through method that would determine if an actual xhr request should be made, e.g.:
function xhrRequest(xhrArgs) {
if(shouldMock) {
var fakeReturnJson = dojo.toJson({
howdy: "that's odd!",
isStrange: false
});
return fakeReturnJson;
} else {
dojo.xhr(xhrArgs);
}
}
Can someone tell me the best way to go about mocking dojo xhr calls?
Thanks!
It's an old question, but I think you should do your mocking using Sinon.js
However you will need to put the following:
has: { native-xhr2: false }
into your dojoConfig for it to work in 1.8
I haven't heard of any Dojo specific libraries similar to Mockjax. But what I think you could try is use Mockjax with Dojo. This should be pretty easy to do since all you'll have to do is use JQuery during development only for testing with Mockjax and then remove it once development is complete.
I use your second suggestion. Currently, I have a transport layer (simple js class) and 2 implementations (XhrTransport and MockTransport). I then switch in which I need without changing the widget code.
Widgets call the server with:
Controller.send(aServerCall);
where aServerCall is a simple value object with the server endpoint, params and callback.
This way, you can add nice things to the controller that will apply to all server calls (such as logging, analytics, generic error handling...) and also mock out the entire server when doing unit tests.
For the MockTransport, I simply return canned json data from static .js files in the format that the widget expects.

dojo.xhrGet or dojo.xhrPost

I'm very new at this, in fact this is my first Dojo attempt. I'm trying to get data from a website with:
<script
text="text/javascript"
src="http://o.aolcdn.com/dojo/1.3/dojo/dojo.xd.js"
djConfig="parseOnLoad:true,isDebug:true"
></script>
<script type="text/javascript">
//How are we supposed to know what else to include in the dojo thing? like query?
dojo.addOnLoad(function(){
console.log("hi");
dojo.xhrPost({
url: "http://www.scrapbookingsuppliesrus.com/catalog/layout", //who knows how to set relative urls?
handleAs: "json", //get json data from server
load: function(response, ioArgs){
console.log("got");
console.log(response); //helps with the debugging
return response; //that way goods should be a very large array of the data we want
},
error: function(response, ioArgs){
console.log("nope didn't make it", response+' '+ioArgs); //helps with the debugging
return response; //who knows what this does
} //last item, thus no extra comma
});
});
</script>
But nothing happens. While I'm at it, what exactly is the response and ioArgs variables. They're supposed to magically be the response to the request that I guess is specially defined already. But, who knows. Further, I figured after every attempt it would trigger something in load or error, but alas.
There used to be an error that I was going to a prohibited uri, but then firebug would reference a very large dojo script where it was impossible to tell why it was broken. What environment are the rest of you developing on?
Well, there are a couple of issues.
Lets start with the very easy ones first.
When you are developing you want to use the "uncompressed" version of Dojo, which can be found by appending .uncompressed.js to the path of the Dojo library being used:
http://o.aolcdn.com/dojo/1.3/dojo/dojo.xd.js.uncompressed.js
This will make it much easier to see what breaks, if it is in core-Dojo that is.
Next, the djConfig parameter. I'm quite certain that Dojo can handle a string, but traditionally it has been defined with an object, so, once you've included your Dojo library:
<script src="path to dojo"></script>
Start a new script block and define the djConfig object in there:
<script>
djConfig = {
parseOnLoad: true,
isDebug: true
};
</script>
Next simplest, I use IntelliJ JIDEA to develop, it has build-in code-sense for Dojo, makes life much easier. Otherwise, the standard package, Firefox + Firebug.
The complex stuff:
It seems that you are requesting data using the XHR method, hopefully you are aware that this means that your script and the data being accessed must reside on the same domain, if they don't you'll have security errors. How can this be solved? you use the technique called cross-domain scripting, which dojo also supports via the dojo.io.script.get functionality.
The more complex stuff:
Dojo works with something called "Deferred" objects. That means that the request doesn't actually go out as soon as the object is created, rather it goes out when you ask it to go out, that's the concept of "Deferred", you defer the execution of a block of code to a later time. The way this problem would then be solvedin your case is like this:
var deferred = dojo.xhrPost({
url: "http://www.scrapbookingsuppliesrus.com/catalog/layout", //who knows how to set relative urls?
handleAs: "json" //get json data from server
});
if(deferred) {
deferred.addCallback(function(response){
console.log("got");
console.log(response); //helps with the debugging
return response; //that way goods should be a very large array of the data we want
});
deferred.addErrback(function(response){
console.log("nope didn't make it", response+' '+ioArgs); //helps with the debugging
return response; //who knows what this does
});
}
And this should work out now.
As a personal note, i would not recommend using XHR but rather the dojo.io.script.get methodology, which over the long term is much more portable.
There where several very basic errors in your code.
<script ... djConfig="parseOnLoad:true,isDebug:true"/></script>
Here you use the short form of the script tag /> (which is forbidden) and at the same include the closing </script> too.
console.log("hi")
There is a semi-colon missing at the end of the statement
You try to load data from http://www.scrapbookingsuppliesrus.com/catalog/layout is your script also running on that domain? Else the security restrictions on Crossdomain-Ajax (google it) will prevent you from loading the data.
This question was also asked on the dojo-interest list and there are a few replies to the question on that list.
If your page is being served from www.scrapbookingsuppliesrus.com, then the code you've posted looks correct. The way you declare djConfig will work, and specifying load and error in the argument to xhrGet is correct. You're going to have dig in and debug.
Take a look in Firebug's Console window. You should see the GET request, complete with request and response HTTP headers, and the response text. If you don't see it, then I suspect something else has gone wrong before your onLoad function from being called - I'd throw a console.log at the top of that too. If your onLoad function isn't getting called, you may want to click the little down arrow in the Script tab and set "Break on all errors"
As to what the response and ioArgs are.
Response is, well, the response. If the request was successful, it will be the JSON object (or XML DOM object, or HTML DOM object, or text, depending on handleAs). If the request failed, it will contain an object with details about the error.
ioArgs is an object that includes a slew of lower-level details about the xhr request. As an asice, I've found that if you attach a callback to the deferred returned by xhrGet:
var dfd = dojo.xhrGet(args);
dfd.addCallbacks(function(response) {...}, function(error){...});
then the callback is not passed the ioArgs argument, just the response (or error).
dojocampus.org is the official dojo documentation site, and includes a lot of detail and examples.
Dojo: The Definitive Guide from O'Reilly is an excellent book. If you're going to be doing a lot of dojo dev., it's a great resource.
First, let's start with the basics, then you can add all the functionality.
You only need this to implement Ajax (take advantage of Dojo):
function sendData(dataToPost) {
dojo.xhrPost({
url: "http://myUrl.html",
postData: "data="+dataToPost,
handleAs: "text",
load: function(text){
getData(text);
},
error: function(error){
alert(error);
}
});
}
Now you can use the data in your "getData" function
function getData(text){
myVariable = text;
}
You can find many tutorials to see how it's implemented. This is the most complete example that I found, here you can see how it's implemented and all the code is available:
http://www.ibm.com/developerworks/java/library/j-hangman-app/index.html