Writing EJS View helpers - backbone.js

I have a rails-backbone project that generates jst.ejs templates.
I'd like to include some view helpers within there, but I'm having a helluva time figuring out how to include either EJS or JST functions into that template file. If anyone could offer a very quick explanation of how to include a very basic function so that it can be read by an ejs.jst template I'd be very appreciative.
I've tried hacking into JST & EJS, plus just using bare javascript functions, but nothing is bringing any joy. Example attempt below:
Example:
# helpers.js.coffee
console.log('yes, this file is being called from the app')
helloWorld: () ->
console.log "Hello, world!"
# app/assets/javascripts/backbone/templates/project/new.jst.ejs
<%= helloWorld() %>
(Returns uncaught referenceError)
Any ideas appreciated. Cheers.

You might need to attach that to window, since coffeescript puts closures () around each .coffee file. A good example of how to deal with scoping issues is any popular js/coffee utility, like underscore.js. He uses var root = this and exports to conform to CommonJS practices and get his _ function out into the world where it can be used globally.
The book CoffeeScript: Accelerated JavaScript Development has a chapter (chapter 4) on this very topic, as well as it's just a damn good book on CoffeeScript. It explains a lot of where the modern world is at javascript-wise.

Related

How to uglify an angular project using grunt?

I'm trying to deploy a meanjs project but can't seem to figure out how to minify,concat&uglify the project using grunt.
What I've found out so far :
Need to run concat -> ngAnnotate -> uglify (else code won't run)
need to concat in dependency order (else it won't run)
With this logic I've managed to create a single 'uglified' version of the relevant 3rd party libraries (node modules), but I'm unable to do the same for the modules I've written.
I've tried using concat tools that are supposed to reorder the files according to dependencies (grunt-concat-in-order, grunt-concat-dependencies, grunt-concat-deps) but nothing helped. Just errors of missing modules/declarations.
I've tried reordering the js files that should be concatenated, and each time something else is missing and the site loads partially (at best).
reordering the files according to the order they appear in the compiled header doesn't help.
Is there something that concats Angular files according to their dependencies or or a general logic in which I should reorder them?
Thanks.
FOUND IT!
apparently JS and Angular are flexible with missing ';' in the end of module/directive declarations.
I've went through the entire code and added missing ';' in the appropriate places.
For example:
angular.module('core').filter('xyz', [function() {
.....
}])
Finally can go to sleep.
*original post:
Angular module().factory() is not a function after concat (gulp) (cheers to Max Yari)
The first thing to check is that you actually use the DI pattern everywhere in your code as the function parameters will be replaced during uglification and thus won't be resolved let anymore.
ControllerName.$inject = ['component']
Or
angular.module('module')
.controller(['module', function (module) { /*... */}) ;
When you've done that, check if you may explicitly specify file order like this (pseudo code):
['module1_decl_file.js','module2_decl_file.js', '*.js','**/*.js']

Custom template delimiter for kataras/iris framework, Go Language

How do I add a custom delimiter to iris templates? I'm using angularjs for the front end and it conflicts with what angularjs is doing. I found some reference here but when I tried, it doesn't work, looks like the author of iris just gave a simple snippet just to describe it.
I'm quite new to Go so even checking the source code of iris, I'm having trouble. Thanks.
Note: I know that I should be using static files for this, but this just really peaked my curiousity

Is it possible to dynamically import modules?

I have many imports for angular components, and it looks like I can write a function to simplify the import. I just don't know how, but this should be simple.
Sample imports:
import {DashboardComponent} from './app/components/dashboard/dashboard.component';
angular.module('app.components').component('dashboard', DashboardComponent);
import {HeaderComponent} from './app/components/header/header.component';
angular.module('app.components').component('header', HeaderComponent);
The function below demonstrates what I want to achieve, however I'm missing two concepts to make it work:
How do I put a variable (name) in the {}?
Can I use an Angular filter in a function like | ucfirst in a JS file?
componentImporter('header');
function componentImporter(name)
{
import {name | ucfirst + 'Component'} from './app/components/'+ name + '/' + name +'.component';
angular.module('app.components').component(name, name | ucfirst + 'Component');
}
Finally an error I run into is:
'import' and 'export' may only appear at the top level
So can this actually ever work?
So can this actually ever work?
Short Answer: No
Long Answer
The error you saw pretty much says it all... imports can't be nested inside conditionals, loops, or other expressions. Here's a great article on ES6 Modules that goes in depth on the subject. Another interesting note, also mentioned in that article, is that imports are hoisted, similar to functions.
How to put a name in the {} and 2) can I use an angular filter in the fuction like | ucfirst in a js file?
From the article:
...the structure of ES6 modules is static
Using a variable in the import would make it dynamic. The bracket syntax you're using can only be written to do a partial import (i.e. Importing named exports from the given module). This is really neat if you're using tree shaking, another article by Dr. Rauschmayer.
Personally I like keeping all my imports at the top of each file making it very easy to see what that particular module is dependent on.
Update
There is now the dynamic import() method. Some bundlers like webpack already support this method natively. This method is what should be used for dynamic importing of modules. Note that "Dynamic Imports" is an umbrella topic that contains a few subtopics including "Code Splitting", "Dynamic Module Expressions", as well as using logic to determine whether a module and its dependencies should be loaded.

How to merge multiple html files into one with brunch.js

I'm using underscore.js for my templates which are stored in multiple separate XXX_tpl.html files inside sections similar to:
<script type="text/x-template" id="tpl_XXX">
<h1>hi</h1>
</script>
Which I am then using inside backbone.js views as follows:
render: function () {
this.$el.html($('#tpl_XXX').text());
}
I am now using brunch.js build tool which nicely outputs all my libs/js/css code into several optimized files but I am having issue with managing / organizing my templates. How do I make brunch.js build tool to append all *_tpl.html files at the end of index.html? All the examples I am seeing online show how to use brunch.js to merge templates into .js files but I don't yet understand how that works (the templates are a mix of html/js and I lose both access by ID and syntax formatting/highlighting when storing templates in .js files).
Q1. If what I'm doing is right (multiple templates in multiple different .tpl.html files all appended at the end of index.html when built) then how do I make build.js merge all of that?
Q2. If what I'm doing isn't right, what's a better approach to:
have multiple templates that are organized and easily managed
not create additional http requests to pull / all compiled into a single file
have easy access from backbone.js models
want to achieve syntax highlighting in my IDE for the template markup (i.e. no JS string concatenations, etc)
Nice question, but I don't know if you understood how underscore templates should work precisely. Let's try to clear that up first.
Template compilation
An underscore template source is any text with interpolated code. For example:
var myTemplateString = "hello: <%= name %>";
When you want to use that template, you need to compile it into a function first. What? Here's how it works:
var myTemplateFunction = _.template(myTemplateString);
This creates a myTemplateFunction which contains your template logic. In a very simplified, pseudo-code way, you can expect myTemplateFunction to work somewhat like this:
function (context) { return "hello: " + context.name };
So, now you understand why you can call this function and produce a string!
myTemplateFunction({name: 'moe'}) // hello: moe
Using compiled templates
OK, but why do you need to compile it previously? Why not always call directly:
_.template(myTemplateString)({name: 'moe'})
Because compilation can be CPU-intensive. Therefore, it's much faster to use a pre-compiled template. You should not force the user's browser to do it! You should do it for him!
Delivering compiled templates
By now, you understand you don't care about delivering the text of your functions to your client, only the compiled template functions. There are many ways to accomplish that.
Brunch has a bunch of plugins for pre-compiled templates, but apparently none for underscore: http://brunch.io/plugins.html
You can use webpack and it's EJS template loader.
Your code would look something like this:
var myTemplateFunction = require('./template.html')
console.log(myTemplateFunction);
You can also use Grunt and it's underscore template task: grunt-contrib-jst.
Whichever you choose, they will all work similarly: they'll compile your template into a function and you'll be able to use that function. Personally, I recommend learning webpack!

Uncaught ReferenceError: SWFObject is not defined

It sounds like a dumb question and FAQ as well, but I truly don't see any reason not to be able to run it.
I try to run a imagerotator with SWFObject and that's the error I get. I do include properly the swfobject.js file (accessible via the direct url) and I pass the parameters through an XML file which loads independently fine as well. I do use version 2.2.
Here there is my SWF call:
<div id="slide1">Get the Flash Player to see this rotator.</div>
<div id="rotator"></div>
<script type="text/javascript">
var s1 = new SWFObject("/admin/cms/imagerotator.swf","rotator","606","199","5");
s1.addVariable("file","imagerotator.php");
s1.addParam("allowfullscreen","false");
s1.addVariable("linkfromdisplay", "false");
s1.addVariable("transition","lines");//bgfade,blocks,bubbles,circles,fade,flash,fluids,lines,random,slowfade
s1.addVariable("rotatetime","5");
s1.addVariable("overstretch","false");
s1.addVariable("backcolor","0xFFFFFF");// change if its helps to fit better in design (optional)
s1.addVariable("shuffle","false");
s1.addParam("wmode", "transparent");
s1.addVariable("showicons","false");
s1.addVariable("shownavigation","false");
s1.write("slide1");
</script>
I doubt that this usage of the SWFobject is completely inappropriate for this version, although I use a sample code of a CMS including this exact version of the library.
The implementation changed:
1) Your problem is described (and solved) here.
2) Check the original docs here.
Basically you need to use swfobject.embedSWF(...) now instead of var x = new swfobject(...)
In any case, Google is your friend on this one ;)

Resources