Search code examples
htmlnode.jspug

Include another Jade file in HTML format syntax


I am using Jade just to include other sections in my HTML files using include. This works fine if I write Jade syntax instead of HTML syntax. But in my case, I need to write HTML syntax only. I am trying to use jade just for include only.

From this link, I found that we can write HTML by including . or | in the code. So, to test this out, I wrote the code like this:

File index.jade

div.main.
     <div class="wrapper">
         include header
     </div>

As you can see in above code, I added . as suffix to the Jade syntax line, i.e., div.main., which lets me write HTML from next line.

File header.jade

<header></header>

But this isn't working. The rendered HTML looks like this:

File index.html

<div class="main">
    <div class="wrapper">
         include header
    </div>
</div>

If I don't use . and follow the Jade syntax, everything works fine. But in my case, I really need to write in HTML, but not in Jade.

Is there a workaround to make the include work inside the HTML syntax?


Solution

  • Well, it is possible to do what you want, but I am not sure if Jade is the best option.

    Note: In Jade, every line which starts with < is considered plain text, so there is no need to use dot or | to write html tags.

    Here is a working example of what you want:

    a.jade

    div.main
      <div class="wrapper">
      include b.jade
      </div>
    

    b.jade

    <div class="b">I am content from b.jade</div>
    

    and after compilation of a.jade we get:

    a.html

    <div class="main">
      <div class="wrapper">
        <div class="b">I am content from b.jade</div>
      </div>
    </div>
    

    This code was tested and it works 100% with the latest version of Jade, but It works only when you don't increase indentation level. For example, the following code will not work:

    div.main
      <div class="wrapper">
        include b.jade
      </div>
    

    On compilation it will throw: unexpected token "indent", and the error itself:

    div.main
      <div class="wrapper">
        include b.jade
      ^^ extra indent "tab"
      </div>
    

    The same is true for nested plain HTML too, so the following:

    div.main
      <div class="wrapper">
        <div class="foo">
          include b.jade
        </div>
      </div>
    

    will also throw this error: unexpected token "indent", and the errors:

    div.main
      <div class="wrapper">
        <div class="foo">
      ^^
          include b.jade
      ^^^^
        </div>
      ^^
      </div>
    

    You can write code like this:

    div.main
      | <div class="wrapper">
      |  <div class="foo">
      |    <div class="bar">
      include b.jade
      |    </div>
      |  </div>
      | </div>
    

    and assuming that we already have that b.jade, it will be compiled into:

    <div class="main">
      <div class="wrapper">
       <div class="foo">
         <div class="bar"><div class="b">I am content from b.jade</div></div>
       </div>
      </div>
    </div>
    

    But note where I placed that include b.jade, exactly one tab has been added in comparison with last Jade command div.main (so included file will be nested into .main div), and you should follow that indent rule if you want your code to work.


    Alternative solution

    As I wrote at the beginning, Jade is not the best option in your case. I would use another server side language to do what you want.

    Here is a basic algorithm:

    1. Write your HTML files in plain HTML (.html) and as an include use a custom tag like <include b.html>
    2. Create a master file using a server side language which will load and process your HTML files and will replace your custom tags with actual content from these files
    3. Save output to a new file and use it.

    Here is an example written in PHP:

    master.php

    <?php
    
    $main_file = "a.html";
    $content = file_get_contents($main_file);
    
    $content = preg_replace_callback(
        '!<include\s+([^>]+)>!',
        function ($m) {
            return file_get_contents($m[1]);
        }, $content
    );
    
    file_put_contents("bundle.{$main_file}", $content);
    

    Now HTML files:

    a.html

    <div class="main">
        <div class="wrapper">
            <include b.html>
        </div>
    </div>
    

    b.html

    <div class="b">foobar</div>
    

    Now after we will execute master.php we will get bundle.a.html with the following content:

    bundle.a.html

    <div class="main">
        <div class="wrapper">
            <div class="b">foobar</div>
        </div>
    </div>