Loading HTML templates with RequireJS - html

I am trying to load HTML templates with RequireJS and I am trying to use a RequireJS plugin for that. https://github.com/ZeeAgency/requirejs-tpl . Here's the sample code provided in the plugin for loading a template.
define(['tpl!your-template-path.tpl'], function(tpl) {
return tpl({your: 'data'});
});
The problem with this function is that there is no way to pass the data to this function and get the rendered html. I'm new to javascript, so please help.
And do you know of a simpler way to load HTML templates with requirejs?

I use the text plugin, and underscore for the templating
You use it like this:
your_template.html
<p>hello <%=name%><p>
In your requirejs file,
define(['underscore', 'text!./your_template.html'], function(_, yourTemplate ) {
var compiledTemplate = _.template(yourTemplate );
return = compiledTemplate({name: 'moe'});
});

Related

Programmatically loading a ES6 module with Traceur in web page

I have been using Traceur to develop some projects in ES6. In my HTML page, I include local Traceur sources:
<script src="traceur.js"></script>
<script src="bootstrap.js"></script>
and if I have a module in the HTML afterwards like:
<script type="module" src="foo.js"></script>
Then Traceur loads in that module, compiles it and everything works great.
I now want to programmatically add an ES6 module to the page from within another ES6 module (reasons are somewhat complicated). Here was my first attempt:
var module = document.createElement('script');
module.setAttribute('type', 'module');
module.textContent = `
console.log('Inside the module now!');
`;
document.body.appendChild(module);
Unfortunately this doesn't work as Traceur does not monitor the page for every script tag added, I guess.
How can I get Traceur to compile and execute the script? I guess I need to invoke something on either 'traceur' or '$traceurRuntime' but I haven't found a good online source of documentation for that.
You can load other modules using ES6 import statements or TraceurLoader API for dynamic dependencies.
Example from Traceur Documentation
function getLoader() {
var LoaderHooks = traceur.runtime.LoaderHooks;
var loaderHooks = new LoaderHooks(new traceur.util.ErrorReporter(), './');
return new traceur.runtime.TraceurLoader(loaderHooks);
}
getLoader().import('../src/traceur.js',
function(mod) {
console.log('DONE');
},
function(error) {
console.error(error);
}
);
Also, System.js loader seems to be supported as well
window.System = new traceur.runtime.BrowserTraceurLoader();
System.import('./Greeter.js');
Dynamic module loading is a (not-yet-standardized) feature of System:
System.import('./repl-module.js').catch(function(ex) {
console.error('Internal Error ', ex.stack || ex);
});
To make this work you need to npm test then include BrowserSystem
<script src="../bin/BrowserSystem.js"></script>
You might also like to look into https://github.com/systemjs/systemjs as it has great support for browser loading.
BTW the System object may eventually be standardize (perhaps under a different name) in the WHATWG: http://whatwg.github.io/loader/#system-loader-instance

Referencing resources in a global way either from a virtual directory or the web root?

Let's say I have an MVC/WebAPI/AngularJS site that I'm running locally, e.g. ;
localhost/Test/
which I then want to move to
www.test.com
While local, I have a lot of references to various directories (jsfiles, etc) of the following format (in either JS or HTML files)
app.directive('rpdbSpinner', function() {
return {
restrict: 'E',
**templateUrl: '/Test/templates/directives/spinner.html',**
scope: {
isLoading:'='
}
}
})
when updating/web publishing, I'd have to change everything to:
app.directive('rpdbSpinner', function() {
return {
restrict: 'E',
**templateUrl: '/templates/directives/spinner.html',**
scope: {
isLoading:'='
}
}
})
I can do this manually (which is what I've been doing),but the larger the project grows, the harder it becomes. I could, of course, only change it once and then excluded the files during publishing phase (web.config/rest), but it still feels like I am going about it the wrong way. Using "~/" wouldn't work on plain HTML/JS files as far as I'm aware, and this I can't really use it...
Any suggestions to map to paths globally regardless of whether in a Virtual Directory or the root of a project?
Thanks :)
If you simply care about getting the root/base url of the site so you can append that to get the other url you are after, you may simply use / as the first character of your url.
var getUsersUrl = "/api/users";
Here is an alternate approach if you want more than just the app root (Ex : Specific urls( built using mvc helper methods such as Url.RouteUrl etc)
You should not hard code your app base path like that. You may use the Url.Content or Url.RouteUrl helper methods in your razor view to generate the url to the app base. It will take care of correctly building the url regardless of your current page/path.Once you get this value, assign it to a javascript variable and use that in your other js code to build your other urls. Always make sure to use javascript namespacing when doing so to avoid possible issues with global javascript variables.
So in your razor view (Layout file or specific view), you may do this.
<script>
var myApp = myApp || {};
myApp.Urls = myApp.Urls || {};
myApp.Urls.baseUrl = '#Url.Content("~")';
myApp.Urls.userListUrl = '#Url.Action("Index","User")';
</script>
<script src="~/Scripts/NonAngularJavaScript.js"></script>
<script src="~/Scripts/AngularControllerForPage.js"></script>
<script>
var a = angular.module("app").value("appSettings", myApp);
</script>
In your angular controller, you can access it like,
var app = angular.module("app", []);
var ctrl = function (appSettings) {
var vm = this;
console.log(appSettings.Urls.userListUrl);
vm.baseUrl = appSettings.Urls.baseUrl;
//build other urls using the base url now
var getUsersUrl = vm.baseUrl + "api/users";
console.log(getUsersUrl);
};
app.controller("ctrl", ctrl)
You can also access this in your data services, directives etc.
In your non angular java script files.
// With the base url, you may safely add the remaining url route.
var urlToJobIndex2= myApp.Urls.baseUrl+"jobs/GetIndex";
Using "~/" wouldn't work on plain HTML/JS files as far as I'm aware,
and this I can't really use it...
Yes, but you could inject it in your main server-side served webpage as a variable:
<script>
var baseUrl = ... get the base url from the server using ~/
</script>
and then in your external scripts simply concatenate the relative urls with it. As far as static html files are concerned, then it could be a little more problematic. You could serve them through some special server side handler that will take care of injecting this logic.
You can use module.constant to create an injectable which you can use.
app.constant("URL_BASE", "/Test");
app.directive('rpdbSpinner', function(URL_BASE) {
return {
restrict: 'E',
**templateUrl: URL_BASE + '/templates/directives/spinner.html',**
scope: {
isLoading:'='
}
}
})
You can also use module.value if you register it before you register your directive.
For more information see AngularJS Module Guide -- configuration.

How to use gulp to organize the different js file in different html?

How to use gulp to organize the different js file in different html?
is the only way I can do is to define each page to gulp task ? Or gulp have a better way can detect file automatically?
This is my situation below.
I have two html 'index.html','content.html'
index.html need plugin_A.js
content.html need plugin_B.js
And my gulp file:
gulp.task('index_concat', function() {
return gulp.src('./app/js/plugin_A.js')
.pipe(concat('index.js'))
.pipe(gulp.dest('./build/js/'));
});
gulp.task('content_concat', function() {
return gulp.src('./app/js/plugin_B.js')
.pipe(concat('content.js'))
.pipe(gulp.dest('./build/js/'));
});
If I had 100 pages, the tasks were too big!!!
I think this is a stupid way to define each page, but I have no idea how to get better. Please give me some advice.
You could use some name convention for your plugins like pluginName_index.js and pluginName_content.js . So you be able to do something like that:
function yourFunction(pluginName,targetName){
return gulp.src('./app/js/'+pluginName)
.pipe(concat(targetName))
.pipe(gulp.dest('./build/js/'));
}
fs.readdirSync('.app/js/pluginFolder')
.filter(function(fileName) {
var fileNameParts = fileName.split('_');
yourFunction(fileName,fileNameParts[1]);
});

Handlebars Js Not Loading my Content

I am trying to parse some json with Handlebars on my website. I don't get any errors but also don't get any content. I've developed my own rest point to return a json response and I think my problem might be there somewhere, but you can see the response in the code.
http://codepen.io/anon/pen/Czdxh
$(document).ready(function(){
var raw_template = $('#post-template').html();
// Compile that into an handlebars template
var template = Handlebars.compile(raw_template);
// Retrieve the placeHolder where the Posts will be displayed
var placeHolder = $("#all-posts");
// Fetch all Blog Posts data from server in JSON
$.getJSON("https://instapi-motleydev.rhcloud.com/liked",function(data){
$.each(data,function(index,element){
// Generate the HTML for each post
var html = template(element);
// Render the posts into the page
placeHolder.append(html);
});
});
});
Thanks for any help!
The problem was I was getting an array response from the server and needed to adapt my template to include the {#each this} syntax. Also switched my getJSON to a simple get and looped over the reaction that way and tossed the $.each handler.

Node.js : How to embed Node.js into HTML?

In a php file I can do:
<p><?php echo "hello!";?></p>
Is there a way to do this in node, if yes what's the logic for it?
I have an idea how could this be done:
Use an identifier markup for node in the HTML file like: <node>code</node>
Load & Parse HTML file in Node
Grab node markup from the HTML file and run it
But I'm not sure if this is the best way or even if it works :)
Please note I want to learn node.js, so express and other libraries and modules are not answers for me, because I want to know the logic of the process.
What your describing / asking for a node.js preprocessor. It does exist but it's considered harmful.
A better solution would be to use views used in express. Take a look at the screencasts.
If you must do everything from scratch then you can write a micro templating engine.
function render(_view, data) {
var view = render.views[view];
for (var key in data) {
var value = data[key];
view.replace("{{" + key + "}}", value);
}
return view;
}
render.views = {
"someView": "<p>{{foo}}</p>"
};
http.createServer(function(req, res) {
res.end(render("someView", {
"foo": "bar"
}));
});
There are good reasons why mixing php/asp/js code directly with HTML is bad. It does not promote seperation of concerns and leads to spaghetti code. The standard method these days is templating engines like the one above.
Want to learn more about micro templating? Read the article by J. Resig.
You can try using JooDee, a node webserver which allows you to embed serverside javascript in your web pages. If you are familiar with Node and PHP/ASP, it is a breeze to create pages. Here's a sample of what a page looks like below:
<!DOCTYPE html>
<html>
<: //server side code in here
var os = require('os');
var hostname = os.hostname();
:>
<body>
<div>Your hostname is <::hostname:></div>
</body>
</html>
Using JooDee also lets you expose server javascript vars to the client with no effort by attaching attributes to the 'Client' object server side, and accessing the generated 'Client' object in your client side javascript.
https://github.com/BigIroh/JooDee
Use a template engine. From terminal
npm install ejs
In code:
var ejs = require('ejs');
var options = {
locals: {
foo: function() { return "bar"; }
}
};
var template = "<p><%= foo() %></p>";
console.log(ejs.render(template, options));