Generate multiple HTML files at once by pouring JSON data into an HTML template with Python

I would like to generate multiple HTML files at once by pouring data managed separately into the HTML template file of the common format.

Execution environment

・ Node.js 14.15 -Python 3.8 ・ Jinja

procedure

  1. Creating JSON data
  2. Create template HTML
  3. Creating a Python script
  4. Run

Creating JSON data

JSON data may be obtained using an external API, but this time I would like to create it locally and create it from a TypeScript object for easy management and operation.

types/index.ts


//Data type definition file

type Post = {
  id: string;
  date: string;
  title: string;
  author: string;
  body: string;
};

export interface PageData {
  filename: string;
  meta: {
    title: string;
    description: string;
  }
  posts: Post[];
}

Manage data for each page in the / data/pages directory.

Data that manages sample-a.html

/data/pages/sample-a.ts


import { PageData } from '../../types';

export const sampleA: PageData = {
  filename: 'sample-a.html',
  meta: {
    title: 'Sample A',
    description: 'Description of sample A',
  },
  posts: [
    {
     id: '001',
     date: '2021/01/01',
     title: 'First post',
     author: 'Dog',
     body: 'hoge',
    },
    {
     id: '002',
     date: '2021/01/02',
     title: 'Interesting title!',
     author: 'Cat',
     body: 'hogehoge',
    }
  ]
}

Data that manages sample-b.html

/data/pages/sample-b.ts


import { PageData } from '../../types';

export const sampleB: PageData = {
  filename: 'sample-b.html',
  meta: {
    title: 'Sample B',
    description: 'Description of sample B',
  },
  posts: [
    {
     id: '003',
     date: '2021/01/05',
     title: 'A memorable movie',
     author: 'Dog',
     body: '〇〇〇〇〇〇〇〇〇〇',
    },
  ]
}

Combine these TypeScript objects to generate JSON data.

Write a script to generate JSON data.

script.ts


import { writeFile } from "fs"; // <-Beforehand"yarn add -D fs"Install the module with
import { PageData } from "./types";
//Data import
import { sampleA } from "./data/pages/sample-a";
import { sampleB } from "./data/pages/sample-b";

//Put in an array
const data: PageData[] = [sampleA, sampleB];

//Export as a JSON data file
writeFile('data.json', JSON.stringify(data, null, "  "), () => {});

Compile this into JS and run it in Node.js.

tsc script.ts
node script.js

This will generate data.json.

data.json


[
  {
    "filename": "sample-a.html",
    "meta": {
      "title": "Sample A",
      "description": "Description of sample A"
    },
    "posts": [
      {
        "id": "001",
        "date": "2021/01/01",
        "title": "First post",
        "author": "Dog",
        "body": "hoge"
      },
      {
        "id": "002",
        "date": "2021/01/02",
        "title": "Interesting title!",
        "author": "Cat",
        "body": "hogehoge"
      }
    ]
  },
  {
    "filename": "sample-b.html",
    "meta": {
      "title": "Sample B",
      "description": "Description of sample B"
    },
    "posts": [
      {
        "id": "003",
        "date": "2021/01/05",
        "title": "A memorable movie",
        "author": "Dog",
        "body": "〇〇〇〇〇〇〇〇〇〇"
      }
    ]
  }
]

Creating template HTML

Create template HTML in common format. Templates are used in the Python library Jinja2, so create them according to Jinja2 syntax.

templates/page.html


<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{{ meta.title }}</title>
  <meta name="description" content="{{ meta.description }}">
</head>
<body>
  <h1>{{ meta.title }}</h1>
  <div class="posts">
    {% for post in posts %}
      <div class="post" data-id="{{ post.id }}">
        <div class="date">{{ post.date}}</div>
        <h2 class="title">{{ post.title }}</h2>
        <div class="author">{{ post.author }}</div>
        <div class="body">{{ post.body }}</div>
      </div>
    {% endfor %}
  </div>
</body>
</html>

According to the type of PageData created, describe the variable that contains the data received from JSON in{{}}.

Control syntax such as for loops and if statements can be written and used in {%%}. Please refer to the Jinja2 page for details.

Creating a python script

Now that the data and template are complete, it's time to write the script to build in Python.

First, install the Jinja2 library.

pip install jinja2

generate.py


from jinja2 import Environment, FileSystemLoader
import json
import os

# 1.Read data from JSON
json_open = open('./data.json', 'r')
#Array of data
items = json.load(json_open)

# 2.Loading template file
env = Environment(loader = FileSystemLoader('./templates'), autoescape = True)
template = env.get_template('page.html')

# 3.Fill the template with data
build_dir = 'dist'
#Check for the existence of the dist directory. If not, create
if os.path.isdir(build_dir) == False:
  os.mkdir(build_dir)

#Execute as many times as there are data arrays
for item in items:
  #Create HTML by pouring data into a template
  parse_html = template.render(item)

  #Create a destination path
  path = f"{build_dir}/{item['filename']}"

  #Generate and save HTML files
  with open(path, 'w') as file:
    file.write(parse_html)

Run build

python generate.py

Now, if the desired HTML files (here sample-a.html and sample-b.html) are generated in the dist / directory, you're done!

The source code is on GitHub. https://github.com/hiropy0123/python-html-generate

Recommended Posts

Generate multiple HTML files at once by pouring JSON data into an HTML template with Python
Convert multiple proto files at once with python
[Python] Send gmail with python: Send one by one with multiple image files attached
Rsync multiple files at once
Read json data with python
Make multiple numerical elevation data into a single picture with Python
Convert memo at once with Python 2to3
Generate Japanese test data with Python faker
Convert Excel data to JSON with python
Reading and writing JSON files with Python
Organize data divided by folder with Python
Combine multiple python files into one python file
[Python & Unix] Combine multiple PDF files into one.
Generate an insert statement from CSV with Python.
Update multiple tables at once with pandas to_sql
Make JSON into CSV with Python from Splunk
Combine multiple csv files into one csv file with python (assuming only one line of header)
Convert multiple proto files at once with python
Rsync multiple files at once
Sorting image files with Python (2)
Sorting image files with Python (3)
Sorting image files with Python
[Python] Send gmail with python: Send one by one with multiple image files attached
Replace all at once with sed
Convert memo at once with Python 2to3
Send newsletters all at once with Gmail
One liner webServer (with CGI) in python
Erase & generate serial number files with shell script
One liner to make Lena images with scipy
Update multiple tables at once with pandas to_sql
Upgrade all at once including dependencies with pip
Get corporate number at once via gbizinfo with python
Extract the table of image files with OneDrive & Python
Beginners try to convert Word files to PDF at once
Limits that can be analyzed at once with MeCab
Generate multiple HTML files at once by pouring JSON data into an HTML template with Python