I'm currently creating my new website with express. The page is split up in different "sections" (for example a blog, information about my project and so on).
I'd like a have a "sidebare" next to my content thats different for each section. For example in the "blog"-Section id like to have a list of my tags or categorys and in the project section there should be a list of all projects. The content depends on the section and is the same for every "subpart" of this section.
One solution would be to create a function that creates the sidebars content and call this function in every function that handles a route. But I don't like this solution because it doesn't seems to "be the right one"...
Does anyone have a nice solution for this?
If I understand your question correctly, you want to know how to render multiple 'sections' using the same overall template, yes? Each section could differ depending on the content on the page and the main URL.
I can suggest two ways:
1) IMHO the right way - Define a base template (say index.jade if you're using jade/express) and you would create routes for say a homepage (/) and a blog page (/blog) using that:
# Home Page
app.get '/', (req, res) ->
# Do some simple DB transactions, etc, and get the main area content.
res.render 'index.jade', { json: json }
# Blog Page
app.get '/blog/:id', (req, res) ->
blog.grabPost req.params.id, (json) -> # Grab content of the blog post from the DB
res.render 'index.jade', { json: json }
Next, create a few 'partial' URL's for the remainder of the content:
# Sidebar Partial
app.get '/sidebar/:page/:id', (req, res) ->
sidebar.grabContent req.params.id, (json) ->
res.render '{#req.params.page}.jade', { json: json }
You would then call the partial client-side upon pageload via JQuery like so:
$ ->
$('.sidebar').load '/sidebar/blog/365' + id, (response, status, xhr) ->
2) Using Express 'view partials' which I'm much less familiar with. Documentation can be found here: http://expressjs.com/guide.html#view-partials
From the description: "The Express view system has built-in support for partials and collections, which are “mini” views representing a document fragment. For example rather than iterating in a view to display comments, we could use partial collection:"
Related
I am confused what the "/" is used for in this piece of code:
app.get("/", (req, res) =>// The / is a shortcut for index.html (might be right could be wrong)
{
res.render(index);
});
Traditional and convenience.
Given the domain example.com, you want the homepage to be at https://example.com/ (i.e. the path, which comes immediately after the domain name, is /) so you don't need to type https://example.com/anything-here.
In your example, the default page of the website, i.e example.com, would render the index page.
However if you wish to make a different page, such as example.com/about you would use /about and render the about page.
e.g. for your code
app.get("[Whatever directory]" ...)
{
res.render([whatever page])
...
I'm not really sure where I"m screwing up with this. Basically I'm reading from my database to generate an html page and dynamically set the hrefs of some anchor tags. When I click on the links, however, the page just reloads and doesn't send a GET request to the server. The important part of the Jade rendering is here.
each val in tournaments
a(href="/home/tournaments/?_id=" + val._id)
The _id param is just the default _id MongoDB gives to the document upon creation.
I'm also using Express to handle my server side requests. The pertinent one for this is here:
app.route("/home/tournaments/:id")
.get(function(req, res, next) {
console.log("Request: " + req.query._id);
});
Nothing gets printed to the console when I click the anchor tag, so I guess it's not reaching this route for some reason.
Can anyone explain what I'm doing wrong and what I need to do to fix it?
Thanks in advance.
The problem is that you're placing the ID in the query string instead of the actual url path. So to make your existing route match, you'd need to instead do this:
each val in tournaments
a(href="/home/tournaments/" + val._id)
and then use req.params.id instead of req.query._id.
OR you could adjust your route pattern to just be /home/tournaments.
I am trying to visualize some Data with d3 which is stored inside of a MongoDB. My question is about something like a best practice to create div elements for every data through the JADE template and afterwards call a method to draw different charts.
My main problem is that I am losing the reference to my data after displaying the HTML file and I do not want to query the DB a second time.
Schema
# Create Schema
executionSchema = new Schema(
timestamp: Number,
components: [{
uid: String,
type: { type: String },
samples: [Number],
execution_times: [Number]
}]
)
The data is initially retrieved and given to the JADE template:
Index coffee
exports.index = (req, res) ->
Execution.find (err, executions, count) ->
res.render "index", title: "Debugger", executions: executions
return
return
Afterwads, the index.JADE creates divs for every component inside of execution[0]
- each component in executions[0].components
div(class="panel panel-primary")
div(class="panel-heading") UID: #{component.uid}
div(class="panel-body")
p(style='white-space:pre;')
| Type: #{component.type}
- var uid = component.uid
div(id=uid)
This is everything right now, since I am not able to call a JavaScript method outside of the JADE file. Any ideas?
Thank you.
If I understand correctly, you want this data to be available on the clientside script without actually querying the db the second time?
You have two options here. The first one is to just add this line right bellow your current Jade code:
- each component in executions[0].components
// div creation stuff here
// ...
script
window.executions = JSON.stringify(executions);
Now your client-side scripts will be able to access the executions object and access that data like this:
var data = JSON.parse(executions);
Not sure if this is efficient though. If you do not want to query the db for the second time, it could be because the dataset is large or db slow?
Well the other way to do this with only a single db query is to render the page without the divs, and do not query the db at all. Then use the Javascript to fetch the executions (ajax call) and render it client-side once the data is loaded.
That depends on your use case though.
Right now, I have an ASP.NET application where, within the aspx files, at various points, I call a function which inserts standard template HTML. For example:
<html>
<head>
</head>
<body>
<%=SectionHeader('Section title 1') %>
some content for section 1
<%=SectionHeader('Section title 2') %>
some content for section 2
</body>
</html>
So wherever the SectionHeader function was called, it would read the passed in parameter, and insert the HTML for the section header, such as {title}. I'm trying to figure out how to accomplish the same thing in Node.
I understand how to do a basic token replacement - reading a static HTML file, looking for a token (such as {token1}) and replacing it with something. But short of using Regex and complex string manipulation, is there any way to accomplish the same thing in Node that I'm doing with ASP.NET?
I took the generated application skeleton, and modified the index.js and index.jade to pass a function into the template. I think is what you are asking for, but there may be opinions if this is a good architecture to have the template call back into logic.
index.js
exports.index = function(req, res){
var fn = function(initial) {
return initial + ". Tester";
};
res.render('index', { title: 'Express', fn : fn });
};
index.jade
block content
h1= title
p Welcome to #{title}
div Hello #{fn('A')}
Now, when I load http://localhost:3000/, this is what renders on the screen. Notice the "A" is being passed into the function to generate the string "A. Tester" for the output.
Express
Welcome to Express
Hello A. Tester
There are lots of templating engines for node, maybe you should try one of these. If you are searching for a web application framework express would be a good starting point, which has support for many templating enignes.
Of course you could do just string replacement, but a templating engine provides much more.
This is a multi part question and I'm a complete newbie to Node so please be gentle:)
I have a very simple Node/express app set up returning an index.html without using routing...
var app = express();
var port = process.env.PORT || 1337;
app.use('/i', express.static(__dirname + '/i'));
app.use('/Stylesheets', express.static(__dirname + '/Stylesheets'));
app.use(express.static(__dirname));
app.listen(port);
console.log('listening on port ' + port);
The index.html is served as a static file.
My next job is to start returning a few pages with proper routing, I've got as far as working out I need to put my routes in a routes.js file and "require" that file in my server.js file but I can't get my head around setting the routes up and every example/demo I see online seems to do it a different way. Any definitive examples of how to do this would really be appreciated.
The next part of the problem is that I want to include dynamic pages but don't know where to go with templating engines. I would like to use something "unobtrusive" so that my original HTML files still make sense when viewed in a browser.
On the front-end I would simply inject HTML into the page by first using a selector and then using the .html() method to alter the html, I could bind JSON data with a template and then inject it into the right place by looking for a classname etc. THis would be totally unobtrusive and wouldn't require any ugly {} brackets, inline javascript or directives. Psuedo code...
var data = {"name":"John"};
var result = templateEngine.bind("/template.html", data)
$('.person').html(result);
That way, I could keep my original HTML clean and viewable, like this...
<div class="person">
My Name is FirstName
</div>
The closest thing I can find is PURE - http://beebole.com/pure - but I'm not sure how to get it working with NODE (or even if it's compatible).
To add more complexity, whatever templating engine I use needs to be able to use sub-templates(partials?) so that I can include a header/footer etc which is te same on every page. I assume this can be done recursively by referencing sub-templates from within each main template where needed?
If you're still reading this then clearly you'll have worked out that I'm floundering here with a new technology and any help would be really appreciated!
but I can't get my head around setting the routes up and every
example/demo I see online seems to do it a different way. Any
definitive examples of how to do this would really be appreciated.
Not sure what you have seen different in the examples, but the general pattern is like this:
app.**[HTTP VERB]**(**[URL]**, function(req, res){
res.end('<html>hello world</html>');
});
The following code will accept all HTTP GET requests to the root URL of your site:
app.get('/', function(req, res){
res.end('<html>hello world</html>');
});
While the following code will accept all HTTP GET request to /test in your site
app.get('/test', function(req, res){
res.end('<html>hello world from the test folder</html>');
});
It's common to have a separate route for HTTP POST requests (e.g. when the user submits data back to the server). In this case the HTTP verb is POST as in the following example.
app.post('/test', function(req, res){
res.end('<html>Thanks for submitting your info</html>');
});
In this case I am embedding the code to handle the request directly rather than referencing an external routes.js as you indicated just to make the examples cleaner in this question. In a real application you'll do it by referencing an external function so that your app.js stays lean and clean.
app.get('/test', routes.NameOfFunctionToHandleGetForSlashTest);
app.post('/test', routes.NameOfFunctionToHandlePostForSlashTest);
I know this is an old question, but I have explored this topic recently, and came up with the following solution:
my original question
I have placed the following configuration on ejs:
var ejs = require('ejs');
server.configure(function(){
server.set("view options", {layout: false});
server.engine('html', require('ejs').renderFile);
server.use(server.router);
server.set('view engine', 'html');
server.set('views', __dirname + "/www");
});
This sets your view engine as ejs, your view directory as your static public html directory and tells ejs to process .html files as opposed to .ejs.
The routes can be handles like this:
server.all("*", function(req, res, next) {
var request = req.params[0];
if((request.substr(0, 1) === "/")&&(request.substr(request.length - 4) === "html")) {
request = request.substr(1);
res.render(request);
} else {
next();
}
});
server.use(express.static(__dirname + '/www'));
This routes all html requests through the view engine, and passes all other requests on down the stack to be sent as static files.
Your html can now look something like:
<%include head.html%>
<%include header.html%>
<p class="well">Hello world!</p>
<%include footer.html%>
you can have nested includes, and pass variables down into your includes. So for instance your include head can call:
<title> <%= title %> </title>
and at the top of your index page you can include an object like:
{var title: "Home"}
Anyway, maybe this will help out someone who is looking for a ultra easy way to handle includes while sticking with normal html.