How to link JS route var and Symfony 2 URLs - javascript

I would like to know what is the most flexible solution to link SF2 routes & a JS var which is containing the routes.
For static routes, I don't have any problems, but when I want to connect URL with parameters, i did not find any solution (not hard-coded).
How can I do if I edit the routing.yml file, Dynamics URL on change
I'm using var url = "domain.com/path/to/url/with/" + token + "/and/" + name for generating but it is not flexible.
I know that twig generated urls are server side etc...
Any solutions ?
Ex :
JS
var route = {
home : "{{ path("home") }}",
custom_route : "{{ path("my_custom_route") }}"
}
Routing.yml
my_custom_route:
pattern: /path/to/url/with/{token}/and/{name}
defaults: { _controller: "SupboxCloudBundle:Public:file" }

I think you could try FOSJSRoutingBundle.

Well, this sort of depends on the result you are trying to achieve. Are you doing this in some sort of JS app?
If it were me, I would render the routes, or route parameters in the DOM. I wouldn't mess with rendering anything in the JS and I would make the JS code abstract.
For instance:
<div data-custom="{{ path("my_custom_route") }}"></div>
<div data-home="{{ path('home') }}"
or
whatever
then you can grab your routes in JS when needed (from the first example):
var route = {
home: $('div[data-home]').data('home'),
custom_route: $('div[data-custom]').data('custom')
}
This is a little messy as I'm just trying to show you a concept. However your actual implementation would depend on the actual result you are trying to achieve.
If you comment a more specific intent below I will provide a better solution for you.

Related

Serve dynamic javascript file with nodejs

Questions
How to serve javascript file dynamically? Specifically, the scripts maintain most of its body but with some variables changable (imagine HTML Jade template, but this is for pure javascript).
Scenario
When user or browser (http GET in general) visits /file.js passing parameter api, e.g. /file.js?api=123456, I would like to output pure javascript where I can take that 123456 and put in inside of my code, dynamically. Content-Type is application/javascript.
Sample:
var api = #{req.query.api}; //Pseudo
//The rest of my javascripts template
...
From my main .js file, I have set up the route:
app.get( '/file.js', function( req, res ) {
//Pseudo code that I would like to achieve
var name = req.query.name;
res.render( 'out_put_javascript_file_from_jade_file.jade', { name: name } );
});
So when a person visits /file.js, the script file will be rendered differently based on the parameter api passed in the URL. The only possible dynamic way I can think of is using Jade, but it doesn't allow pure javascript template. I believe there must be other solutions.
Please excuse my explanation. The problem is somewhat like this: How to generate a pure JavaScript file with Jade
If you want to do something quick and dirty, then you can do something like this (based on your example in the comments).
App init - read the .js template file and cache it:
// this should be async, but hey, not teaching you that part here yet
var fileJs = fs.readFileSync('file.js.template');
File.js:
(function() {
$(window).on('load', function() {
alert('Your api key is API_KEY_CONST');
});
})();
Request:
GET /api/file.js?key=123
Router:
app.get('/api/file.js', function(req, res) {
var key = req.query.key;
var key = fetchKeyFromDBSync(); // just to make it easier here, no async.
var out = fileJs.replace(API_KEY_CONST, key);
res.setHeader('content-type', 'text/javascript');
res.write(out);
res.end();
});
Now, this is really dumb and you should not try it at home, but it simply demonstrates how to do what you wanted.
Edit:
Depending on the file length, you might perform a bit better if you put the chunks of the file into an array, like:
var fileChunks = ['(function(){ blablabla;', 'var myAPIKey=', 'KEY_PLACEHOLDER', '; alert (myAPIKey);', '})()']
So later when you're resolving it with the real API key, you join the file.
fileChunks[2] = '12345';
var responseData = fileChunks.join('');
res.write(responseData);
But your last-accessed api key is then held in an array. Not quite future proof, but it shouls work if you need something quick.

How to manipulate HTML table once it's returned from backend like Node.js?

Here's the situation: I use Node.js as my backend, and use markdown to edit and post my blog article. And when a client requests the specific URL, such as http://www.example.com/blog/article_1, I returned the blog contents from Node.js with some template like ejs, which would be something like the follows:
app.get("/blog/article1", function(req, res) {
var article = something // this is a valid HTML converted from a markdown file
res.render("article1", {
title: "my blog article 1",
article: article
});
});
In the above code, I render article.ejs with title and article variable. The article variable is a valid HTML to be injected to the ejs template. So far, it' fine.
However, if I want to display a HTML table which is written in the original markdown file, with Bootstrap 3's responsive table functionality, (i.e. <div class="table-responsive"><table class="table">...actual table...</table></div>), how can I do it? Right now the table in my markdown file is just a markdown file, and I don't think that it's the best idea to just modify all of my markdown files on which I insert or wrap with the <div class="table-responsive">...</div> line; the files might also be used in a situation other than Bootstrap.
In other words, is it feasible to dynamically or programmatically inject the responsive functionality to the table once the template is returned by Node.js? And is it also feasible to inject the responsive table functionality selectively? (in other words choose arbitrarily some tables that I want to add the responsive function?)
Continuing on from the comments: It's actually not that difficult to fork and modify a project. The faster you can get used to working with open source libraries the better your experience will be with Node. Things move pretty quickly in the Node world, and sometimes things won't work like they are expected to. You can either wait around for a fix, or roll up your sleeves and pitch in.
I found a way to update the markdown templates using their addTemplate method. However the version of Marked the project is using (2.8) doesn't support custom templates. I've forked the repository and updated the version of marked as well as fixed the issues this caused with the tests. I also added a restriction to prevent it from using Express 4 which breaks all the tests. I submitted these as a pull request to the original repo, but in the mean time you could use my version to write something like the following.
untested
var
express = require('express'),
app = express(),
Poet = require('poet'),
marked = require('marked'),
renderer = new marked.Renderer();
renderer.table = function(header, body) {
return '<div class="table-responsive"><table class="table">' + header + body + '</table></div>';
}
var poet = Poet(app, {
posts: './_posts/',
postsPerPage: 5,
metaFormat: 'json'
});
poet.addTemplate({ ext: 'markdown', fn: function(s) {
return marked(s);
}});
Alternatively, if all you're using poet for is the markdown conversion, you might as well use marked directly and cut out the dependency on poet.

Django get last GET parameter

I've been working with Django for a few months now so I'm still new at it.
I want to get the last GET parameter from the URL. Here is and example of the URL:
example.com?q=Something&filter1=Test&filter1=New&filter2=Web&filter3=Mine
Is there a way to get the last inserted GET parameter with django? It could be filter1, filter2 or filter3..
Maybe there is a way to do this after the initial refresh with javascript/jQuery?
Thanks!
You can try to parse url parameters yourself. For example:
Python/Django
from urlparse import urlparse, parse_qsl
full_url = ''.join([request.path, '?', request.META['QUERY_STRING']])
#example.com?q=Something&filter1=Test&filter1=New&filter2=Web&filter3=Mine
parameters = parse_qsl(urlparse(full_url)[4])
#[(u'q', u'Something'), (u'filter1', u'Test'), (u'filter1', u'New'), (u'filter2', u'Web'), (u'filter3', u'Mine')]
last_parameter = parameters[-1]
#(u'filter3', u'Mine')
Javascript
var params = window.location.search.split("&");
//["?q=Something", "filter1=Test", "filter1=New", "filter2=Web", "filter3=Mine"]
var last_param = params[params.length-1].replace("?","").split("=");
//["filter3", "Mine"]
This example do not use jQuery and provides basic knowledge of url parsing. There are a lot of libraries, that can do it for you.

How to generate seperate RESTful urls for edit and update in Backbone js model?

I'm following Jame Yu's Backbone tutorial here to create my own app. Below is my model. I wonder if there's a way to generate separate urls for edit and update (RESTful) instead of just 1 as in the tutorial. I use Rails on the back end. Thanks.
var BusinessCard = Backbone.Model.extend({
url : function() {
var base = 'business_cards';
if (this.isNew()) return 'backbone/' + base;
return 'backbone/' + base + (base.charAt(base.length = 1) == '/' ? '' : '/')
+ this.id;
}
})
You are missing the point of REST...the fact that there is one URI which responds to different verbs from the uniform interface (GET, POST, PUT, DELETE), makes it restful. So Backbone is actually being RESTful, while you're not.
The default backbone sync method works exactly how you want it to already by appending the models id to the url when performing an update.
If you need to customize how data is sent to your server I've found the best thing is to create your own backbone sync. Here is an example of how I do it to wrap my create and update requests in a root json object: https://github.com/codebrew/rails3-backbone-coffeescript/blob/master/app/coffeescripts/lib/mongo_model.coffee

How should I handle Asp.net MVC URLs in javascript calls?

I am attempting to write a javascript heavy portion of my Asp.net MVC Web App (this portion of the website is a RIA using Extjs). However, I have come up to a standstill at the correct way to handle URLs in the javascript.
For example, right now I have an Ajax call to the List action in the ObjectsController, which resides in the Reading area. The List action takes a parameter of documentId (int). As of right now, this maps to /Reading/Objects/List since I have no changed routing yet (the site is too young at the moment to finalize routes). Normally in a view, to put this URL in a string I would do #Html.Action("List", "Objects", new { area = "Reading", documentId = 3).
However, this doesn't work when dealing with javascript, since javascript isn't parsed by a viewengine.
To get around this, I have a very small view that returns javascript constants, such as URLs, that is loaded prior to my main application's js files. The issue is that I can't call Html.Action for this action because at constant creation time I (obviously) do not know what documentId the ajax calls are going to be, and if you exclude documentId from the Html.Action call an exception occurs. The documentId could change during the normal workflow of the application.
How do I handle this? I don't want to hardcode the URL to /Reading/Objects/List because if I change my routing for this (for a more user friendly json API), or this web app isn't hosted on the root of the domain, the URL will no longer be valid.
How does everyone else handle MVC URLs in their javascript calls?
Here's a safe technique that I've been using. Even if your route changes, your JavaScript will automatically conform to the new route:
<script>
var url = '#Url.Action("List", "Objects", new { area = "Reading", documentId = "_documentId_")';
var id = 100;
var finalUrl = url.replace('_documentId_', id);
</script>
"_documentId_" is essentially a dummy placeholder. Then inside my JavaScript, I replace "_documentId_" with the proper id value once I know what it is. This way, regardless of how your route is configured, your URL will conform.
Update: Dec 20
I just saw this interesting blog post. The author built a library that allows you to build routes inside of your JavaScript file with intellisense support in VisualStudio.
http://weblogs.asp.net/zowens/archive/2010/12/20/asp-net-mvc-javascript-routing.aspx
Personally I use unobtrusive javascript and avoid mixing markup with javascript. AJAX calls are normally triggered by clicking on some buttons or links:
#Html.ActionLink("click me", "List", "Objects",
new { area = "Reading", documentId = 3 }, new { id = "foo" })
and then in a separate js file I would attach and handle the onclick event (example with jquery):
$(function() {
$('#foo').click(function() {
$('#resultDiv').load(this.href);
return false;
});
});
As you can I didn't need to use any hardcoded URL in my javascript file. URLs should always be handled by the routing engine and generated with html helpers.
If it was a <form> instead of a link I would simply handle the onsubmit event (the same way) and use the form's action attribute to get the URL.
UPDATE:
After pointing out in the comments section that the documentId is known only at client-side you could do this:
#Html.ActionLink("click me", "List", "Objects",
new { area = "Reading" }, new { id = "foo" })
And then:
$(function() {
$('#foo').click(function() {
$('#resultDiv').load(this.href, { documentId: '123' });
return false;
});
});
Turns out, this was all solved by using Url.Action() instead of Html.Action(). Url.Action() is (so far) allowing me to generate URLS without all of the parameters. I am assuming that this only works when the route does not specify the parameters in the target URL itself.

Categories

Resources