Gulp is not updating my static generated pages with Assemble - node.js

I have a working Modular Gulpfile which is building my static pages with assemble. So far so good. When i run a watch job and change my data in a Json file the watcher is running assemble again, building the pages without the new data. Handlebars partials and all other things are working exept for the data files. When i quit my watch task and run the whole assemble task again, the data is updated, so the assemble task works i think.
This is my assemble task.
module.exports = function(gulp, plugins, config, assemble, browserSync) {
var error = require("./error.js");
var clean = require("./clean-html.js");
//var production = require("./distribution.js");
var app = assemble();
gulp.task('load', function() {
app.partials(config.source.assembleSrc.partials);
app.layouts(config.source.assembleSrc.layouts);
app.data(config.source.assembleSrc.data);
});
gulp.task('assemble', ['load'], function() {
return app.src(config.source.assembleSrc.pages)
.pipe(plugins.plumber({
errorHandler: error
})) //Added proper error handling
.pipe(app.renderFile())
.pipe(plugins.rename(function(path) {
path.extname = ".html" // Rename to HTML
}))
.pipe(plugins.if(production, gulp.dest(config.dist.html), gulp.dest(config.temp.html)))
.pipe(browserSync.reload({
stream: true
})); // Browser reload
});
};
Thanx in advance!

Related

Migrating main.js to Parse Server

I need help migrating my parse server and was directed here by the parse support page.
I have finished the database migration to an mLab database and have the parse server example running in heroku.
My project runs perfectly at retrieving my current data with the default parse server example main.js file, but I would like to still run ParseServer jobs from the client like in this iOS example so I would like to use my own main.js file.
[PFCloud callFunction:#"publishCard" withParameters:#{
#"cardID" : card.cardPF.objectId,
} error:&error];
When I try to run my project with the following file as main.js (I've renamed it newmainjs just for visibility), it doesn't let me login with parse at all anymore from my iOS Client--so it seems to be triggering errors and I have no idea how to debug it as it's not covered in the migration tutorial.
https://github.com/KetchupMoose/cardgameserver/blob/master/cloud/newmain.js
I am very amateur at backend/node so I would really appreciate some support, as I relied on Parse for a lot of things before.
take a look at: https://parse.com/migration
section 3 "cloud code".
You need to change any use of:
Parse.Cloud.useMasterKey()
which you use:
here:
https://github.com/KetchupMoose/cardgameserver/blob/master/cloud/newmain.js#L162
and here: https://github.com/KetchupMoose/cardgameserver/blob/master/cloud/newmain.js#L633
instead of using useMasterKey(), you need to pass 'useMasterKey: true' to queries and saves.
Here are a few examples from your code:
userQuery.find({
useMasterKey: true, // <-- note the addition here
success: function(results) {
console.log(results.count);
....
And:
}).then(function(saveObjects)
{
Parse.Object.saveAll(updatedUserObjects, {
useMasterKey: true, // <--- here
success: function(list) {
//assumes all are saved
response.success("user EloRatings Saved Successfully");
},
.....
And:
Parse.Cloud.define("giveSellerGold", function(request, response) {
Parse.Cloud.useMasterKey();
var user = new Parse.User();
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", request.params.sellerID);
query.first({
useMasterKey: true, // <--- here
success: function(object) {
object.increment("gold", request.params.sellerGold);
object.save(null, { useMasterKey: true }); // <-- note how save is done.
response.success("Successfully saved gold");
},
error: function(error) {
response.error("update failed");
}
});
});
so just make sure that all the queries (that need it) are passing 'useMasterKey' in the options and that ought do it! Good luck.

Include Gruntfile and run a task in an another file

I have an app using Grunt, that I launch in my terminal, and I want to run a task through an another app.
So I'd like to know how can I include my Gruntfile.js to this other app, and run the task.
For now this new app is really basic, juste a simple local web page using NodeJS, with a button that launch the task.
Gruntfile (I want to run the "archive" task)
module.exports = function (grunt) {
require('time-grunt')(grunt);
require('jit-grunt')(grunt, {
ngtemplates: "grunt-angular-templates"
});
var Generator = require("./generator.js")(grunt);
var generator = new Generator();
generator.printLogo();
// Build
grunt.registerTask("build", function (fileType) {
//definition of build task
grunt.task.run(tasks);
});
// Archive Task.
grunt.registerTask("archive", ["build", "compress", "clean:post-rsync"]);
};
Other file : (I tried a require, It seems to work, but I can't run the "archive" task of the Gruntfile.)
var grunt = require('grunt');
var gruntfile = require('./Gruntfile.js')(grunt);
var app = express();
app.get('/', function(req, res){
res.render('test.ejs');
});
app.post('/create', function(req, res){
//run grunt task "archive" here
//gruntfile.grunt.registerTask("archive", ["build"]);
res.redirect('/');
});
app.listen(8080);
Do you have any idea how could I run the task in my gruntfile in this other file ?
(The function printLogo() is working so i'm sure the Gruntfile is include)
Thank you very much (I'm a beginner with Grunt so sorry if I miss something trivial)
You can just run a command from node. This way you don’t have to worry about dependencies and what not. You just spawn grunt, like you normally would, except programatically.
var spawn = require('child_process').spawn;
// This will run the 'archive' task of grunt
spawn('grunt', ['archive'], {
cwd: 'path/to/grunt/project'
});
Grunt is a command line tool, the cleanest approach here would be to refactor your Gruntfile and extract your task's logics into a library.
Then from your Gruntfile's task you can call that library, and from your /create route you can also call your library.
You can use grunt-hub plugin:
grunt.initConfig({
hub: {
all: {
src: ['../*/Gruntfile.js'],
tasks: ['jshint', 'nodeunit'],
},
},
});

Gulp, livereload, jade

Need help.
I use gulp-conect and it livereload method. But if I build a few template in time, get a lot of page refresh. Is any solution, I want to build few templates with single page refresh?
So, I reproduce the problem you have and came accross this working solution.
First, lets check gulp plugins you need:
gulp-jade
gulp-livereload
optional: gulp-load-plugins
In case you need some of them go to:
http://gulpjs.com/plugins/
Search for them and install them.
Strategy: I created a gulp task called live that will check your *.jade files, and as you are working on a certain file & saving it, gulp will compile it into html and refresh the browser.
In order to accomplish that, we define a function called compileAndRefresh that will take the file returned by the watcher. It will compile that file into html and the refesh the browser (test with livereload plugin for chrome).
Notes:
I always use gulp-load-plugin to load plugins, so thats whay I use plugins.jad and plugins.livereload.
This will only compile files that are saved and while you have the task live exucting on the command line. Will not compile other files that are not in use. In order to accomplish that, you need to define a task that compiles all files, not only the ones that have been changed.
Assume .jade files in /jade and html output to /html
So, here is the gulpfile.js:
var gulp = require('gulp'),
gulpLoadPlugins = require('gulp-load-plugins'),
plugins = gulpLoadPlugins();
gulp.task('webserver', function() {
gulp.src('./html')
.pipe(plugins.webserver({
livereload: true
}));
gulp.watch('./jade/*.jade', function(event) {
compileAndRefresh(event.path);
});
});
function compileAndRefresh(file) {
gulp.src(file)
.pipe(plugins.jade({
}))
.pipe(gulp.dest('./html'))
}
Post edit notes:
Removed liveReload call from compileAndRefresh (webserver will do that).
Use gulp-server plugin insted of gulp-connect, as they suggest on their repository: "New plugin based on connect 3 using the gulp.src() API. Written in plain javascript. https://github.com/schickling/gulp-webserver"
Something you can do is to watch only files that changes, and then apply a function only to those files that have been changed, something like this:
gulp.task('live', function() {
gulp.watch('templates/folder', function(event) {
refresh_templates(event.path);
});
});
function refresh_templates(file) {
return
gulp.src(file)
.pipe(plugins.embedlr())
.pipe(plugins.livereload());
}
PS: this is not a working example, and I dont know if you are using embedlr, but the point, is that you can watch, and use a callback to call another function with the files that are changing, and the manipulate only those files. Also, I supposed that your goal is to refresh the templates for your browser, but you manipulate as you like, save them on dest or do whatever you want.
Key point here is to show how to manipulate file that changes: callback of watch + custom function.
var jadeTask = function(path) {
path = path || loc.jade + '/*.jade';
if (/source/.test(path)) {
path = loc.jade + '/**/*.jade';
}
return gulp.src(path)
.pipe(changed(loc.markup, {extension: '.html'}))
.pipe(jade({
locals : json_array,
pretty : true
}))
.pipe(gulp.dest(loc.markup))
.pipe(connect.reload());
}
First install required plugins
gulp
express
gulp-jade
connect-livereload
tiny-lr
connect
then write the code
var gulp = require('gulp');
var express = require('express');
var path = require('path');
var connect = require("connect");
var jade = require('gulp-jade');
var app = express();
gulp.task('express', function() {
app.use(require('connect-livereload')({port: 8002}));
app.use(express.static(path.join(__dirname, '/dist')));
app.listen(8000);
});
var tinylr;
gulp.task('livereload', function() {
tinylr = require('tiny-lr')();
tinylr.listen(8002);
});
function notifyLiveReload(event) {
var fileName = require('path').relative(__dirname, event.path);
tinylr.changed({
body: {
files: [fileName]
}
});
}
gulp.task('jade', function(){
gulp.src('src/*.jade')
.pipe(jade())
.pipe(gulp.dest('dist'))
});
gulp.task('watch', function() {
gulp.watch('dist/*.html', notifyLiveReload);
gulp.watch('src/*.jade', ['jade']);
});
gulp.task('default', ['livereload', 'express', 'watch', 'jade'], function() {
});
find the example here at GitHub

RequireJS plugin, load files on demand

I have RequireJS implemented fine, and a Grunt based build process which is optimizing the all the JS files app into one file via r.js which is also working fine. All my app files are concatenated into one big JS file for efficient production deployment.
Now I'm having the following requirements:
I need to write a plugin for requirejs, that will not load(not include the file) into the optimized file in the build process, but will required on demand:
Meaning in my code I'll have:
var myObj = require("myplugIn!jsFile");
So in the end when this line runs, it will runs in 2 options:
on build process, the file is not included in the optimized file
The application is running, it will be request the file on demand.
I wrote the following plugin, but is not working:
define(function () {
"use strict";
return {
load : function (name, req, onload, config) {
// we go inside here we are running the application not in build process
if (!config.isBuild) {
req([name], function () {
onload(arguments[0]);
});
}
}
};
});
What I'm missing here.
In your build configuration you can exclude files that you don't want to bundle. They will still be loaded on demand when needed. You may also do something like this:
define(function (){
// module code...
if (condition){
require(['mymodule'], function () {
// execute when mymodule has loaded.
});
}
}):
This way mymodule will be loaded only if condition is met. And only once, if you use same module dependency elsewhere it will return loaded module.
It was more simpler that I though, if helps someone, I'm posting the solution, I create a plugin , that in build process return nothing and in run time, returns the required file, hope helps someone.
define(function () {
"use strict";
return {
load : function (name, req, onload, config) {
if (config.isBuild) {
onload(null);
} else {
req([name], function () {
onload(arguments[0]);
});
}
}
};
});

Nodejs Backbone Templates

I have worked a lot with rails, requirejs and backbone and know how to use haml coffee templates in rails.
App = new Backbone.Marionette.Application()
App.addInitializer (options) ->
Backbone.history.start()
alert "yay"
$ ->
alert "yay"
App.start()
How do i do it in Node.js, I have a Node.js app and i am at a deadend with regards to how do i get a template to compile client side, i am not stuck on haml coffee, any template engine will do, jade is fine too, underscore too. Just a good starting point so that i can get on with building the backbone app in node.js.
Any Help is appreciated!
I don't suggest dragging the templates to the client and compiling them there,the right way would be to use some framework such as www.socketstream.com that offers what you want and much more. If you're against frameworks quick and dirty solution to compiling them on the server and calling them as function on the client will be :
// compile.js
var fs = require("fs")
,jade = require("jade");
exports.build = function(templatesDir) {
var js = "var Templates = {}; \n\n";
var files = fs.readdirSync(templatesDir);
var jadeFiles = files.filter(function(file) {
return file.substr(-5) === ".jade";
});
for(var i = 0; i < jadeFiles.length; ++i){
var filePath, key;
var file = jadeFiles[i];
key = file.substr(0, file.indexOf("."));
filePath = templatesDir + file;
var jadeSource = fs.readFileSync(filePath);
js += "Templates." + key + " = " + jade.compile(jadeSource, {
debug: false,
client: true
}).toString() + "; \n\n";
}
return js;
};
// On the server.js
// Compile views
var viewsPath = path.join(__dirname, 'views/');
var generatedJs = require('./compile').build(viewsPath);
var savePath = path.join(__dirname, 'public/js/lib/templates.js');
fs.writeFile(savePath, generatedJs, function (err) {
if (err) throw err;
});
// Then on the client include js/lib/templates.js and use templates like this
FactSummaryView = Backbone.View.extend({
template: Templates.issueSummary,
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
// Also add templates.js to nodemonignore if you're using nodemon
./public/js/lib/templates.js
/public/js/lib/templates.js
You usually don't compile the templates on the client (expect the templates are edited directly in the browser), instead they are compiled in the backend and rendered in the browser.
Compile the templates
In this step you compile the template source code to a JavaScript file that contains a render function.
You can either use haml-coffee on the command line and make a script in your build process or make use of the projects listed in the integration section of the Haml-Coffee README.
Grunt is a popular solution to run certain tasks and with Grunt-Haml you have certainly a flexible build solution for your project.
Render the templates
To render the templates with Marionette you need to make sure the template render function is available on the client. Just type the configured namespace into the developer tools to see if the template functions are registered:
If this is fine, you need to have a custom template render function:
Backbone.Marionette.Renderer.render = (template, data) ->
if JST[template]
JST[template](data)
else if _.isFunction(template)
template(data)
else
console.error 'Template %s not found', template
Now you can simply define the view template and it'll be rendered properly:
class App.Views.Login extends Backbone.Marionette.ItemView
template: 'shared/_login'

Resources