Skip to content

Commit

Permalink
Generalize website generation (#688)
Browse files Browse the repository at this point in the history
### Summary

Adds the ability to generate HTML that can be embedded into a markdown
document.
You may find it easier to review each commit separately.

- (3ec7a48) Makes the license field
optional. A license is still a requirement for ecosystem projects, this
change just allows building the website if it isn't set in the database.
- (d24a4ab) Add 'standalone' option to
generate a page that can be embedded in another page.
This basically means exluding the head/body tags, removing some CSS, and
removing indentation (to play nicely with markdown).
- (92000f2) Specify output filename
(not just folder) in case you don't want the page to be called
`index.html`.
- (e98f6e5) Add custom css
capabilities. This lets users add custom CSS rules, specified in the
`website.toml` file.
  • Loading branch information
frankharkins authored Apr 2, 2024
1 parent 6350ec2 commit 3ac5c64
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 26 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,4 @@ dmypy.json

# Generated files
/website/index.html
/website/style.css
32 changes: 26 additions & 6 deletions ecosystem/cli/website.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from pathlib import Path
from typing import Any
import json
import re
import toml

from jinja2 import Environment, PackageLoader, Template
Expand All @@ -17,21 +18,31 @@ def build_website(resources: str, output: str) -> None:
"""
Generates the ecosystem web page from data in `resources` dir, writing to `output` dir.
"""
resources_dir = Path(resources)
html = _build_html(*_load_from_file(resources_dir))
Path(output, "index.html").write_text(html)
projects, web_data, label_descriptions, templates, custom_css = _load_from_file(
Path(resources)
)
html = _build_html(projects, web_data, label_descriptions, templates)
Path(output).write_text(html)

css = templates["css"].render(
custom_css=custom_css, standalone=web_data.get("standalone", True)
)
(Path(output).parent / "style.css").write_text(css)


def _load_from_file(
resources_dir: Path,
) -> tuple[list[Repository], dict[str, Any], dict[str, str], dict[str, Template]]:
) -> tuple[
list[Repository], dict[str, Any], dict[str, str], dict[str, Template], str | None
]:
"""
Loads website data from file.
Returns:
* Projects: List of Repository objects from `members` folder.
* Web data: Strings (title / descriptions etc.) from `website.toml`.
* Label descriptions: from `labels.json`.
* Jinja templates: from `html_templates` folder.
* Any custom css to be appended to the css file.
"""
# Projects list
dao = DAO(path=resources_dir)
Expand All @@ -49,21 +60,28 @@ def _load_from_file(
# Website strings
web_data = toml.loads((resources_dir / "website.toml").read_text())

# Custom css
custom_css = None
if web_data.get("custom-css", False):
custom_css = (resources_dir / web_data["custom-css"]).read_text()

# Jinja templates
environment = Environment(loader=PackageLoader("ecosystem", "html_templates/"))
templates = {
"website": environment.get_template("webpage.html.jinja"),
"card": environment.get_template("card.html.jinja"),
"tag": environment.get_template("tag.html.jinja"),
"link": environment.get_template("link.html.jinja"),
"css": environment.get_template("style.css.jinja"),
}
return projects, web_data, label_descriptions, templates
return projects, web_data, label_descriptions, templates, custom_css


def _build_html(projects, web_data, label_descriptions, templates) -> str:
"""
Take all data needed to build the website and produce a HTML string.
"""
# pylint: disable=too-many-locals
sections = {group["id"]: group for group in web_data["groups"]}
for section in sections.values():
section.setdefault("html", "")
Expand Down Expand Up @@ -123,7 +141,9 @@ def _build_html(projects, web_data, label_descriptions, templates) -> str:
# Adding the card to a section
sections[repo.group]["html"] += card

return templates["website"].render(
html = templates["website"].render(
is_standalone=web_data.get("standalone", True),
header=web_data["header"],
sections=sections.values(),
)
return re.sub(r"^\s+", "", html, flags=re.MULTILINE)
24 changes: 19 additions & 5 deletions website/style.css → ecosystem/html_templates/style.css.jinja
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% if standalone %}
* {
box-sizing: inherit;
}
Expand All @@ -19,6 +20,12 @@ header {
background-color: white;
}

p {
font-size: 14px;
color: #525252;
}
{% endif %}

.inside-header {
padding: 0px 32px 0px 32px;
display: flex;
Expand Down Expand Up @@ -92,11 +99,6 @@ cds-tag {
margin-bottom: 8px;
}

p {
font-size: 14px;
color: #525252;
}

.title-description {
margin: 24px 0;
width: 400px;
Expand Down Expand Up @@ -171,6 +173,7 @@ p {
cursor: pointer;
}

{% if standalone %}
/* ------------------------------ */

@media only screen and (max-width: 1500px) {
Expand Down Expand Up @@ -205,3 +208,14 @@ p {
width: auto;
}
}
{% endif %}

{% if custom_css %}

/* ------------ */
/* Custom rules */
/* ------------ */

{{ custom_css }}

{% endif %}
36 changes: 23 additions & 13 deletions ecosystem/html_templates/webpage.html.jinja
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{% if is_standalone %}
<!doctype html>
<html lang="en">
<head>
Expand All @@ -8,6 +9,21 @@
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ header.title.bold }} {{ header.title.normal }}</title>
{# These two CSS files include general rules that we don't want to interfere #}
{# with the page we're embedding in, so we only set them in standalone mode. #}
<link
rel="stylesheet"
href="https://1.www.s81c.com/common/carbon-for-ibm-dotcom/tag/v1/latest/plex.css"
/>
<link
rel="stylesheet"
href="https://1.www.s81c.com/common/carbon/web-components/tag/v2/latest/themes.css"
/>
{% endif %}
<link
rel="stylesheet"
href="https://1.www.s81c.com/common/carbon/web-components/tag/v2/latest/grid.css"
/>
<script
type="module"
src="https://1.www.s81c.com/common/carbon/web-components/tag/v2/latest/tile.min.js"
Expand All @@ -28,21 +44,12 @@
type="module"
src="https://1.www.s81c.com/common/carbon/web-components/tag/v2/latest/tooltip.min.js"
></script>
<link
rel="stylesheet"
href="https://1.www.s81c.com/common/carbon-for-ibm-dotcom/tag/v1/latest/plex.css"
/>
<link
rel="stylesheet"
href="https://1.www.s81c.com/common/carbon/web-components/tag/v2/latest/themes.css"
/>
<link
rel="stylesheet"
href="https://1.www.s81c.com/common/carbon/web-components/tag/v2/latest/grid.css"
/>
<link rel="stylesheet" href="style.css" />
{% if is_standalone %}
</head>
<body class="cds-theme-zone-white">
<body>
{% endif %}
<div class="cds-theme-zone-white">
<header>
<div class="inside-header cds--grid layout-lead-space-fixed__container">
<div class="header-content">
Expand Down Expand Up @@ -113,5 +120,8 @@
<div class="cards cds--row">{{ section.html }}</div>
</div>
{% endfor %}
</div>
{% if is_standalone %}
</body>
</html>
{% endif %}
2 changes: 1 addition & 1 deletion ecosystem/models/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Repository(JsonSerializable):
name: str
url: str
description: str
licence: str
licence: str | None = None
contact_info: str | None = None
alternatives: str | None = None
affiliations: str | None = None
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ commands = black {posargs} ecosystem tests --check
allowlist_externals = bash
basepython = python3
commands =
bash -ec "python manager.py build --resources ecosystem/resources --output website"
bash -ec "python manager.py build --resources ecosystem/resources --output website/index.html"

0 comments on commit 3ac5c64

Please sign in to comment.