various website tweaks (tiny bit of javascript for mobile users), added freee
This commit is contained in:
@ -10,20 +10,20 @@
|
||||
<link rel="stylesheet" href="{{ base['url_to'](['css', 'bulma.min.css']) }}">
|
||||
<link rel="stylesheet" href="{{ base['url_to'](['css', 'osgl.min.css']) }}">
|
||||
<link rel="icon" type="image/svg+xml" href="{{ base['url_to'](['favicon.svg']) }}">
|
||||
<script type="text/javascript" src="{{ base['url_to'](['js', 'osgl.js']) }}"></script>
|
||||
</head>
|
||||
<body>
|
||||
{#- navigation bar -#}
|
||||
<nav class="navbar container is-light" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item{% if 'index' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['index.html']) }}">{{ macros.render_icon({'class':'home'}) }}<span>OSGL</span></a>
|
||||
<a class="navbar-item" href="https://github.com/Trilarion/opensourcegames">{{ macros.render_icon({'class':'github'}) }}<span>On GitHub</span></a>
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navbarMenu">
|
||||
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="navMenu">
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
<span aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-menu is-active">
|
||||
<div class="navbar-menu" id="navMenu">
|
||||
<div class="navbar-start">
|
||||
<a class="navbar-item{% if 'games' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['games', 'index.html']) }}">{{ macros.render_icon({'class':'dice'}) }}<span>Games</span></a>
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
@ -40,22 +40,21 @@
|
||||
<a class="navbar-item{% if 'inspirations' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['inspirations', 'index.html']) }}">{{ macros.render_icon({'class':'bulb'}) }}<span>Inspirations</span></a>
|
||||
<a class="navbar-item{% if 'statistics' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['statistics.html']) }}">{{ macros.render_icon({'class':'stats-dots'}) }}<span>Statistics</span></a>
|
||||
<a class="navbar-item{% if 'contribute' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['contribute.html']) }}">{{ macros.render_icon({'class':'pencil'}) }}<span>Contribute</span></a>
|
||||
<a class="navbar-item" href="https://github.com/Trilarion/opensourcegames">{{ macros.render_icon({'class':'github'}) }}<span>On GitHub</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
{#- content block -#}
|
||||
{% block content %}{% endblock %}
|
||||
{#- footer -#}
|
||||
<footer class="footer">
|
||||
<div class="container content is-size-7">
|
||||
<p>The <a href="https://github.com/Trilarion/opensourcegames">Open source games list (OSGL)</a> is a collection of open source game descriptions focusing on technical aspects.
|
||||
The content on this site is the result of voluntary work and may be outdated or incorrect.<br>
|
||||
For giving feedback or improving the content see the <a href="contribute.html">contribution guidelines</a> or read the <a href="https://trilarion.blogspot.com/search/label/osgames">Blog</a>.</p>
|
||||
<p>The content (games descriptions) is licensed <a href="https://github.com/Trilarion/opensourcegames/blob/master/LICENSE">CC-0</a>.
|
||||
Used icons are licensed under CC BY-SA 3.0 (<a href="https://github.com/somerandomdude/Iconic">Iconic</a> or <a href="http://designmodo.com/linecons-free/">Linecons</a>), CC0 1.0 (<a href="https://simpleicons.org/">Simple Icons</a>),
|
||||
CC BY 4.0 (<a href="https://github.com/FortAwesome/Font-Awesome">Font Awesome</a> or <a href="https://icomoon.io/#icons-icomoon">IcoMoon Free</a>), CC BY-SA 4.0 (<a href="http://www.entypo.com/">Entypo+</a>) or Apache License 2.0 (<a href="https://material.io/resources/icons">Material Icons</a>).
|
||||
This website is built using Python, Lark, Jinja2 and Bulma. Last updated: {{ base['creation-date'] }}</p>
|
||||
</div>
|
||||
<footer class="footer container content is-size-7">
|
||||
<p>The <a href="https://github.com/Trilarion/opensourcegames">Open source games list (OSGL)</a> is a collection of open source game descriptions focusing on technical aspects.
|
||||
The content on this site is the result of voluntary work and may be outdated or incorrect. For giving feedback or improving the content see the
|
||||
<a href="contribute.html">contribution guidelines</a> or read the <a href="https://trilarion.blogspot.com/search/label/osgames">Blog</a>.</p>
|
||||
<p>The content (games descriptions) is licensed <a href="https://github.com/Trilarion/opensourcegames/blob/master/LICENSE">CC-0</a>.
|
||||
Used icons are licensed under CC BY-SA 3.0 (<a href="https://github.com/somerandomdude/Iconic">Iconic</a> or <a href="http://designmodo.com/linecons-free/">Linecons</a>), CC0 1.0 (<a href="https://simpleicons.org/">Simple Icons</a>),
|
||||
CC BY 4.0 (<a href="https://github.com/FortAwesome/Font-Awesome">Font Awesome</a> or <a href="https://icomoon.io/#icons-icomoon">IcoMoon Free</a>), CC BY-SA 4.0 (<a href="http://www.entypo.com/">Entypo+</a>) or Apache License 2.0 (<a href="https://material.io/resources/icons">Material Icons</a>).
|
||||
This website is built using Python, Lark, Jinja2 and Bulma. Last updated: {{ base['creation-date'] }}</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
@ -1,35 +1,36 @@
|
||||
{% extends "base.jinja" %}
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="box">
|
||||
{#- title and subtitle -#}
|
||||
<div class="block">
|
||||
<h1 class="title">{{ macros.render_element(index['title']) }}</h1>
|
||||
{%- if 'subtitle' in index -%}
|
||||
<h2 class="subtitle">{{ macros.render_element(index['subtitle']) }}</h2>
|
||||
{%- endif -%}
|
||||
<p class="title is-4">{{ macros.render_element(index['title']) }}</p>
|
||||
{%- if 'subtitle' in index %}<p class="subtitle is-6">{{ macros.render_element(index['subtitle']) }}</p>{% endif -%}
|
||||
</div>
|
||||
{#- index of the categories -#}
|
||||
{#- index of the categories as tags -#}
|
||||
<div class="tags">
|
||||
{% for category in index['categories'] -%}
|
||||
<span class="tag is-white {% if index['number_entries'][category] > index['number_entries_per_category_threshold'] %}is-size-5{% else %}is-size-6{% endif %}">
|
||||
<a href="#{{ category.lower() }}" class="has-text-weight-semibold mr-1">{{ macros.render_element(index['category-names'][category]) }}</a> <span class="has-text-grey">({{ index['number_entries'][category] }})</span>
|
||||
{%- if category in index['category-icons'] %}{{ macros.render_element(index['category-icons'][category]) }}{% endif -%}
|
||||
<a href="#{{ category.lower() }}" class="has-text-weight-semibold">{{ macros.render_element(index['category-names'][category]) }}</a> <span class="has-text-grey">({{ index['number_entries'][category] }})</span>
|
||||
</span>
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{#- each of the categories -#}
|
||||
{#- each of the categories one box -#}
|
||||
{% for category in index['categories'] %}
|
||||
<div class="box">
|
||||
<div id="{{ category.lower() }}" class="box">
|
||||
<div class="block">
|
||||
<h2 id="{{ category.lower() }}" class="is-size-4 has-text-weight-semibold">{{ macros.render_element(index['category-names'][category]) }}</h2>
|
||||
{%- if category in index['category-infos'] -%}{{ macros.render_element(index['category-infos'][category]) }}{%- endif -%}
|
||||
{%- if category in index['category-icons'] %}{{ macros.render_element(index['category-icons'][category]) }}{% endif -%}
|
||||
<span class="title is-4">{{ macros.render_element(index['category-names'][category]) }}</span>
|
||||
{%- if category in index['category-infos'] -%}<br>{{ macros.render_element(index['category-infos'][category]) }}{%- endif -%}
|
||||
</div>
|
||||
<div class="columns">
|
||||
{#- each of the entry sets one column -#}
|
||||
{%- for entries_column in index['entries'][category] -%}
|
||||
<div class="column">
|
||||
<ul>
|
||||
{#- for each entry one link -#}
|
||||
{%- for entry in entries_column -%}
|
||||
<li>{%- if index['entry_bold'](entry) -%}<span class="has-text-weight-semibold">{%- endif -%}
|
||||
{{ macros.render_element(entry['url']) }}{%- if 'tags' in entry -%}{{ macros.render_element(entry['tags']) }}{%- endif -%}
|
||||
@ -39,9 +40,8 @@
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
<a class="is-light is-size-7" href="#">Back to top</a>
|
||||
<p class="is-size-7 has-text-right"><a href="#">Back to top</a></p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
@ -3,20 +3,13 @@ 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
|
||||
Sitemaps is not needed, only for large projects with lots of JavaScript und many undiscoverable pages.
|
||||
|
||||
"""
|
||||
|
||||
# TODO most people only come to the main page, put more information there (direct links to genres, ...)
|
||||
# TODO put more explanations on the category pages and the categories (number and short sentences)
|
||||
|
||||
# TODO game engines should be sorted with frameworks/tools, not with games (they aren't games or are they?)
|
||||
|
||||
# TODO if the only change is a change in last updated, do not change it (we can probably check with git diff for it) or checksums
|
||||
@ -31,7 +24,7 @@ Listing:
|
||||
# TODO everywhere: singular, plural (game, entries, items)
|
||||
|
||||
# TODO statistics: better and more statistics with links where possible
|
||||
# TODO statistics: with nice graphics (pie charts in SVG) with matplotlib, seaborn, plotly?
|
||||
# TODO statistics: with nice graphics (pie charts in SVG) with matplotlib
|
||||
# TODO statistics: get it from common statistics generator
|
||||
|
||||
# TODO frameworks: icons for frameworks/libraries/tools
|
||||
@ -41,6 +34,7 @@ Listing:
|
||||
# TODO games: @see-home/@see-download/@add (ignore or replace?)
|
||||
# TODO games: top 50 list from Github via their stars with download links (add to entries) and with screenshot
|
||||
# TODO games: add screenshot ability (add screenshot to database, at least for top 50)
|
||||
# TODO games: order: homepage, inspiration, download, developer
|
||||
|
||||
# TODO update Bulma
|
||||
|
||||
@ -55,8 +49,6 @@ Listing:
|
||||
# TODO games: javascript table
|
||||
# TODO games: repositories comments have too much space after( and before )
|
||||
|
||||
# TODO add sitemap
|
||||
|
||||
# TODO mobile view: optimize layout for mobile view
|
||||
|
||||
# TODO languages: C# redirects to C
|
||||
@ -65,7 +57,9 @@ Listing:
|
||||
|
||||
# TODO categories: use icon-text as in https://bulma.io/documentation/elements/icon/ instead of is-large
|
||||
|
||||
# TODO info: show only first line of info (which should be a short description if present)
|
||||
# TODO meta description of the pages, fill them
|
||||
|
||||
# TODO info: show only first line of info (which should be a short description or make it a field (only for popular ones), otherwise rely on keywords)
|
||||
|
||||
# TODO developers: anchors to non-latin written developers do not work (chinese names have simply xxxxx)
|
||||
|
||||
@ -74,7 +68,11 @@ Listing:
|
||||
# TODO Google search console
|
||||
# TODO <a> rel attribute https://www.w3schools.com/TAGS/att_a_rel.asp
|
||||
|
||||
# TODO inspirations: if included in the database, link instead to game
|
||||
# TODO inspirations: if included in the database, link instead to game (cross-reference)
|
||||
|
||||
# TODO cross-references for code dependencies if included
|
||||
|
||||
# TODO add dynamic table (what to include)
|
||||
|
||||
import os
|
||||
import shutil
|
||||
@ -86,18 +84,24 @@ from utils import osg, constants as c, utils
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
import html5lib
|
||||
|
||||
# the categories for the alphabetical indices, letters A-Z, used for identification and as link names internally
|
||||
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
# the internal category name for all names not starting with a letter
|
||||
extra = '0'
|
||||
extended_alphabet = alphabet + extra
|
||||
extended_alphabet_names = {k: k for k in extended_alphabet}
|
||||
alphabet_replacements = {'Á': 'A', 'Å': 'A', 'É': 'E', 'Ł': 'L', 'Ľ': 'L', 'А': 'A', 'Б': 'B', 'Д': 'D', 'И': 'I', 'К': 'K', 'П': 'P'}
|
||||
|
||||
# and how they are displayed
|
||||
extended_alphabet_names = {k: k for k in alphabet}
|
||||
extended_alphabet_names[extra] = '0-9'
|
||||
# especially for developers, replacements from other alphabets
|
||||
alphabet_replacements = {'Á': 'A', 'Å': 'A', 'Ä': 'A', 'É': 'E', 'ⴹ': 'E', 'Ł': 'L', 'Ľ': 'L', 'А': 'A', 'Б': 'B', 'Д': 'D', 'И': 'I', 'К': 'K', 'П': 'P', 'Ö': 'O', 'Ü': 'U', 'ζ': 'Z'}
|
||||
|
||||
# the subfolder structure
|
||||
games_path = ['games']
|
||||
frameworks_path = ['frameworks']
|
||||
inspirations_path = ['inspirations']
|
||||
developers_path = ['developers']
|
||||
|
||||
# derived paths
|
||||
games_index_path = games_path + ['index.html']
|
||||
frameworks_index_path = frameworks_path + ['index.html']
|
||||
inspirations_index_path = inspirations_path + ['index.html']
|
||||
@ -108,6 +112,7 @@ games_by_genres_path = games_path + ['genres.html']
|
||||
games_by_platform_path = games_path + ['platforms.html']
|
||||
games_top50_path = games_path + ['top50.html']
|
||||
|
||||
# TODO currently not used, use?
|
||||
platform_color = {
|
||||
'Windows': 'is-danger',
|
||||
'Linux': 'is-link',
|
||||
@ -117,6 +122,7 @@ platform_color = {
|
||||
'Web': 'is-warning',
|
||||
}
|
||||
|
||||
# map from supported OS name to icon name
|
||||
platform_icon_map = {
|
||||
'Windows': 'windows',
|
||||
'Linux': 'tux',
|
||||
@ -127,6 +133,7 @@ platform_icon_map = {
|
||||
'Unspecified': 'device_unknown'
|
||||
}
|
||||
|
||||
# map from genre name to icon name
|
||||
genre_icon_map = {
|
||||
'Action': 'target',
|
||||
'Adventure': 'dice',
|
||||
@ -145,16 +152,31 @@ genre_icon_map = {
|
||||
'Library': 'library'
|
||||
}
|
||||
|
||||
# cross-references to the langue pages
|
||||
code_language_references = {l: games_by_language_path[:-1] + ['{}#{}'.format(games_by_language_path[-1], osg.canonical_name(l))] for l in c.known_languages}
|
||||
|
||||
# map of internal framework names to display names (which are in plural)
|
||||
framework_names = {
|
||||
'tool': 'Tools',
|
||||
'framework': 'Frameworks',
|
||||
'library': 'Libraries'
|
||||
}
|
||||
|
||||
# we check the output html structure every time
|
||||
html5parser = html5lib.HTMLParser(strict=True)
|
||||
|
||||
# pluralization (mostly with s, but there are a few exceptions)
|
||||
plurals = {k: k+'s' for k in ('Assets license', 'Contact', 'Code language', 'Code license', 'Developer', 'Download', 'Inspiration', 'Game', 'Keyword', 'Home', 'Homepage', 'Organization', 'Platform', 'Tag')}
|
||||
for k in ('Media', 'Play', 'Play online', 'State'):
|
||||
plurals[k] = k
|
||||
for k in ('Code repository', 'Code dependency'):
|
||||
plurals[k] = k[:-1] + 'ies'
|
||||
|
||||
code_language_references = {l: games_by_language_path[:-1] + ['{}#{}'.format(games_by_language_path[-1], osg.canonical_name(l))] for l in c.known_languages}
|
||||
|
||||
|
||||
def get_plural_or_singular(name, amount):
|
||||
"""
|
||||
Gets the pluarization of a known word for a known amount. Helper function.
|
||||
"""
|
||||
if not name in plurals.keys():
|
||||
raise RuntimeError('"{}" not a known singular!'.format(name))
|
||||
if amount == 1:
|
||||
@ -162,27 +184,17 @@ def get_plural_or_singular(name, amount):
|
||||
return plurals[name]
|
||||
|
||||
|
||||
framework_names = {
|
||||
'tool': 'Tools',
|
||||
'framework': 'Frameworks',
|
||||
'library': 'Libraries'
|
||||
}
|
||||
|
||||
|
||||
html5parser = html5lib.HTMLParser(strict=True)
|
||||
|
||||
|
||||
def raise_helper(msg):
|
||||
"""
|
||||
Helper, because raise in lambda expression is a bit cumbersome.
|
||||
(ref. https://stackoverflow.com/questions/8294618/define-a-lambda-expression-that-raises-an-exception)
|
||||
"""
|
||||
raise Exception(msg)
|
||||
|
||||
|
||||
def is_list(obj):
|
||||
return isinstance(obj, list)
|
||||
|
||||
|
||||
def write(text, file):
|
||||
"""
|
||||
|
||||
Writes a generated HTML page to a file, but checks with a HTML parser before.
|
||||
:param text:
|
||||
:param file:
|
||||
"""
|
||||
@ -193,7 +205,7 @@ def write(text, file):
|
||||
html5parser.parse(text)
|
||||
except Exception as e:
|
||||
utils.write_text(os.path.join(c.web_path, 'invalid.html'), text) # for further checking with https://validator.w3.org/
|
||||
print('probem with file {}, see invalid.html'.format(file))
|
||||
print('problem with file {}, see invalid.html'.format(file))
|
||||
raise RuntimeError(e)
|
||||
# output file
|
||||
file = os.path.join(c.web_path, *file)
|
||||
@ -205,31 +217,29 @@ def write(text, file):
|
||||
utils.write_text(file, text)
|
||||
|
||||
|
||||
def sort_into_categories(list, categories, fit, unknown_category_name=None):
|
||||
def sort_into_categories(items, categories, fit, unknown_category_name=None):
|
||||
"""
|
||||
Given a list of items and a list of categories and a way to determine if an item fits into a category creates
|
||||
lists of items fitting in each category as well as a list of items that fit in no category.
|
||||
|
||||
:param list:
|
||||
:param categories:
|
||||
:param fit:
|
||||
:param unknown_category_name:
|
||||
:return:
|
||||
:return: A mapping category (or unknown_category_name) -> sub-list of items in that category
|
||||
"""
|
||||
categorized_sublists = {}
|
||||
for category in categories:
|
||||
sublist = [item for item in list if fit(item, category)]
|
||||
sublist = [item for item in items if fit(item, category)]
|
||||
categorized_sublists[category] = sublist
|
||||
if unknown_category_name:
|
||||
# now those that do not fit
|
||||
sublist = [item for item in list if not any(fit(item, category) for category in categories)]
|
||||
sublist = [item for item in items if not any(fit(item, category) for category in categories)]
|
||||
categorized_sublists[unknown_category_name] = sublist
|
||||
return categorized_sublists
|
||||
|
||||
|
||||
def divide_in_columns(categorized_lists, transform):
|
||||
def divide_in_three_columns_and_transform(categorized_lists, transform):
|
||||
"""
|
||||
|
||||
Used for creating table of content pages for the entries.
|
||||
:param transform:
|
||||
:param categorized_lists:
|
||||
:param key:
|
||||
:return:
|
||||
"""
|
||||
number_entries = {category: len(categorized_lists[category]) for category in categorized_lists.keys()}
|
||||
@ -405,9 +415,9 @@ def make_repo_url(x, name):
|
||||
if len(c) > 1:
|
||||
value = c[1]
|
||||
if key == 'archived':
|
||||
comments.append(make_text('archived', css_class='is-size-7'))
|
||||
comments.append(make_text('archived'))
|
||||
if key == 'created':
|
||||
comments.append(make_text('since {}'.format(value), css_class='is-size-7'))
|
||||
comments.append(make_text('since {}'.format(value)))
|
||||
if key == 'stars':
|
||||
value = int(value)
|
||||
if value > 200:
|
||||
@ -417,7 +427,7 @@ def make_repo_url(x, name):
|
||||
else:
|
||||
comments.append(make_icon('star-o', 'low rated'))
|
||||
# this is the default element
|
||||
url = make_url(x.value, shortcut_url(x.value, name), css_class='is-size-7')
|
||||
url = make_url(x.value, shortcut_url(x.value, name))
|
||||
if comments:
|
||||
return make_enumeration([url, make_enclose(make_enumeration(comments), '(', ')')], '')
|
||||
else:
|
||||
@ -477,19 +487,25 @@ def make_tags(entries):
|
||||
|
||||
|
||||
def developer_profile_link(link):
|
||||
"""
|
||||
Creates links to developer profiles.
|
||||
|
||||
:param link: Shortcut link from the developer contact field.
|
||||
:return: A URL to a profile page.
|
||||
"""
|
||||
if link.endswith('@SF'):
|
||||
return make_url('https://sourceforge.net/u/{}/profile/'.format(link[:-3]), make_icon('sourceforge'), 'Profile on Sourceforge')
|
||||
return make_url('https://sourceforge.net/u/{}/profile/'.format(link[:-3]), make_icon('sourceforge'), 'User {} on Sourceforge'.format(link[:-3]))
|
||||
if link.endswith('@GH'):
|
||||
return make_url('https://github.com/{}'.format(link[:-3]), make_icon('github'), 'Profile on Github')
|
||||
return make_url('https://github.com/{}'.format(link[:-3]), make_icon('github'), 'User {} on Github'.format(link[:-3]))
|
||||
if link.endswith('@GL'):
|
||||
return make_url('https://gitlab.com/{}'.format(link[:-3]), make_icon('gitlab'), 'Profile on Gitlab')
|
||||
return make_url('https://gitlab.com/{}'.format(link[:-3]), make_icon('gitlab'), 'User {} on Gitlab'.format(link[:-3]))
|
||||
if link.endswith('@BB'):
|
||||
return make_url('https://bitbucket.org/{}/'.format(link[:-3]), make_icon('bitbucket'), 'Profile on BitBucket')
|
||||
return make_url('https://bitbucket.org/{}/'.format(link[:-3]), make_icon('bitbucket'), 'User {} on BitBucket'.format(link[:-3]))
|
||||
raise RuntimeError('Unknown profile link {}'.format(link))
|
||||
|
||||
|
||||
def convert_inspirations(inspirations, entries):
|
||||
entries_references = {entry['Title']:entry['href'] for entry in entries}
|
||||
entries_references = {entry['Title']: entry['href'] for entry in entries}
|
||||
for inspiration in inspirations:
|
||||
name = inspiration['Name']
|
||||
inspiration['name'] = name
|
||||
@ -502,7 +518,7 @@ def convert_inspirations(inspirations, entries):
|
||||
|
||||
# inspired entries (with links to them)
|
||||
inspired_entries = inspiration['Inspired entries']
|
||||
entries = [make_url(entries_references[entry], make_text(entry, 'has-text-weight-semibold')) for entry in inspired_entries]
|
||||
entries = [make_url(entries_references[entry], make_text(entry)) for entry in inspired_entries]
|
||||
name = make_text('Inspired {}: '.format(get_plural_or_singular('Game', len(entries)).lower()), 'has-text-weight-semibold')
|
||||
inspiration['inspired'] = [name, make_enumeration(entries)]
|
||||
|
||||
@ -515,8 +531,8 @@ def convert_developers(developers, entries):
|
||||
|
||||
# games
|
||||
developed_entries = developer['Games']
|
||||
entries = [make_url(entries_references[entry], make_text(entry, 'has-text-weight-semibold')) for entry in developed_entries]
|
||||
name = make_text('Developed {}:'.format(get_plural_or_singular('Game', len(entries)).lower()), 'has-text-weight-semibold')
|
||||
entries = [make_url(entries_references[entry], make_text(entry)) for entry in developed_entries]
|
||||
name = make_text('Developed {}: '.format(get_plural_or_singular('Game', len(entries)).lower()), 'has-text-weight-semibold')
|
||||
developer['games'] = [name, make_enumeration(entries)]
|
||||
|
||||
# contacts
|
||||
@ -537,7 +553,7 @@ def convert_developers(developers, entries):
|
||||
|
||||
def create_keyword_tag(keyword):
|
||||
if keyword in c.recommended_keywords:
|
||||
if keyword in c.framework_keywords:
|
||||
if keyword in c.non_game_keywords:
|
||||
url = frameworks_index_path.copy()
|
||||
else:
|
||||
url = games_by_genres_path.copy()
|
||||
@ -553,14 +569,14 @@ def create_keyword_tag(keyword):
|
||||
def create_state_texts(states):
|
||||
texts = []
|
||||
if 'mature' in states:
|
||||
texts.append(make_text('mature', 'is-size-7 has-text-weight-bold has-text-info'))
|
||||
texts.append(make_text('mature', 'has-text-weight-bold'))
|
||||
else:
|
||||
texts.append(make_text('beta', 'is-size-7 has-text-gray-lighter'))
|
||||
texts.append(make_text('beta'))
|
||||
inactive = [x for x in states if x.startswith('inactive since')]
|
||||
if inactive:
|
||||
texts.append([make_text(inactive[0], 'is-size-7 has-text-gray-lighter'), make_icon('brightness_3')])
|
||||
texts.append([make_text(inactive[0], ''), make_icon('brightness_3')])
|
||||
else:
|
||||
texts.append([make_text('active', 'is-size-7 has-text-weight-bold has-text-info'), make_icon('sun')])
|
||||
texts.append([make_text('active', 'has-text-weight-bold'), make_icon('sun')])
|
||||
return texts
|
||||
|
||||
|
||||
@ -591,12 +607,12 @@ def convert_entries(entries, inspirations, developers):
|
||||
if isinstance(e[0], osg.osg_parse.ValueWithComment):
|
||||
e = [x.value for x in e]
|
||||
if field == 'Inspiration':
|
||||
e = [make_url(inspirations_references[x], make_text(x, 'has-text-weight-semibold')) for x in e]
|
||||
e = [make_url(inspirations_references[x], make_text(x)) for x in e]
|
||||
elif field == 'Developer':
|
||||
if len(e) > 10: # many devs, print smaller
|
||||
e = [make_url(developer_references[x], make_text(x, 'has-text-weight-semibold is-size-7')) for x in e]
|
||||
e = [make_url(developer_references[x], make_text(x, 'is-size-7')) for x in e]
|
||||
else:
|
||||
e = [make_url(developer_references[x], make_text(x, 'has-text-weight-semibold')) for x in e]
|
||||
e = [make_url(developer_references[x], make_text(x)) for x in e]
|
||||
elif field in c.url_fields:
|
||||
e = [make_url(x, shortcut_url(x, name)) for x in e]
|
||||
else:
|
||||
@ -605,7 +621,7 @@ def convert_entries(entries, inspirations, developers):
|
||||
field = 'Homepage'
|
||||
elif field == 'Play': # Play -> Play online
|
||||
field = 'Play online'
|
||||
namex = make_text('{}: '.format(get_plural_or_singular(field, len(e))), 'has-text-weight-semibold')
|
||||
namex = make_text('{}: '.format(get_plural_or_singular(field, len(e))))
|
||||
entry[field.lower()] = [namex, make_enumeration(e, divider)]
|
||||
|
||||
# platforms
|
||||
@ -615,9 +631,10 @@ def convert_entries(entries, inspirations, developers):
|
||||
e = [x.value for x in e]
|
||||
else:
|
||||
e = ['Unspecified']
|
||||
e = [make_url(games_by_platform_path[:-1] + ['{}#{}'.format(games_by_platform_path[-1], x.lower())], make_icon(platform_icon_map[x]), x) if x in platform_icon_map else make_text(x, 'is-size-7') for x in e]
|
||||
namex = make_text('{}:'.format(get_plural_or_singular('Platform', len(e))), 'has-text-weight-semibold')
|
||||
entry['platform'] = [namex] + e
|
||||
e = [make_url(games_by_platform_path[:-1] + ['{}#{}'.format(games_by_platform_path[-1], x.lower())], make_icon(platform_icon_map[x]), x) if x in platform_icon_map else make_text(x) for x in e]
|
||||
namex = make_text('{}:'.format(get_plural_or_singular('Platform', len(e))))
|
||||
# entry['platform'] = [namex] + e
|
||||
entry['state'].insert(0, [namex] + e)
|
||||
|
||||
# technical info fields
|
||||
for field in ('Code language', 'Code license', 'Code repository', 'Code dependency', 'Assets license'):
|
||||
@ -631,14 +648,14 @@ def convert_entries(entries, inspirations, developers):
|
||||
if field == 'Code repository':
|
||||
e = [make_repo_url(x, name) for x in e]
|
||||
elif field == 'Code language':
|
||||
e = [make_url(code_language_references[x], make_text(x, 'is-size-7')) for x in e]
|
||||
e = [make_url(code_language_references[x], make_text(x)) for x in e]
|
||||
elif field == 'Code license' or field == 'Assets license':
|
||||
e = [make_url(c.license_urls[x], x, css_class='is-size-7') if x in c.license_urls else make_text(x, 'is-size-7') for x in e]
|
||||
e = [make_url(c.license_urls[x], x) if x in c.license_urls else make_text(x) for x in e]
|
||||
elif field in c.url_fields:
|
||||
e = [make_url(x, shortcut_url(x, name), css_class='is-size-7') for x in e]
|
||||
e = [make_url(x, shortcut_url(x, name)) for x in e]
|
||||
else:
|
||||
e = [make_text(x, 'is-size-7') for x in e]
|
||||
namex = make_text('{}: '.format(get_plural_or_singular(field, len(entries))), 'is-size-7')
|
||||
e = [make_text(x) for x in e]
|
||||
namex = make_text('{}: '.format(get_plural_or_singular(field, len(entries))))
|
||||
entry[field.lower()] = [namex, make_enumeration(e, divider)]
|
||||
|
||||
# build system
|
||||
@ -683,7 +700,7 @@ def get_top50_games(games):
|
||||
stars = value
|
||||
top50_games.append((game, stars))
|
||||
top50_games.sort(key=lambda x:x[1], reverse=True)
|
||||
top50_games = top50_games[:50]
|
||||
top50_games = top50_games[:50] # get top 50
|
||||
top50_games =[game for game, stars in top50_games]
|
||||
return top50_games
|
||||
|
||||
@ -699,14 +716,14 @@ def generate(entries, inspirations, developers):
|
||||
# split entries in games and frameworks
|
||||
games, frameworks = [], []
|
||||
for entry in entries:
|
||||
(games, frameworks)[any([keyword in entry['Keyword'] for keyword in c.framework_keywords])].append(entry)
|
||||
(games, frameworks)[any([keyword in entry['Keyword'] for keyword in c.non_game_keywords])].append(entry)
|
||||
|
||||
# preprocess
|
||||
preprocess(games, 'Title', games_path)
|
||||
preprocess(frameworks, 'Title', frameworks_path)
|
||||
# TODO preprocess doesn't set the urls for frameworks correctly fix here, do better later
|
||||
for framework in frameworks:
|
||||
keyword = [keyword for keyword in c.framework_keywords if keyword in framework['Keyword']][0]
|
||||
keyword = [keyword for keyword in c.non_game_keywords if keyword in framework['Keyword']][0]
|
||||
framework['href'] = frameworks_path + ['{}.html#{}'.format(keyword, framework['anchor-id'])]
|
||||
entries = games + frameworks
|
||||
preprocess(inspirations, 'Name', inspirations_path)
|
||||
@ -727,36 +744,35 @@ def generate(entries, inspirations, developers):
|
||||
inspirations_by_alphabet = sort_into_categories(inspirations, extended_alphabet, sorter)
|
||||
developers_by_alphabet = sort_into_categories(developers, extended_alphabet, sorter)
|
||||
|
||||
genres = [keyword.capitalize() for keyword in c.recommended_keywords if keyword not in c.framework_keywords]
|
||||
genres = [keyword.capitalize() for keyword in c.recommended_keywords if keyword not in c.non_game_keywords]
|
||||
genres.sort()
|
||||
games_by_genre = sort_into_categories(games, genres, lambda item, category: category.lower() in item['Keyword'])
|
||||
games_by_platform = sort_into_categories(entries, c.valid_platforms, lambda item, category: category in item.get('Platform', []), 'Unspecified')
|
||||
games_by_language = sort_into_categories(entries, c.known_languages, lambda item, category: category in item['Code language'])
|
||||
frameworks_by_type = sort_into_categories(frameworks, c.framework_keywords, lambda item, category: category in item['Keyword'])
|
||||
frameworks_by_type = sort_into_categories(frameworks, c.non_game_keywords, lambda item, category: category in item['Keyword'])
|
||||
|
||||
# extract top 50 Github stars games
|
||||
top50_games = get_top50_games(games)
|
||||
|
||||
|
||||
# base dictionary
|
||||
base = {
|
||||
'title': 'OSGL',
|
||||
'creation-date': datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M')
|
||||
}
|
||||
|
||||
# copy css
|
||||
# copy css and js
|
||||
utils.copy_tree(os.path.join(c.web_template_path, 'css'), c.web_css_path)
|
||||
utils.copy_tree(os.path.join(c.web_template_path, 'js'), c.web_js_path)
|
||||
|
||||
# collage_image and google search console token and favicon.svg
|
||||
for file in ('collage_games.jpg', 'google1f8a3863114cbcb3.html', 'favicon.svg'):
|
||||
shutil.copyfile(os.path.join(c.web_template_path, file), os.path.join(c.web_path, file))
|
||||
|
||||
|
||||
# create Jinja Environment
|
||||
environment = Environment(loader=FileSystemLoader(c.web_template_path), autoescape=True)
|
||||
environment.globals['base'] = base
|
||||
environment.globals['raise'] = raise_helper
|
||||
environment.globals['is_list'] = is_list
|
||||
environment.globals['is_list'] = lambda obj: isinstance(obj, list)
|
||||
|
||||
# multiple times used templates
|
||||
template_categorical_index = environment.get_template('categorical_index.jinja')
|
||||
@ -810,18 +826,19 @@ def generate(entries, inspirations, developers):
|
||||
base['active_nav'] = 'frameworks'
|
||||
|
||||
# frameworks by type
|
||||
index = divide_in_columns(frameworks_by_type, game_index)
|
||||
index = divide_in_three_columns_and_transform(frameworks_by_type, game_index)
|
||||
index['title'] = make_text('Open source game frameworks/tools')
|
||||
index['subtitle'] = make_text('Index of {} game frameworks/tools'.format(len(frameworks)))
|
||||
index['categories'] = c.framework_keywords
|
||||
index['categories'] = c.non_game_keywords
|
||||
index['category-names'] = framework_names
|
||||
index['category-icons'] = {}
|
||||
index['number_entries_per_category_threshold'] = 0
|
||||
index['entry_bold'] = lambda x: 'tags' not in x
|
||||
index['category-infos'] = {}
|
||||
write(template_categorical_index.render(index=index), frameworks_index_path)
|
||||
|
||||
# generate frameworks pages
|
||||
for keyword in c.framework_keywords:
|
||||
for keyword in c.non_game_keywords:
|
||||
listing = {
|
||||
'title': framework_names[keyword],
|
||||
'subtitle': make_url(frameworks_index_path, 'Index'),
|
||||
@ -842,35 +859,38 @@ def generate(entries, inspirations, developers):
|
||||
write(template_listing_entries.render(listing=listing), games_path + ['{}.html'.format(letter.capitalize())])
|
||||
|
||||
# generate games index
|
||||
index = divide_in_columns(games_by_alphabet, game_index)
|
||||
index = divide_in_three_columns_and_transform(games_by_alphabet, game_index)
|
||||
index['title'] = make_text('Open source games')
|
||||
index['subtitle'] = make_text('Alphabetical index of {} games'.format(len(games)))
|
||||
index['subtitle'] = make_text('Alphabetical index of informations about {} games'.format(len(games)))
|
||||
index['categories'] = extended_alphabet
|
||||
index['category-names'] = extended_alphabet_names
|
||||
index['category-icons'] = {}
|
||||
index['number_entries_per_category_threshold'] = 20
|
||||
index['entry_bold'] = lambda x: 'tags' not in x
|
||||
index['category-infos'] = {}
|
||||
index['category-infos'] = {letter: make_text('{} games'.format(len(games_by_alphabet[letter]))) for letter in extended_alphabet}
|
||||
write(template_categorical_index.render(index=index), games_index_path)
|
||||
|
||||
# genres
|
||||
base['active_nav'] = ['filter', 'genres']
|
||||
index = divide_in_columns(games_by_genre, game_index)
|
||||
index = divide_in_three_columns_and_transform(games_by_genre, game_index)
|
||||
index['title'] = make_text('Open source games')
|
||||
index['subtitle'] = make_text('Index by game genre')
|
||||
index['categories'] = genres
|
||||
index['category-names'] = {k:[make_icon(genre_icon_map[k]), make_text(k)] if k in genre_icon_map else make_text(k) for k in index['categories']}
|
||||
index['number_entries_per_category_threshold'] = 25
|
||||
index['category-names'] = {k: make_text(k) for k in index['categories']}
|
||||
index['category-icons'] = {k: make_icon(genre_icon_map[k]) for k in index['categories'] if k in genre_icon_map}
|
||||
index['number_entries_per_category_threshold'] = 50
|
||||
index['entry_bold'] = lambda x: 'tags' not in x
|
||||
index['category-infos'] = {}
|
||||
index['category-infos'] = {genre: make_text('{} games'.format(len(games_by_genre[genre]))) for genre in genres}
|
||||
write(template_categorical_index.render(index=index), games_by_genres_path)
|
||||
|
||||
# games by language
|
||||
base['active_nav'] = ['filter', 'code language']
|
||||
index = divide_in_columns(games_by_language, game_index)
|
||||
index = divide_in_three_columns_and_transform(games_by_language, game_index)
|
||||
index['title'] = 'Open source games and frameworks'
|
||||
index['subtitle'] = make_text('Index by programming language')
|
||||
index['categories'] = c.known_languages
|
||||
index['category-names'] = {k:k for k in index['categories']}
|
||||
index['category-icons'] = {}
|
||||
index['number_entries_per_category_threshold'] = 15
|
||||
index['entry_bold'] = lambda x: 'tags' not in x
|
||||
index['category-infos'] = {category: make_url(c.language_urls[category], 'Language information', css_class='is-size-7') for category in c.known_languages if category in c.language_urls}
|
||||
@ -878,14 +898,16 @@ def generate(entries, inspirations, developers):
|
||||
|
||||
# games by platform
|
||||
base['active_nav'] = ['filter', 'platforms']
|
||||
index = divide_in_columns(games_by_platform, game_index)
|
||||
index = divide_in_three_columns_and_transform(games_by_platform, game_index)
|
||||
index['title'] = 'Open source games and frameworks'
|
||||
index['subtitle'] = make_text('Index by supported platform')
|
||||
index['categories'] = c.valid_platforms + ('Unspecified',)
|
||||
index['category-names'] = {k:[make_icon(platform_icon_map[k]), make_text(k)] for k in index['categories']}
|
||||
index['category-names'] = {k: make_text(k) for k in index['categories']}
|
||||
index['category-icons'] = {k: make_icon(platform_icon_map[k]) for k in index['categories']}
|
||||
index['number_entries_per_category_threshold'] = 15
|
||||
index['entry_bold'] = lambda x: 'tags' not in x
|
||||
index['category-infos'] = {}
|
||||
index['category-infos'] = {category: make_text('{} entries'.format(len(games_by_platform[category]))) for category in index['categories']}
|
||||
write(template_categorical_index.render(index=index), games_by_platform_path)
|
||||
|
||||
# top 50 games
|
||||
@ -904,11 +926,12 @@ def generate(entries, inspirations, developers):
|
||||
# inspirations
|
||||
|
||||
# inspirations index
|
||||
index = divide_in_columns(inspirations_by_alphabet, inspiration_index)
|
||||
index = divide_in_three_columns_and_transform(inspirations_by_alphabet, inspiration_index)
|
||||
index['title'] = 'Inspirations'
|
||||
index['subtitle'] = make_text('Alphabetical index of {} games used as inspirations'.format(len(inspirations)))
|
||||
index['categories'] = extended_alphabet
|
||||
index['category-names'] = extended_alphabet_names
|
||||
index['category-icons'] = {}
|
||||
index['number_entries_per_category_threshold'] = 10
|
||||
index['entry_bold'] = lambda x: 'tags' in x
|
||||
index['category-infos'] = {}
|
||||
@ -937,11 +960,12 @@ def generate(entries, inspirations, developers):
|
||||
write(template_listing_developers.render(listing=listing), developers_path + ['{}.html'.format(letter.capitalize())])
|
||||
|
||||
# developers index
|
||||
index = divide_in_columns(developers_by_alphabet, developer_index)
|
||||
index = divide_in_three_columns_and_transform(developers_by_alphabet, developer_index)
|
||||
index['title'] = 'Open source game developers'
|
||||
index['subtitle'] = make_text('Alphabetical index of {} developers'.format(len(developers)))
|
||||
index['categories'] = extended_alphabet
|
||||
index['category-names'] = extended_alphabet_names
|
||||
index['category-icons'] = {}
|
||||
index['number_entries_per_category_threshold'] = 10
|
||||
index['entry_bold'] = lambda x: 'tags' in x
|
||||
index['category-infos'] = {}
|
||||
@ -964,10 +988,14 @@ if __name__ == "__main__":
|
||||
inspirations = osg.read_inspirations()
|
||||
inspirations = list(inspirations.values())
|
||||
inspirations.sort(key=lambda x: str.casefold(x['Name']))
|
||||
# remove orphaned inspirations for the website creation
|
||||
inspirations = [inspiration for inspiration in inspirations if inspiration['Inspired entries']]
|
||||
|
||||
developers = osg.read_developers()
|
||||
developers = list(developers.values())
|
||||
developers.sort(key=lambda x: str.casefold(x['Name']))
|
||||
# remove orphaned developers for the website creation
|
||||
developers = [developer for developer in developers if developer['Games']]
|
||||
|
||||
# re-generate static website
|
||||
print('re-generate static website')
|
||||
|
29
code/html/js/osgl.js
Normal file
29
code/html/js/osgl.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* A tiny bit of JavaScript to improve the OSGL site.
|
||||
*/
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// Get all "navbar-burger" elements
|
||||
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
|
||||
|
||||
// Check if there are any navbar burgers
|
||||
if ($navbarBurgers.length > 0) {
|
||||
|
||||
// Add a click event on each of them
|
||||
$navbarBurgers.forEach( el => {
|
||||
el.addEventListener('click', () => {
|
||||
|
||||
// Get the target from the "data-target" attribute
|
||||
const target = el.dataset.target;
|
||||
const $target = document.getElementById(target);
|
||||
|
||||
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
|
||||
el.classList.toggle('is-active');
|
||||
$target.classList.toggle('is-active');
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
});
|
@ -1,16 +1,14 @@
|
||||
{% extends "base.jinja" %}
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">{{ listing['title'] }}</h1>
|
||||
{#- iterate over items -#}
|
||||
{% for item in listing['items'] %}
|
||||
<p class="title is-4">{{ listing['title'] }}</p>
|
||||
{#- iterate over items, each one as a box-#}
|
||||
{% for item in listing['items'] %}
|
||||
<div id="{{ item['anchor-id'] }}" class="box">
|
||||
{#- name and contact elements on one line, as a level -#}
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<h2 class="title is-4">{{ item['name'] }}</h2>
|
||||
</div>
|
||||
<div class="level-item"><p class="title is-4">{{ item['name'] }}</p></div>
|
||||
</div>
|
||||
<div class="level-right is-size-5">
|
||||
{%- for contact in item['contact'] -%}
|
||||
@ -18,18 +16,18 @@
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</div>
|
||||
{#- games as a separate element -#}
|
||||
<div class="block">{{ macros.render_element(item['games']) }}</div>
|
||||
<div class="block">
|
||||
{%- for field in ('organization',) -%}
|
||||
{%- if field in item %}{{ macros.render_element(item[field]) }}{% endif -%}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
<div class="block">
|
||||
<a href="{{ base['url_to'](['contribute.html#developers']) }}" title="Contribution guide" class="is-size-7">Improve</a>
|
||||
</div>
|
||||
{#- other elements -#}
|
||||
<div class="block">
|
||||
{%- for field in ('organization',) -%}
|
||||
{%- if field in item %}{{ macros.render_element(item[field]) }}{% endif -%}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
{#- improve link -#}
|
||||
<p class="is-size-7 has-text-right"><a href="{{ base['url_to'](['contribute.html#developers']) }}" title="Contribution guide">Improve</a></p>
|
||||
</div>
|
||||
{% endfor -%}
|
||||
<a class="is-light is-size-7" href="#">Back to top</a>
|
||||
<p class="is-size-7 has-text-right"><a href="#">Back to top</a></p>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
@ -1,57 +1,46 @@
|
||||
{% extends "base.jinja" %}
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">{{ listing['title'] }}</h1>
|
||||
{%- if 'subtitle' in listing -%}
|
||||
<h2 class="subtitle">{{ macros.render_element(listing['subtitle']) }}</h2>
|
||||
{%- endif -%}
|
||||
{# iterate over items -#}
|
||||
<div class="box"><p class="title is-4">{{ listing['title'] }}</p>
|
||||
{%- if 'subtitle' in listing %}<p class="subtitle is-6">{{ macros.render_element(listing['subtitle']) }}</p>{% endif -%}</div>
|
||||
{#- iterate over items -#}
|
||||
{% for item in listing['items'] %}
|
||||
<div id="{{ item['anchor-id'] }}" class="box">
|
||||
{#- title and platform, activity, state as a level item (all on one line) -#}
|
||||
<nav class="level">
|
||||
<div class="level-left">
|
||||
<div class="level-item">
|
||||
<h2 class="title is-4">{{ item['name'] }}</h2>
|
||||
</div>
|
||||
<div class="level-item title is-4">{{ item['name'] }}</div>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<div class="level-right is-size-7">
|
||||
{%- for state in item['state'] -%}
|
||||
<div class="level-item">{{ macros.render_element(state) }}</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</nav>
|
||||
{#- keywords as tags, no note currently -#}
|
||||
<div class="block">
|
||||
{%- if 'platform' in item -%}
|
||||
{%- for platform in item['platform'] -%}
|
||||
<span class="mr-2">{{ macros.render_element(platform) }}</span>
|
||||
{%- endfor -%}
|
||||
{%- endif -%}
|
||||
{{ macros.render_element(item['keyword']) }}
|
||||
{%- if 'note' in item %}{{ macros.render_element(item['note']) }}{% endif -%}
|
||||
{{ macros.render_element(item['keyword']) }}
|
||||
</div>
|
||||
{#- important fields in a certain order -#}
|
||||
<div class="block">
|
||||
{%- if 'inspiration' in item %}{{ macros.render_element(item['inspiration']) }}<br>{% endif -%}
|
||||
{%- if 'developer' in item %}{{ macros.render_element(item['developer']) }}{% endif -%}
|
||||
</div>
|
||||
<div class="block">
|
||||
{%- for field in ('homepage', 'media', 'download', 'play online') -%}
|
||||
{%- for field in ('homepage', 'media', 'inspiration', 'download', 'play online', 'developer') -%}
|
||||
{%- if field in item -%}{{ macros.render_element(item[field]) }}<br>{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
<div class="block">
|
||||
<span class="has-text-weight-semibold">Technical info</span><br>
|
||||
{#- technical fields -#}
|
||||
<div class="block is-size-7">
|
||||
<span class="has-text-weight-semibold">Technical information</span><br>
|
||||
{%- for field in ('code language', 'code license', 'code repository', 'code dependency', 'assets license', 'build system') -%}
|
||||
{%- if field in item -%}{{ macros.render_element(item[field]) }}<br>{%- endif -%}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
<div class="block">
|
||||
<a href="{{ base['url_to'](['contribute.html#games']) }}" title="Contribution guide" class="is-size-7 mr-2">Improve</a>
|
||||
<a href="{{ item['raw-path'] }}" title="Text based entry on Github" class="is-size-7">Raw entry</a>
|
||||
{#- improve, raw -#}
|
||||
<div class="block is-size-7 has-text-right">
|
||||
<a href="{{ base['url_to'](['contribute.html#games']) }}" title="Contribution guide" class="mr-2">Improve</a>
|
||||
<a href="{{ item['raw-path'] }}" title="Text based entry on Github">Raw entry</a>
|
||||
</div>
|
||||
</div>{#- of box -#}
|
||||
{% endfor %}
|
||||
<a class="is-light is-size-7" href="#">Back to top</a>
|
||||
<p class="is-size-7 has-text-right"><a href="#">Back to top</a></p>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
@ -1,22 +1,19 @@
|
||||
{% extends "base.jinja" %}
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">{{ listing['title'] }}</h1>
|
||||
{# iterate over items -#}
|
||||
<p class="title is-4">{{ listing['title'] }}</p>
|
||||
{#- iterate over items, each one as a box-#}
|
||||
{%- for item in listing['items'] -%}
|
||||
<div id="{{ item['anchor-id'] }}" class="box">
|
||||
<div class="block">
|
||||
<h2 class="title is-4">{{ item['name'] }}</h2>
|
||||
<div class="subtitle is-size-6">{{ macros.render_element(item['inspired']) }}</div>
|
||||
<p class="title is-4">{{ item['name'] }}</p>
|
||||
<p class="subtitle is-6">{{ macros.render_element(item['inspired']) }}</p>
|
||||
{%- if 'media' in item -%}{{ macros.render_element(item['media']) }}{%- endif -%}
|
||||
</div>
|
||||
<div class="block">
|
||||
<a href="{{ base['url_to'](['contribute.html#inspirations']) }}" title="Contribution guide" class="is-size-7">Improve</a>
|
||||
</div>
|
||||
{#- improve link -#}
|
||||
<p class="is-size-7 has-text-right"><a href="{{ base['url_to'](['contribute.html#inspirations']) }}" title="Contribution guide">Improve</a></p>
|
||||
</div>
|
||||
{% endfor -%}
|
||||
<a class="is-light is-size-7" href="#">Back to top</a>
|
||||
<p class="is-size-7 has-text-right"><a href="#">Back to top</a></p>
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
@ -32,7 +32,7 @@
|
||||
|
||||
{# Renders an icon #}
|
||||
{%- macro render_icon(icon) -%}
|
||||
<span class="icon is-large has-text-black" {% if 'title' in icon %} title="{{ icon['title'] }}"{% endif %}><i class="icon-{{ icon['class'] }}"></i></span>
|
||||
<span class="icon has-text-black"{% if 'title' in icon %} title="{{ icon['title'] }}"{% endif %}><i class="icon-{{ icon['class'] }}"></i></span>
|
||||
{%- endmacro -%}
|
||||
|
||||
{# Some text surrounded by a link tag #}
|
||||
|
@ -1,18 +1,16 @@
|
||||
{% extends "base.jinja" %}
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">{{ data['title'] }}</h1>
|
||||
<p class="title is-4">{{ data['title'] }}</p>
|
||||
{% set comma = joiner(",") %}
|
||||
{% for section in data['sections'] %}
|
||||
{{ comma() }} <a href="#">{{ section['title'] }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% for section in data['sections'] %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h2 id="">{{ section['title'] }}</h2>
|
||||
<p id="" class="title is-4">{{ section['title'] }}</p>
|
||||
<ul>
|
||||
{% for item in section['items'] -%}
|
||||
<li>{{ item }}</li>
|
||||
|
Reference in New Issue
Block a user