Search code examples
node.jsincludeexpresstemplatingejs

Include HTML blocks Using node.js


This is what I want but probably can't have:

Using node.js and express and maybe ejs, I would like to, while writing a regular HTML file in my client dir, server-side-include a template block of HTML. It would be cool also if I could pass variables into the include from the HTML document.

Sooo something like:

 <!doctype html>
 <html>
   <head>
    <%include head, ({title: "Main Page"}) %>   
   </head>
   <body>
      <% include header, ({pageName: "Home", color: "red"}) %>
    ...
      <<% include footer%>>
   </body>
 </html>

Is there anyhting in node world that works like this? Or any thing that comes close and that could be maybe adapted for this functionality? I would not use it exactly in the way indicated here, but this is the functionality that I am looking for.

I have looked into jade, handlebars, ember and ejs, and ejs seems to come the closest. Maybe one of these does this already, but I am just confused about the implementation.

Any suggestions would be great!


Solution

  • OK I got it...

    server.js

     var express =      require('express');
     var server  =      express();
     var ejs = require('ejs'); 
     ejs.open = '{{'; 
     ejs.close = '}}';
    
    
     var oneDay = 86400000;
     server.use(express.compress());
    
     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");
     });
    
    
     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', { maxAge: oneDay }));
    
     server.listen(process.env.PORT || 8080);
    

    and in /www I have the following .html files:

    index.html

          {{include head.html}}
     {{include header.html}}
    
     <p class="well">Hello world!</p>
    
     {{include footer.html}}
    

    head.html

     <!DOCTYPE html>
     <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
     <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
     <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
     <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
         <head>
             <meta charset="utf-8">
             <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
             <title></title>
             <meta name="description" content="">
             <meta name="viewport" content="width=device-width">
    
             {{include include.css.html}}
    
             <script src="js/vendor/modernizr-2.6.2.min.js"></script>
         </head>
         <body>     
    

    include_css.html

          <link rel="stylesheet" href="css/normalize.css">
          <link rel="stylesheet" href="css/bootstrap.css">
          <link rel="stylesheet" href="css/bootstrap-responsive.css">
          <link rel="stylesheet" href="css/main.css">
    

    header.html

     <div class="well">
          <h1>HEADER</h1>
     </div>
    

    footer.html

             <div class="well">
                 <h1>FOOTER</h1>
             </div>
    
    
             <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
             <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.9.1.min.js"><\/script>')</script>
             <script src="js/plugins.js"></script>
             <script src="js/bootstrap.min.js"></script>
             <script src="js/main.js"></script>
    
             <!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
             <script>
                 var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
                 (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
                 g.src='//www.google-analytics.com/ga.js';
                 s.parentNode.insertBefore(g,s)}(document,'script'));
             </script>
         </body>
     </html>
    

    It all comes through, even includes in includes and static content. It is all performed on html files, and in a context that feel like vanilla web authoring.

    ++++Oops+++++ Well I almost all of it. I forgot that I also wanted to be able to pass variables into the include from the templates. I haven't tried that yet... any ideas?

    ++++Update+++++

    Ok I figured it out.

    This discussion made it clear, i guess i just didn't know enough about how ejs worked.

    I have changed index.html to begin with variable declarations:

     {{
        var pageTitle = 'Project Page';
        var projectName = 'Project Title';
     }}
    

    and then you can call these variables from within the includes, no matter how deeply they are nested.

    So for instance, index.html includes start.html which includes header.html. Within header .html I can call {{= projectName}} within the header even though it was declared inside index.html.

    I have put the whole thing on github.