Templating Button Pages With Jinja2

Batch Way

For a while I used a batch one-liner to generate the image links on the 88x31 button page. If you have a directory full of images you want to show via HTML this is a quick and easy way to do it from the command line.

for %i in (*.*) do echo ^<a href="//%~ni.neocities.org/"^>^<img src="/images/buttons/neocitizens/%i" alt="%~ni"/^>^</a^>>> all.html

Last month I decided I wanted to start preserving multiple buttons for each citizen, so I started naming extra buttons citizen_2.gif, citizen_3.gif, and so on. I couldn't find a sexy batch one-liner for url correction, so I corrected the urls after the fact with some regex find/replace:

  Find :-[0-9]+.neocities.org
  Replace: .neocities.org

Getting the citizen population was a bit fiddly. I had a second operation where I isolate the usernames then remove the duplicate lines:

    for %i in (*.*) do echo (%~ni) >> usernames.html
    Find/replace: (.*?)$\s+?^(?=.*^\1$)

Jinja2 Way (This is the way)

After I learned to use Jinja2 templates and realized how easy that was, I decided to create a template for the button page. Big improvement.

  <h2>NeoCitizens, population: {{population}}</h2>

  {% for citizen, button_list in buttons.items() %}
    {% for button in button_list %}
        <a href="//{{citizen}}.neocities.org">  <img src="/images/buttons/neocitizens/{{button}}" alt="{{citizen}}"/>  </a>
    {% endfor %}
  {% endfor %}
  

For the data, I use the neocitizen name as a key and the value is a list of buttons. This lets me have a citizen population count by simply counting the keys.

  # 88x31-builder.py

  import os
  from jinja2 import Environment, FileSystemLoader
  import datetime

  def inject_today_date():
      return datetime.date.today()

  def print_html_doc():
      j2_env = Environment(loader=FileSystemLoader('cyber'),trim_blocks=True)
      template = j2_env.get_template('88x31_template.j2')
      rendered_template = template.render(buttons=buttons,population=population,today_date=today_date)
      with open('cyber/88x31.html', 'w') as f:
          f.write(rendered_template)

  buttons = {}
  button_path = "images/buttons/neocitizens/"
  for file in os.listdir(button_path):
      if os.path.isfile(os.path.join(button_path, file)):
          if "_" in file:
              s = file.split("_")
          else:
              s = file.split(".")
          subdomain = s[0]
          if subdomain in buttons.keys():
              buttons[subdomain].append(file)
          else:
              buttons[subdomain] = [file]

  population = len(buttons.keys())
  today_date = inject_today_date()
  print_html_doc()
  

It probably saves me 5 to 10 minutes each time I update the archive.