Dynamic Multi-Page Multi-Column Newsletter Layout with Columnizer

A Columnizer Case Study

Sample Page Layout

I got an interesting email this week, asking about how to use Columnizer to help layout a multipage and multicolumn newsletter. The length of the content would vary from week to week, so the newsletter needed to be grow/shrink to as many pages as necessary. It also needed a custom header and footer for each page.

Here’s the sample page showing the solution in action.

The HTML

How does it work? Let’s take a look at the source, beginning with the HTML:

<div id="page_template">
    <div class="header">
        This is a header
        <hr>
    </div>
    <div class="content"></div>
    <div class="footer">
        <hr>
        Page: This is the footer.
    </div>
</div>
<div id="newsletterContent">Newsletter Content Goes Here</div>

We define the template for what we want each page to look like. For our case, every page will have the exact same header and footer (with the page number shown in the footer), and page content should be split into 2 columns. Beneath our template, we just print out the entire contents of the newsletter that we want columnized.

Columnizing the Content

Our basic algorithm will be:

  1. Copy the page template and append it to the bottom of the <body>
  2. Columnize what’s in #newsletterContent into that last page until it’s full
  3. Put whatever doesn’t fit back into #newsletterContent
  4. Repeat until #newsletterContent is empty

Awesome, so lets see that in real life code:

$(function() {
  // the height of the content, discluding the header/footer
  var content_height = 652;
  // the beginning page number to show in the footer
  var page = 1;
  function buildNewsletter() {
    if ($('#newsletterContent').contents().length & gt; 0) {
      // when we need to add a new page, use a jq object for a template
      // or use a long HTML string, whatever your preference
      $page = $("#page_template").clone().addClass("page").css("display", "block");
      // append the page number to the footer
      $page.find(".footer span").append(page);
      $("body").append($page);
      page++;
      // here is the columnizer magic
      $('#newsletterContent').columnize({
        columns: 2,
        target: ".page:last .content",
        overflow: {
          height: content_height,
          id: "#newsletterContent",
          doneFunc: function() {
            console.log("done with page");
            buildNewsletter();
          }
        }
      });
    }
  }
  buildNewsletter();
});

The Result

Check out the fully columnized and multi-paged newsletter sample, and be sure to check out the Columnizer project page for more samples, documentation, and of course, to download Columnizer!

It’s been really fun over the past few months to see how different people are using Columnizer. If your site uses Columnizer, give me a shout in the comments, I’d love to check it out!

31 thoughts on “Dynamic Multi-Page Multi-Column Newsletter Layout with Columnizer

  1. Hi,

    Thanks for the nice plug-in. But it is bothering me it is not resulting in same number of pages in all browsers and splitting at the same place across browsers i.e., a given content does not splits equally in all the browsers eg: http://adamwulf.me/autocolumn/sample10.html

    Safari shows 6 pages whereas Firefox shows 5 pages.

    I use lib_columns.js, but it as well has similar issue.

    Do we have a solution for this? Please advise.

    Thanks in advance.

  2. @Shravan,
    good catch. most of the reason is that different browsers have different default CSS stylesheets. i just put up a simple css reset and now they both show 5 pages, though still some minor differences.

    i’d just recommend that you look very closely at your CSS and make sure you’re as specfic as possible. also massage the input as best you can and make use of dontsplit and dontend, and removeiffirst as appropriate.

  3. this is wonderful work. I am a bit confused by some of the comments here, because they seem to indicate that others are seeing multiple pages laid out (hence the safari is 6 pages vs. the ff is 5 pages). I am only seeing the first page laid out. Am I missing something? or has the code changed?

  4. Hi,

    Does anyone know why we see only one page in Internet Explorer 7? (I know it’s an old browser, but in companies..)

    It seems to be a really great script!!

  5. Great script.

    I’m trying to add a div to the first page that would have a lead image, that would be the width of the entire page. Do you have any idea how this might be done?

  6. I have a 3 column layout, header image and a few sub header images that need to be spanned across a 3 column layout without being broken.

    I have a height requirement for the paper, 11×17. The template idea is great, but it does not combine the height that is used in the plugin. This messes up my height requirement.

    Is there a way around this issue?

    Thanks,
    ~Vyee

  7. I have 2 other issues,

    first, I can’t get my odd and even facing pages to work right, maybe the recursive nature of the program isn’t letting me doing a simple page%2 == 0….

    I was able to do it with a hack using the following:

    $(“.cr-subhead-page-odd:even”).css(“display”, “inline”);
    $(“.cr-subhead-page-even:odd”).css(“display”, “inline”);
    $(“.cr-subhead-page-odd:odd”).css(“display”, “none”);

    The other issue is, how do I assign a min-height, even if no content is available? I want a almost blank page, even if it has some text in it? I’m going to try to do it with css, but maybe its a plugin feature…

    http://jsfiddle.net/grimreaper01/2DXrw/1/

    Thanks

  8. I forgot to point out, why does the template use an ID instead of a class?

    That invalidates the HTML code!

    When I use a class instead of id, I get style errors…

    Unless I’m doing something wrong…

  9. Hi, I have a site wide header and footer. Is it possibe for the layout to appear between my header and footer?? At the moment, it jumps to the bottom of the screen below the footer.

  10. Vyache, I’m having the same issue, sometimes my first page appears again after the second page, I’m guessing this is happening because many of the divs are using the same id.
    Did you fmanage to fix it?

  11. Adam, can you post or point me to a script that will reset columnizer back to a single column when the page width is below a certain dimension. (for media queries).

    Thanks

  12. Thank you! This is a great piece of code.

    I have a question: I am using the newsletter layout with two columns. The two columns have the same length in every page except in the last one, where you might get the first column filled up and the second empty, depending on the length of the text. I would like to balance the two columns in every page, including the last one, so that both columns always have the same length. How can this be done?

    TIA

    1. yeah, not easily printable anyway. to get it nicely formatted to a page you have to play with the width/height of the “pages” generated by CSS. possible, not not a tidy solution for sure

    1. The best way to do that would be using CSS. You can target specific columns using `first`, `last`, and `column` css classes.

Leave a Reply

Your email address will not be published. Required fields are marked *