Configure nginx to send response with header and footer for HTTP body

I have a collection of memos in a folder /memos/items/ A single memo used to contain a SSI include statement for a HTML header part, up to and including the opening <body>, followed by the HTML code of the memo's content, and at the end a further SSI include statement for the footer which contained the code to close the HTML document, like so:

<!--# include file="/memos/header.html" -->
Dies ist ein <i>Testeintrag</i>.
<blockquote>
Man soll den Tag
nicht vor dem Abend loben
</blockquote>
<!--# include file="/memos/footer.html" -->

This works pretty well, but I don't like the SSI statements in the single item file. I would prefer to instruct nginx to serve the header and footer automatically, with a configuration similar to

location ~ /memos/[\w-]+$ {
  sendfile /memos/before.html;
  sendfile $request_filename;
  sendfile /memos/after.html;
}

Is this possible? Is there an nginx module providing a directive sendfile which works like described?

Advantages would be:

  • The folder containing the items contains only the pure content, no additional directive. When providing a "Search" function, the folder could therefore be greped.
  • Redundancy is avoided (the "include" instructions for header and footer exist only once, not in each file duplicated.

EDIT (2016/07/01)

Meanwhile, I found a solution with SSI with the above advantage points (i.e. providing the item files content-only, with no ssi tags), by simply changing the perspective: Instead of including header and footer in each individual item file, I include the item file in a single master template.

Inspired by the proposal on the nginx site; I configure

 location /memos/ {

    ssi on;

    default_type text/html;

    location ~ /memos/([\w-]+)$ {
      set $inc /memos/items/$1;
      rewrite ^ /memos/template.html break;
    }

 }

and use the variable $inc in the master template.html:

<!doctype html>
<html lang="de">
  <head>
    <meta charset="utf-8">
    ...
  </head>
  <body>
    <div id="content">

<!--# include file="$inc" -->

    </div>
    <script src="main.js"></script>
    <script src="items.js"></script>
  </body>
</html>

However, I won't close this topic since I am still interested in the original question whether it's possible to instruct nginx to compose one response as a sequence of several files.


You can use the addition module (ngx_http_addition_module), which needs to be enabled at build time (--with-http_addition_module):

location / {
    add_before_body /before_action;
    add_after_body  /after_action;
}

Note that it does not permit stacking of arbitrary data, but instead provides features to add content before and after the main response. It might be possible to stack addition invocations by using a location with another addition instruction as add_*_body, but I haven't tried that – and it would certainly reduce readability of your configuration.