more options for the formatting of entries in the static website
This commit is contained in:
parent
873679fcc6
commit
13f8e4fa65
@ -30,6 +30,9 @@ http://icculus.org/toby/
|
||||
http://iichantra.ru/en/
|
||||
http://insideastarfilledsky.net/
|
||||
http://lazerbears.wixsite.com/lazerbears/cr-editor
|
||||
https://github.com/vini-guerrero/Godot_Game_Tools
|
||||
https://github.com/nezvers/Godot_goodies
|
||||
https://github.com/eduard-permyakov/permafrost-engine
|
||||
http://libagar.org/agar/index.html.en
|
||||
http://libsdl-android.sourceforge.net/
|
||||
http://lukaszjakowski.pl/ (games apart from uMario)
|
||||
|
@ -2,6 +2,19 @@
|
||||
Generates the static website
|
||||
|
||||
Uses Jinja2 (see https://jinja.palletsprojects.com/en/2.11.x/)
|
||||
|
||||
Listing:
|
||||
|
||||
- title: top level title
|
||||
- items: list of items
|
||||
- anchor-id, name: title of each item
|
||||
- fields: list of fields in item
|
||||
- type: one of 'linebreak', 'text', 'enumeration'
|
||||
if type == 'text': // macro render_text
|
||||
content: the text to display
|
||||
class: the class of the text modifications (optional)
|
||||
if type == 'enumeration': // macro render_enumeration
|
||||
|
||||
"""
|
||||
|
||||
# TODO index.html tiles, content
|
||||
@ -47,12 +60,13 @@ games_path = 'games'
|
||||
inspirations_path = 'inspirations'
|
||||
developers_path = 'developers'
|
||||
|
||||
plurals = {k: k+'s' for k in ('Assets license', 'Contact', 'Code language', 'Code license', 'Developer', 'Download', 'Inspiration', 'Game', 'Home', 'Organization', 'Platform')}
|
||||
for k in ('Media', 'Play', 'Keyword'):
|
||||
plurals = {k: k+'s' for k in ('Assets license', 'Contact', 'Code language', 'Code license', 'Developer', 'Download', 'Inspiration', 'Game', 'Keyword', 'Home', 'Organization', 'Platform')}
|
||||
for k in ('Media', 'Play'):
|
||||
plurals[k] = k
|
||||
for k in ('Code repository', 'Code dependency'):
|
||||
plurals[k] = k[:-1] + 'ies'
|
||||
|
||||
|
||||
def get_plural_or_singular(name, amount):
|
||||
if not name in plurals.keys():
|
||||
raise RuntimeError('"{}" not a known singular!'.format(name))
|
||||
@ -60,9 +74,14 @@ def get_plural_or_singular(name, amount):
|
||||
return name
|
||||
return plurals[name]
|
||||
|
||||
|
||||
html5parser = html5lib.HTMLParser(strict=True)
|
||||
|
||||
|
||||
def raise_helper(msg):
|
||||
raise Exception(msg)
|
||||
|
||||
|
||||
def write(text, file):
|
||||
"""
|
||||
|
||||
@ -178,8 +197,7 @@ def preprocess(list, key, path):
|
||||
|
||||
def game_index(entry):
|
||||
e = {
|
||||
'name': entry['Title'],
|
||||
'href': entry['href'],
|
||||
'url': make_url(entry['href'], entry['Title']),
|
||||
'anchor-id': entry['anchor-id']
|
||||
}
|
||||
tags = []
|
||||
@ -188,35 +206,46 @@ def game_index(entry):
|
||||
if osg.is_inactive(entry):
|
||||
tags.append('inactive since {}'.format(osg.extract_inactive_year(entry)))
|
||||
if tags:
|
||||
e['tags'] = ', '.join(tags)
|
||||
e['tags'] = make_text('({})'.format(', '.join(tags)), 'is-light is-size-7')
|
||||
return e
|
||||
|
||||
|
||||
def inspiration_index(inspiration):
|
||||
e = {
|
||||
'name': inspiration['Name'],
|
||||
'href': inspiration['href'],
|
||||
'url': make_url(inspiration['href'], inspiration['Name']),
|
||||
'anchor-id': inspiration['anchor-id'],
|
||||
}
|
||||
n = len(inspiration['Inspired entries'])
|
||||
if n > 1:
|
||||
e['tags'] = n
|
||||
e['tags'] = make_text('({})'.format(n), 'is-light is-size-7')
|
||||
return e
|
||||
|
||||
|
||||
def make_url(href, text, css_class=None):
|
||||
url = {
|
||||
'type': 'url',
|
||||
'href': href,
|
||||
'text': make_text(text, css_class)
|
||||
}
|
||||
return url
|
||||
|
||||
|
||||
def developer_index(developer):
|
||||
e = {
|
||||
'name': developer['Name'],
|
||||
'href': developer['href'],
|
||||
'url': make_url(developer['href'], developer['Name']),
|
||||
'anchor-id': developer['anchor-id']
|
||||
}
|
||||
n = len(developer['Games'])
|
||||
if n > 1:
|
||||
e['tags'] = n
|
||||
e['tags'] = make_text('({})'.format(n), 'is-light is-size-7')
|
||||
return e
|
||||
|
||||
def shortcut_url(url):
|
||||
|
||||
# remove slash at the end
|
||||
if url.endswith('/'):
|
||||
url = url[:-1]
|
||||
|
||||
# gitlab
|
||||
gl_prefix = 'https://gitlab.com/'
|
||||
if url.startswith(gl_prefix):
|
||||
@ -256,17 +285,19 @@ def convert_inspirations(inspirations, entries):
|
||||
# media
|
||||
if 'Media' in inspiration:
|
||||
entries = inspiration['Media']
|
||||
entries = [{'href': url, 'name': shortcut_url(url)} for url in entries]
|
||||
entries = [make_url(url, shortcut_url(url)) for url in entries]
|
||||
field = {
|
||||
'name': 'Media',
|
||||
'type': 'enumeration',
|
||||
'name': make_text('Media'),
|
||||
'entries': entries
|
||||
}
|
||||
fields.append(field)
|
||||
# inspired entries (with links to them)
|
||||
inspired_entries = inspiration['Inspired entries']
|
||||
entries = [{'href': entries_references[entry], 'name': entry} for entry in inspired_entries]
|
||||
entries = [make_url(entries_references[entry], entry, 'has-text-weight-semibold') for entry in inspired_entries]
|
||||
field = {
|
||||
'name': 'Inspired {}'.format(get_plural_or_singular('Game', len(entries)).lower()),
|
||||
'type': 'enumeration',
|
||||
'name': make_text('Inspired {}'.format(get_plural_or_singular('Game', len(entries)).lower()), 'has-text-weight-semibold'),
|
||||
'entries': entries
|
||||
}
|
||||
fields.append(field)
|
||||
@ -274,30 +305,61 @@ def convert_inspirations(inspirations, entries):
|
||||
inspiration['name'] = inspiration['Name']
|
||||
|
||||
|
||||
def make_text(content, css_class=None):
|
||||
text = {
|
||||
'type': 'text',
|
||||
'text': content
|
||||
}
|
||||
if css_class:
|
||||
text['class'] = css_class
|
||||
return text
|
||||
|
||||
|
||||
def make_linebreak():
|
||||
return {
|
||||
'type': 'linebreak'
|
||||
}
|
||||
|
||||
def developer_profile_link(link):
|
||||
if link.endswith('@SF'):
|
||||
return 'https://sourceforge.net/u/{}/profile/'.format(link[:-3])
|
||||
if link.endswith('@GH'):
|
||||
return 'https://github.com/{}'.format(link[:-3])
|
||||
if link.endswith('@GL'):
|
||||
return 'https://gitlab.com/{}'.format(link[:-3])
|
||||
raise RuntimeError('Unknown profile link {}'.format(link))
|
||||
|
||||
def convert_developers(developers, entries):
|
||||
entries_references = {entry['Title']:entry['href'] for entry in entries}
|
||||
for developer in developers:
|
||||
fields = []
|
||||
# games field
|
||||
developed_entries = developer['Games']
|
||||
entries = [{'href': entries_references[entry], 'name': entry} for entry in developed_entries]
|
||||
entries = [make_url(entries_references[entry], entry, 'has-text-weight-semibold') for entry in developed_entries]
|
||||
field = {
|
||||
'name': 'Open source {}'.format(get_plural_or_singular('Game', len(entries))),
|
||||
'type': 'enumeration',
|
||||
'name': make_text('Developed {}'.format(get_plural_or_singular('Game', len(entries)).lower()), 'has-text-weight-semibold'),
|
||||
'entries': entries
|
||||
}
|
||||
fields.append(field)
|
||||
for field in c.optional_developer_fields:
|
||||
if field in developer:
|
||||
entries = developer[field]
|
||||
if field in c.url_developer_fields:
|
||||
entries = [{'href': entry, 'name': shortcut_url(entry)} for entry in entries]
|
||||
if field == 'Contact':
|
||||
# need to replace the shortcuts
|
||||
entries = [make_url(developer_profile_link(entry), entry) for entry in entries]
|
||||
elif field in c.url_developer_fields:
|
||||
entries = [make_url(entry, shortcut_url(entry)) for entry in entries]
|
||||
else:
|
||||
entries = [{'href': '', 'name': entry} for entry in entries]
|
||||
entries = [make_text(entry) for entry in entries]
|
||||
field = {
|
||||
'name': get_plural_or_singular(field, len(entries)),
|
||||
'type': 'enumeration',
|
||||
'name': make_text(get_plural_or_singular(field, len(entries))),
|
||||
'entries': entries
|
||||
}
|
||||
fields.append(field)
|
||||
if len(fields) > 1: # if there is Game(s) and more, insert an additional break after games
|
||||
fields.insert(1, make_linebreak())
|
||||
developer['fields'] = fields
|
||||
developer['name'] = developer['Name']
|
||||
|
||||
@ -310,8 +372,6 @@ def convert_entries(entries, inspirations, developers):
|
||||
for field in ('Home', 'Inspiration', 'Media', 'Download', 'Play', 'Developer', 'Keyword'):
|
||||
if field in entry:
|
||||
e = entry[field]
|
||||
if field == 'Inspiration':
|
||||
field = 'Inspiration' # TODO this is a bug, rename in entries
|
||||
if isinstance(e[0], osg.osg_parse.ValueWithComment):
|
||||
e = [x.value for x in e]
|
||||
if field == 'Inspiration':
|
||||
@ -335,8 +395,6 @@ def convert_entries(entries, inspirations, developers):
|
||||
e = entry[field]
|
||||
if not e:
|
||||
continue
|
||||
if field == 'Code dependency':
|
||||
field = 'Code dependency' # bug, rename field
|
||||
if isinstance(e[0], osg.osg_parse.ValueWithComment):
|
||||
e = [x.value for x in e]
|
||||
if field in c.url_fields:
|
||||
@ -351,6 +409,7 @@ def convert_entries(entries, inspirations, developers):
|
||||
entry['fields'] = fields
|
||||
entry['name'] = entry['Title']
|
||||
|
||||
|
||||
def add_license_links_to_entries(entries):
|
||||
for entry in entries:
|
||||
licenses = entry['Code license']
|
||||
@ -402,6 +461,7 @@ def generate(entries, inspirations, developers):
|
||||
# create Jinja Environment
|
||||
environment = Environment(loader=FileSystemLoader(c.web_template_path), autoescape=True)
|
||||
environment.globals['base'] = base
|
||||
environment.globals['raise'] = raise_helper
|
||||
|
||||
# multiple times used templates
|
||||
template_categorical_index = environment.get_template('categorical_index.jinja')
|
||||
@ -460,32 +520,32 @@ def generate(entries, inspirations, developers):
|
||||
'title': 'Games starting with {}'.format(letter.capitalize()),
|
||||
'items': games_by_alphabet[letter]
|
||||
}
|
||||
write(template_listing.render(listing=listing), os.path.join(games_path, '{}.html'.format(letter.capitalize())))
|
||||
# write(template_listing.render(listing=listing), os.path.join(games_path, '{}.html'.format(letter.capitalize())))
|
||||
|
||||
# generate games index
|
||||
index = divide_in_columns(games_by_alphabet, game_index)
|
||||
index['title'] = 'Games alphabetical index'
|
||||
index['title'] = 'Open source games - Alphabetical index'
|
||||
index['categories'] = extended_alphabet
|
||||
write(template_categorical_index.render(index=index), os.path.join(games_path, 'index.html'))
|
||||
|
||||
# genres
|
||||
base['active_nav'] = 'filter genres'
|
||||
index = divide_in_columns(games_by_genre, game_index)
|
||||
index['title'] = 'Games by genre'
|
||||
index['title'] = 'Open source games - Genre index'
|
||||
index['categories'] = genres
|
||||
write(template_categorical_index.render(index=index), os.path.join(games_path, 'genres.html'))
|
||||
|
||||
# games by language
|
||||
base['active_nav'] = 'filter code language'
|
||||
index = divide_in_columns(games_by_language, game_index)
|
||||
index['title'] = 'Games by language'
|
||||
index['title'] = 'Open source games - Programming language index'
|
||||
index['categories'] = c.known_languages
|
||||
write(template_categorical_index.render(index=index), os.path.join(games_path, 'languages.html'))
|
||||
|
||||
# games by platform
|
||||
base['active_nav'] = 'filter platforms'
|
||||
index = divide_in_columns(games_by_platform, game_index)
|
||||
index['title'] = 'Games by platform'
|
||||
index['title'] = 'Open source games - Supported platforms index'
|
||||
index['categories'] = c.valid_platforms + ('Unspecified',)
|
||||
write(template_categorical_index.render(index=index), os.path.join(games_path, 'platforms.html'))
|
||||
|
||||
@ -497,7 +557,7 @@ def generate(entries, inspirations, developers):
|
||||
|
||||
# inspirations index
|
||||
index = divide_in_columns(inspirations_by_alphabet, inspiration_index)
|
||||
index['title'] = 'Inspirations alphabetical index'
|
||||
index['title'] = 'Inspirations - Alphabetical index'
|
||||
index['categories'] = extended_alphabet
|
||||
write(template_categorical_index.render(index=index), os.path.join(inspirations_path, 'index.html'))
|
||||
|
||||
@ -516,14 +576,14 @@ def generate(entries, inspirations, developers):
|
||||
# developers single pages
|
||||
for letter in extended_alphabet:
|
||||
listing = {
|
||||
'title': 'Developers ({})'.format(letter.capitalize()),
|
||||
'title': 'Open source game developers ({})'.format(letter.capitalize()),
|
||||
'items': developers_by_alphabet[letter]
|
||||
}
|
||||
write(template_listing.render(listing=listing), os.path.join(developers_path, '{}.html'.format(letter.capitalize())))
|
||||
|
||||
# developers index
|
||||
index = divide_in_columns(developers_by_alphabet, developer_index)
|
||||
index['title'] = 'Developers alphabetical index'
|
||||
index['title'] = 'Open source game developers - Alphabetical index'
|
||||
index['categories'] = extended_alphabet
|
||||
write(template_categorical_index.render(index=index), os.path.join(developers_path, 'index.html'))
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
<link rel="stylesheet" href="{{ base['url_to']('css/bulma.min.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
{# navigation bar -#}
|
||||
<nav class="navbar container is-light" role="navigation" aria-label="main navigation">
|
||||
<div class="navbar-menu">
|
||||
<div class="navbar-start">
|
||||
@ -29,7 +30,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
{# content block -#}
|
||||
{% block content %}{% endblock %}
|
||||
{# footer -#}
|
||||
<footer class="footer">
|
||||
<div class="container is-size-7">
|
||||
<a href="https://trilarion.blogspot.com/search/label/osgames">Blog</a><br>
|
||||
|
@ -4,9 +4,9 @@
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="box">
|
||||
<div class="block"><h1 class="title">{{ index['title'] }}</h1></div>
|
||||
<div class="block"><h1 class="title is-size-4">{{ index['title'] }}</h1></div>
|
||||
{% set comma = joiner(", ") %}
|
||||
<div class="is-size-4">
|
||||
<div class="is-size-5">
|
||||
{% for category in index['categories'] -%}
|
||||
{{ comma() }} <a href="#{{ category }}" class="has-text-weight-semibold">{{ category }}</a> ({{ index['number_entries'][category] }})
|
||||
{%- endfor %}
|
||||
@ -20,7 +20,7 @@
|
||||
<div class="column">
|
||||
<ul>
|
||||
{% for entry in entries_column %}
|
||||
<li>{{ macros.url(entry['href'], entry['name']) }} {% if 'tags' in entry %}<span class="is-light is-size-7">({{ entry['tags'] }})</span>{% endif %}</li>
|
||||
<li>{{ macros.render_url(entry['url']) }} {% if 'tags' in entry %}{{ macros.render_text(entry['tags']) }}{% endif %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -3,8 +3,10 @@
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">{{ listing['title'] }}</h1>
|
||||
{# iterate over items -#}
|
||||
{% for item in listing['items'] %}
|
||||
<div class="box">
|
||||
{# item header with anchor, name and link to contribute -#}
|
||||
<nav class="level is-mobile">
|
||||
<div class="level-left">
|
||||
<h2 id="{{ item['anchor-id'] }}" class="title is-4">{{ item['name'] }}</h2>
|
||||
@ -13,10 +15,19 @@
|
||||
<p class="level-item"><a href="{{ base['url_to']('contribute.html') }}">Edit</a></p>
|
||||
</div>
|
||||
</nav>
|
||||
{% for field in item['fields'] %}{% set comma = joiner(", ") %}
|
||||
{{ macros.listing_field_title(field['title']) }}{% for entry in field['entries'] %}{{ comma() }}{{ macros.url(entry['href'], entry['name']) }}{% endfor %}<br>
|
||||
{# iterate over fields -#}
|
||||
{% for field in item['fields'] %}
|
||||
{% if field['type'] == 'text' %}
|
||||
{{ macros.render_text(field) }}
|
||||
{% elif field['type'] == 'enumeration' %}
|
||||
{{ macros.render_enumeration(field) }}
|
||||
{% elif field['type'] == 'linebreak' %}
|
||||
{% else %}
|
||||
{{ raise('Unknown field type.') }}
|
||||
{% endif %}
|
||||
<br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<a class="is-light is-size-7" href="#">Back to top</a>
|
||||
</div>
|
||||
|
@ -1,13 +1,31 @@
|
||||
{% macro url(href, name) -%}
|
||||
{% if href %}
|
||||
<a href="{{ base['url_to'](href) }}">{{ name }}</a>
|
||||
{% else %}
|
||||
{{ name }}
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
{# A single line of text with a line break at the end and optionally a format class. (see https://bulma.io/documentation/helpers/typography-helpers/) #}
|
||||
{%- macro render_text(text) -%}
|
||||
{%- if 'class' in text -%} {# Enhanced text #}
|
||||
<span class="{{ text['class'] }}">{{ text['text'] }}</span>
|
||||
{%- else -%}
|
||||
{{ text['text'] }}
|
||||
{%- endif -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{# Some text surrounded by a link tag #}
|
||||
{%- macro render_url(url) -%}
|
||||
<a href="{{ base['url_to'](url['href']) }}">{{ render_text(url['text']) }}</a>
|
||||
{%- endmacro -%}
|
||||
|
||||
{# Renders either plain text or a link depending on the type #}
|
||||
{%- macro render_enumeration_entry(entry) -%}
|
||||
{%- if entry['type'] == 'text' -%}
|
||||
{{ render_text(entry) }}
|
||||
{%- elif entry['type'] == 'url' -%}
|
||||
{{ render_url(entry) }}
|
||||
{%- else -%}
|
||||
{{ raise('Unknown entry type.') }}
|
||||
{%- endif -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{# Renders a list of enumeration entries (either links or text) #}
|
||||
{%- macro render_enumeration(enumeration) -%}
|
||||
{%- set comma = joiner(", ") -%}
|
||||
{{ render_text(enumeration['name']) }}: {% for entry in enumeration['entries'] -%}{{ comma() }}{{ render_enumeration_entry(entry) }}{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
|
||||
{% macro listing_field_title(title) -%}
|
||||
{% if title %}
|
||||
{{ title['name'] }}:
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
@ -118,7 +118,7 @@ general_code_dependencies_without_entry = {'OpenGL': 'https://www.opengl.org/',
|
||||
|
||||
# developer information (in the file all fields will be capitalized)
|
||||
essential_developer_fields = ('Name', 'Games')
|
||||
optional_developer_fields = ('Contact', 'Home', 'Organization')
|
||||
optional_developer_fields = ('Home', 'Contact', 'Organization')
|
||||
valid_developer_fields = essential_developer_fields + optional_developer_fields
|
||||
url_developer_fields = ('Home',)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user