Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A recursive sub-render facility #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

coofercat
Copy link

This small addition means it's possible to have json2html call itself mid-way through a render (without needing to use a function()). This allows for larger, fuller templates that have repeating sections within them (see example below).

To use this feature, instead of specifying an html or text attribute, use the new sub attribute and supply the location of the data for it and the template to render:

let template = [
  {
    "<>": "div",
    "sub": { "data": "mylist", "template": {
        "<>": "p", "html": "${value}",
    },
  },
];

let data = {
  "mylist": ["one", "two"],
};

output = json2html.transform(data, template);

The "sub" templates are of course the exact same format as the regular templates that json2html provides. The "data" attribute supplied to the "sub" gives the key to the data within that supplied to the transform().

Going further with templates and data, for example, this is possible:

let template = [
  {
    "<>": "div",
    "class": "pagetitle",
    "html": "${title}",
  },
  {
    "<>": "div",
    "class": "mytable",
    "html": [
      {
        "<>": "table",
        "html": [
          {
            "<>": "thead",
            "html": [
              {
                "<>": "tr",
                "sub": {"data": "table.headings", "template": {
                  "<>": "th",
                  "html": "${value}"
                }},
              },
            ],
          },
          {
            "<>": "tbody",
            "sub": {"data": "table.data", "template": [
              {
                "<>": "tr",
                "html": [
                  {"<>": "td", "html": "${name}"},
                  {"<>": "td", "html": "${age}"},
                ]
              },
            ]},
          },
        ],
      },
    ],
  },
];

And corresponding data such as:

let data = {
  "title": "Sub Template Demo",
  "table": {
    "headings": ["Name", "Age"],
    "data": [
      {"name": "Fred", "age": 22},
      {"name": "George", "age": 17},
      {"name": "Sally", "age": 26},
      {"name": "Alice", "age": 19},
    ]
  }
};

This outputs something like:

<div class="pagetitle">Sub Template Demo</div>
<div class="mytable">
 <table>
  <thead>
    <tr><th>Name</th><th>Age</th></tr>
  </thead>
  <tbody>
   <tr><td>Fred</td><td>22</td></tr>
   <tr><td>George</td><td>17</td></tr>
   <tr><td>Sally</td><td>26</td></tr>
   <tr><td>Alice</td><td>19</td></tr>
  </tbody>
 </table>
</div>

The main points here being that you can have:

  • Multiple points of recursion within a template
  • Multiple array-renders (so multiple repeated sections based on data)
  • Everything just as it always was with json2html (if you don't use the magic sub feature)

With this, since no actual function calls are used, it's also possible to send your template from place to place as a string (should such a requirement be necessary).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant