A template capable of rendering markdown from a given template file. | |
Community templates are a way to use official releases of lowlighter/metrics while using templates from external repositories (owned or not).
Use setup_community_templates
option to specify additional external sources using following format:
user/repo@branch:template
These templates will be downloaded through git and will be usable by prefixing their name with an @
.
Example: using my-theme
template by downloading it from user/repo
- uses: lowlighter/metrics@latest
with:
template: "@my-theme"
setup_community_templates: "user/repo@main:my-theme"
For security reasons, community templates will use the classic
template template.mjs
instead of their own.
If you trust a community template, append +trust
to it.
Example: using and trusting my-theme
template by downloading it from user/repo
- uses: lowlighter/metrics@latest
with:
template: "@my-theme"
setup_community_templates: "user/repo@main:my-theme+trust"
⚠️ Note that it basically allow remote code execution and the template may have access to sensitive data along with tokens! Use this feature only from a trusted source. Remember that its content may also change at any time...
Some templates may accept additional custom parameters that can be passed through the query
option, using a JSON formatted string.
Example: using and trusting my-theme
template by downloading it from user/repo
- uses: lowlighter/metrics@latest
with:
template: "@my-theme"
query: |
{
"header_color": "#FF0000"
}
name: Using a community template
uses: lowlighter/metrics@latest
with:
token: ${{ secrets.METRICS_TOKEN }}
template: '@classic'
setup_community_templates: lowlighter/metrics@master:classic
name: Using a trusted community template
uses: lowlighter/metrics@latest
with:
token: ${{ secrets.METRICS_TOKEN }}
template: '@terminal'
setup_community_templates: lowlighter/metrics@master:terminal+trust
Templates creation requires you to be comfortable with HTML, CSS and JavaScript (EJS flavored).
To create a new template, clone and setup this repository first:
git clone https://github.com/lowlighter/metrics.git
cd metrics/
npm install
Find a cool name for your new template and run the following:
npm run quickstart template <template_name>
It will create a new directory in /source/templates
with the following file structure:
/source/templates/{template-name}
README.md
,metadata.yml
,image.svg
partials/
_.json
*.ejs
Templates are auto-loaded based on their folder existence, so there's no need to register them somewhere.
Usually image.svg
doesn't need to be edited too much, but let's explain it how it works.
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="99999" class="<%= !animated ? 'no-animations' : '' %>">
<defs><style><%= fonts %></style></defs>
<style data-optimizable="true"><%= style %></style>
<foreignObject x="0" y="0" width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml" xmlns:xlink="http://www.w3.org/1999/xlink">
<% for (const partial of [...partials]) { %>
<%- await include(`partials/${partial}.ejs`) %>
<% } %>
<div id="metrics-end"></div>
</div>
</foreignObject>
</svg>
EJS framework is used to programmatically create content through the help of templating tags (<% %>
).
fonts
and style
variables are respectively populated with fonts.css
and styles.css
files content (or will fallback to those of classic
template inexistent).
These will define the global design of the output.
data-optimizable="true"
tells that a style
tag can be safely minified and purged by CSS post-processors.
partials
variable is populated with partials/_.json
file content and define which files should be included along with default ordering.
The loop iterates over this array to include all defined partials. Each partial should handle whether it should be displayed by itself.
#metrics-end
is a special HTML tag which must remain at the bottom of SVG template.
It is used to compute height dynamically through a puppeteer headless instance. Initial height should remain a high number so it doesn't get cropped accidentally while puppeteer compute element.getBoundingClientRect().
metadata.yml
is a file which describes supported account types, output formats, scopes, etc.
name: "🖼️ Template name"
extends: classic
description: Short description
examples:
default: https://via.placeholder.com/468x60?text=No%20preview%20available
supports:
- user
- organization
- repository
formats:
- svg
- png
- jpeg
- json
- markdown
- markdown-pdf
🧱 core
plugin will automatically check user inputs with your defined supported supports
and formats
key and throw an error in case of incompatibility.
name
, description
and examples
are used to auto-generate documentation in the README.md
by replacing the following:
<!--header-->
<!--/header-->
extends
is used to define upon which template it should inherits its template.mjs
when it is not trusted by user.
Workflow examples from examples.yml
are used to auto-generate documentation in the README.md
by replacing the following:
#### ℹ️ Examples workflows
<!--examples-->
<!--/examples-->
Just create a new .ejs
file in partials
folder, and reference it into partials/_.json
.
It should be able to handle gracefully plugins state and errors.
Below is a minimal snippet of a partial:
<% if (plugins.gists) { %>
<% if (plugins.gists.error) { %>
<%= plugins.gists.error.message %>
<% } else { %>
<%# content %>
<% } %>
<% } %>
Partials should have the match the same name as plugin handles, as they're used to display plugin compatibility in auto-generated header.
⚠️ This significantly increases rendered metrics filesize and thus not recommended. You should restrict charset when using this feature
Here's a quick step-by-step tutorial to create base64 encoded fonts:
-
- Find a font on fonts.google.com
- Select regular, bold, italic and bold+italic fonts
- Open
embed
tab and extracthref
-
- Open extracted
href
in a browser and append&text=
parameter with list of used characters
- e.g.
&text=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
- Open extracted
-
- Download each font file from urls present in generated stylesheet
-
- Convert them into base64 with
woff
format on transfonter.org
- Convert them into base64 with
-
- Download archive and extract it
-
- Copy content of generated stylesheet to
fonts.css
- Copy content of generated stylesheet to
-
- Update
style.css
to use the new font
- Update