I'm working on a Rails 3.1 app using JavascriptMVC and ejs templates within the client to do some complicated features on my application. Unfortunately ejs syntax is very similar to erb syntax, to the point where I can't keep the code in the same file (although if someone knows of a good way to do this, I'd be ecstatic). Ultimately I want to be able to apply some rails code within the ejs template (say for I18n) but at this point I will just settle for getting this to work
Following the example from this question I have created a custom template handler that looks like this:
module CommonModel
class Handler < ActionView::Template::Handler
include ActionView::Template::Handlers::Compilable
def compile(template)
template.source.inspect
end
end
end
ActionView::Template.register_template_handler :ejs, CommonModel::Handler
Then I created a partial template that has my ejs code in it:
_jmvc_templates.html.ejs
<script type="text/ejs" id="my_ejs_template">
<div>Some ejs here</div>
</script>
Within my existing template, I attempt to include my partial:
<%= render 'path/to/my/ejs/templates/jmvc_templates' %>
At this point, the file is included and my handler is used, but everything is escaped, so my div in my template gets rendered to the page like this:
<div%gt;
I'm sure I'm missing something obvious here, but I don't know what it could be... How can I get this template handler to just include my ejs based template without escaping all of the html in it?
Edit:
I've found that calling render with html_safe works:
<%= render('path/to/my/ejs/templates/jmvc_templates').html_safe %>
This seems like a kludge though - there has to be a way to get the erb renderer to treat text from my handler as html safe text.
Maybee you should be using raw. Check this
def compile(template)
raw template.source.inspect
end
Related
My express router is making available an object on my ejs template called inventory.
My client side is doing a ajax request that returns an object called result.
I want to put the value of result object into my ejs tag. How can I do this?
<%= inventory["result[x].variation_identifier"].price %>
You cannot. The values inside the EJS tags are calculated and rendered as strings into the markup on page load. What I would suggest that you do is wrap this EJS in another element, then change that element's innerText in the callback of your AJAX request. In turn, I must advise you to avoid turning around and using hard-coded values in your markup to perform other calculations or requests.
I am trying to use a kendo MVC helper inside a template (remote template file loaded like: http://docs.kendoui.com/howto/load-templates-external-files#remote-templates. I have a controller that sends to the client the generated markup)
My template file is something like:
<script id="my-pager-template" type="text/x-kendo-template">
My pager
#(Html.Kendo().ListView<Business.Data.MyPage>()
.Name("myPagerListView")
.TagName("div")
.ClientTemplateId("my-pager-item-template")
.DataSource(dataSource => dataSource.Read(read =>
read.Action("GetMyPages","Page")
)
).ToClientTemplate())
</script>
<script id="my-pager-item-template" type="text/x-kendo-template" >
<div class="k-button" data-pager-item-pageid="${PageID}" data-pager-item-pagename="${Name}">
<span>${ButtonText}</span>
</div>
</script>
But the generated markup is giving me an Uncaught SyntaxError: Unexpected token < in my browser console (chrome).
The markup generated by the helper is like this:
<div id="myPagerListView"></div>
<script>
jQuery(function(){jQuery("\#myPagerListView").kendoListView({"dataSource":{"transport":{"prefix":"","read":{"url":"/Page/GetMyPages"}},"serverPaging":true,"serverSorting":true,"serverFiltering":true,"serverGrouping":true,"serverAggregates":true,"type":"aspnetmvc-ajax","filter":[],"schema":{"data":"Data","total":"Total","errors":"Errors","model":{"fields":{"PageID":{"type":"number"},"Name":{"type":"string"},"ButtonText":{"type":"string"}}}}},"template":kendo.template($('\#my-pager-item-template').html())});});
<\/script>
</script>
Can I use kendo helpers this way?
(In this post, it says that it can be used: Can I use Kendo MVC helpers inside templates?)
I got that message a lot of times, your code is fine, the problem comes retrieving the data, kendo deserialize what it recieves from read.Action("GetMyPages","Page"), you probably are retrieving an HTML page instead of a json, so it tries to serialize something like "<html ...." and here you got the error, just check the url on chrome to check if you recive an json
i mean check http://yourdomain.com/Pages/GetPages/ (or the routing according to your app), you probably get an HTML page
I had this exact issue also. I have come to realise (over the past 3 hours :( ) that this is because I was using ajax then the jquery html function to load the template file and that the error was happening with in jquery's function as it tried to parse than execute the template file which has been mangled for an unknown reason by kendo. (escaping that script tag and in my case inserting buttons in that space). Fortunatly when kendo Its self tries to use the template it does work.
To get around this problem I rendered the partial view directly on the page.
Hope this helps.
I use to work with MVC javascript framework such as Backbone or Angular, i would like to fully use express and there is something i don't know how to do.
When i used javascript client framework, i made AJAX GET calls to get my entities from express with res.send(), but only with the express rendering engine, how to get the entity you send with res.render('index', { User: { name: 'bob' }}) on the client side in your javascript code?
I tried on the client side to directly call:
<script>
console.log(JSON.stringify(User));
</script>
But i get a Uncaught ReferenceError: User is not defined
However, i can access the object in my html using ejs:
<h1><%= User.name %></h1>
I know how to get it in the html using the ejs view engine, but how to get it directly from the javascrit ?
Are you looking for something like client side rendering? Then RequireJS is the thing for you. res.send sends the data back to the client javascript framework and res.render renders a page or a template. Do let me know if you require something else.
Answering this much later, but I ran across this issue and had to work with it for quite a while before I got it, thought I would share for future visitors of this question.
Like V31 said earlier, res.render renders the template without passing the data first in JavaScript. The variables like <%= User.name %> only refer to their server-side definition as long as your EJS template is actually an EJS template -- which it stops being once it's been rendered as the page. As the Express docs say, render "returns the rendered HTML of a view." In other words, saying console.log(User.name) client-side is trying to access an object that only exists in the server.
You can get around this like this:
<script>
console.log('<%= JSON.stringify(User) %>');
</script>
With the quotes required around the <%= JSON.stringify(User) %> because this result will be a string rather than a variable -- you don't want your console.log treating the entire stringified user data as a variable, you just want to log it.
Taking this concept further, this is how one would make variables you're passing into your render accessible to client-side JavaScript files as well. For example, say you have a document.onLoad function that requires a variable from the server to decide whether or not to make a particular DOM manipulation.
<script>
const bob = '<%= User.name %>';
const alice = '<%= User.bestfriend %>';
</script>
<script src='/javascripts/myscript.js'></script>
myscript.js now has access to User.name and User.bestfriend as they were defined in the server's User object, and can use that data client-side in whatever manner you see fit.
I'm trying to save the following inside a textarea to one of my models:
<iframe width="560" height="315" src="http://www.youtube.com/watch?v=Ar7PxP76o28" frameborder="0" allowfullscreen></iframe>
However this is what it actually ends up saving:
<iframe width=\"560\" \r\nheight=\"315\" src=\"http://www.youtube.com/watch?v=Ar7PxP76o28\" \r\nframeborder=\"0\" allowfullscreen></iframe>
Is there any way I can prevent it from escaping the html? I'm trying to render a youtube embeded video inside of the show view using the following code:
= #foo.content.html_safe
However the html_safe helper doesn't seem to work if the html is escaped like this. I also tried swapping out html_safe with a raw wrapper but that didn't seem to work either.
As Zabba suggested there was actually a third-party involved that was causing this issue and not Rails itself. In my case I was using the Aloha WYSIWYG editor which was sanitizing any custom HTML that I added to my form without my permission.
I am using haml for creating views in rails. I want some of these views to also be available as javascript templates. What is the best way to do that without repeating myself?
I was hoping I can do something like this:
Create a haml view, e.g.
app/views/my_view.html.haml
and create a js template as:
app/assets/templates/my_view.js
And inside the js template, having something like:
//= Rails.views.render('my_view')
Is something like this possible?
You can use haml in a javascript thing if you want by putting it in a some_file.js.haml file.
For example, you can use .js.haml files as replacements for the js.erb files that might be used in a javascript call back to mess around with the page.