app.gresource.xml

<?xml version='1.0' encoding='utf-8'?>
<gresources>
    <gresource prefix="/app">
        <file compressed="true">app.json</file>
        <file compressed="true">app.yaml</file>
        <file compressed="true">overrides.css</file>
        <file compressed="true">overrides.scss</file>
        <file compressed="true">credits.json</file>
        <file compressed="true" preprocess="xml-stripblanks">assets/titleImage</file>
    </gresource>
</gresources>

app.yaml

overrides:
  home-featured-articles-arrangement:
    type: Arrangement.Half
    styles:
      - main-arrangement
---
!import blog

assets/icon.svg

icon.svg

assets/icon-64.png

icon-64.png

assets/icon-128.png

icon-128.png

assets/titleImage

titleImage.svg

credits.json

[
    {
        "credit": "Razlan Hanafiah",
        "credit_uri": "https://thenounproject.com/razlanisme/",
        "license": "CC-BY 3.0",
        "thumb_uri": "resource:///app/assets/titleImage",
        "uri": "https://thenounproject.com/term/sheep/6049/",
        "comment": "Derived from 'Sheep' by Razlan Hanafiah from the Noun Project"
    },
    {
        "credit": "Razlan Hanafiah",
        "credit_uri": "https://thenounproject.com/razlanisme/",
        "license": "CC-BY 3.0",
        "thumb_uri": "file:///app/share/icons/hicolor/scalable/apps/org.example.CreativeCommonsBlog.svg",
        "uri": "https://thenounproject.com/term/sheep/6049/",
        "comment": "Derived from 'Sheep' by Razlan Hanafiah from the Noun Project"
    }
]

database_manifest.py

#!/usr/bin/env python3

import hashlib
import json
import os
import subprocess

meson_introspect = os.getenv('MESONINTROSPECT')
prefix = os.getenv('MESON_INSTALL_DESTDIR_PREFIX')

project_info = subprocess.check_output(meson_introspect.split() +
                                       ['--projectinfo'],
                                       universal_newlines=True)
app_id = json.loads(project_info)['name']
hasher = hashlib.sha256()
hasher.update(app_id.encode())
subscription_id = hasher.hexdigest()
subscription_dir = os.path.join(prefix, 'share', 'ekn', 'data', app_id,
                                'com.endlessm.subscriptions', subscription_id)

subprocess.check_call(['eminem', 'regenerate', subscription_dir])

meson.build

project('org.example.CreativeCommonsBlog', version: '0.0.0', license: 'CC0-1.0',
    meson_version: '>= 0.40.0')
app_id = meson.project_name()
subscription_id = run_command('python3', '-c',
    'import hashlib; h = hashlib.sha256(); h.update("@0@".encode()); print(h.hexdigest())'
    .format(app_id)).stdout().strip()

gnome = import('gnome')

pkg_config = find_program('pkg-config')
sassc = find_program('sassc')
autobahn = find_program('autobahn')
basin = find_program('basin')

subscription_dir = join_paths(get_option('datadir'), 'ekn', 'data', app_id,
    'com.endlessm.subscriptions', subscription_id)
pkgdatadir = join_paths(get_option('datadir'), app_id)
theme_path = run_command(pkg_config, '--variable', 'eos_theme_path',
    'eos-knowledge-0').stdout().strip()
preset_path = run_command(pkg_config, '--variable', 'eos_preset_path',
    'eos-knowledge-0').stdout().strip()

overrides_css = custom_target('sass', input: 'overrides.scss',
    output: 'overrides.css',
    command: [sassc, '-I', theme_path, '@INPUT@', '@OUTPUT@'])

app_json = custom_target('autobahn', input: 'app.yaml', output: 'app.json',
    command: [autobahn, '@INPUT@', '-o', '@OUTPUT@', '-I', preset_path])

sets_shard = custom_target('sets', input: 'sets.json', output: 'sets.shard',
    build_by_default: true, install: true, install_dir: subscription_dir,
    command: [basin, '@INPUT@', '@OUTPUT@'])

resource = gnome.compile_resources('app', 'app.gresource.xml',
    gresource_bundle: true, install: true, install_dir: pkgdatadir,
    dependencies: [app_json, overrides_css])

install_data('output.shard', install_dir: subscription_dir)

meson.add_install_script('database_manifest.py')

org.example.CreativeCommonsBlog.desktop

[Desktop Entry]
Version=1.0
Type=Application
Name=Commons Blog
Exec=/usr/bin/flatpak run org.example.CreativeCommonsBlog
Icon=org.example.CreativeCommonsBlog
Comment=Blog posts from the Creative Commons organization, offline!

org.example.CreativeCommonsBlog.json

{
    "app-id": "org.example.CreativeCommonsBlog",
    "runtime": "com.endlessm.apps.Sdk",
    "runtime-version": "master",
    "sdk": "com.endlessm.apps.Sdk",
    "command": "org.example.CreativeCommonsBlog",

    "finish-args": [
        "--socket=x11",
        "--socket=wayland",
        "--device=dri"
    ],

    "modules": [
        {
            "name": "source-sans-font",
            "buildsystem": "simple",
            "build-commands": [
                "install -D -m644 *.otf -t /app/share/fonts"
            ],
            "sources": [
                {
                    "type": "file",
                    "url": "https://github.com/adobe-fonts/source-sans-pro/releases/download/variable-fonts/SourceSansVariable-Roman.otf",
                    "sha256": "afd685a2b43feafbb4c47deaa7a2c0fcd826940d3473abe42e4aaa56d39754af"
                },
                {
                    "type": "file",
                    "url": "https://github.com/adobe-fonts/source-sans-pro/releases/download/variable-fonts/SourceSansVariable-Italic.otf",
                    "sha256": "62c5d0991d6a9571a89c8e137f2b76e3ff57f671e0d1bce832af98422ce13a6d"
                }
            ]
        },
        {
            "name": "org.example.CreativeCommonsBlog",
            "buildsystem": "meson",
            "sources": [
                {
                    "type": "shell",
                    "commands": ["mkdir -p assets"]
                },
                { "type": "file", "path": "app.gresource.xml" },
                { "type": "file", "path": "app.yaml" },
                { "type": "file", "path": "credits.json" },
                { "type": "file", "path": "database_manifest.py" },
                { "type": "file", "path": "meson.build" },
                { "type": "file", "path": "org.example.CreativeCommonsBlog.desktop" },
                { "type": "file", "path": "output.shard" },
                { "type": "file", "path": "overrides.scss" },
                { "type": "file", "path": "sets.json" },
                {
                    "type": "file",
                    "path": "assets/icon.svg",
                    "dest-filename": "assets/icon.svg"
                },
                {
                    "type": "file",
                    "path": "assets/icon-64.png",
                    "dest-filename": "assets/icon-64.png"
                },
                {
                    "type": "file",
                    "path": "assets/icon-128.png",
                    "dest-filename": "assets/icon-128.png"
                },
                {
                    "type": "file",
                    "path": "assets/titleImage",
                    "dest-filename": "assets/titleImage"
                },
                {
                    "type": "script",
                    "dest-filename": "org.example.CreativeCommonsBlog",
                    "commands": [
                        "ekn-app-runner org.example.CreativeCommonsBlog /app/share/org.example.CreativeCommonsBlog/app.gresource $@"
                    ]
                }
            ],
            "build-commands": [
                "install -Dm755 -t /app/bin ../org.example.CreativeCommonsBlog",
                "install -Dm644 -t /app/share/applications ../org.example.CreativeCommonsBlog.desktop",
                "install -Dm644 ../assets/icon-64.png /app/share/icons/hicolor/64x64/apps/org.example.CreativeCommonsBlog.png",
                "install -Dm644 ../assets/icon-128.png /app/share/icons/hicolor/128x128/apps/org.example.CreativeCommonsBlog.png",
                "install -Dm644 ../assets/icon.svg /app/share/icons/hicolor/scalable/apps/org.example.CreativeCommonsBlog.svg"
            ]
        }
    ]
}

overrides.scss

$primary-light-color: #fb7928;
$primary-medium-color: #ee5b32;
$accent-light-color: #049bce;
$accent-dark-color: #464646;
$background-light-color: white;
$background-dark-color: #e9e9e9;

$body-font: 'Source Sans Variable';
$title-font: 'Source Sans Variable';
$display-font: 'Source Sans Variable';
$logo-font: 'Source Sans Variable';
$context-font: 'Source Sans Variable';
$support-font: 'Source Sans Variable';

@import 'blog';

.LayoutSidebar .sidebar {
    min-width: 400px;
    background-color: $accent-dark-color;
    box-shadow: 3px 0px 10px $accent-dark-color;
}

.BannerApp .ThemeableImage {
    min-width: 300px;
}

sets.json

{
    "sets": [
        {
            "title": "About Creative Commons",
            "featured": true,
            "tags": ["EknSetObject"],
            "childTags": [
                "About CC"
            ]
        },
        {
            "title": "Around the World",
            "featured": true,
            "tags": ["EknSetObject"],
            "childTags": [
                "Global affiliates",
                "tag:Canada",
                "tag:Creative Commons Global Network",
                "tag:EU",
                "tag:EU-Mercosur",
                "tag:European Union",
                "tag:Ghana",
                "tag:Mercosur",
                "tag:Mexico",
                "tag:Portuguese",
                "tag:Spanish",
                "tag:Toronto",
                "tag:africa",
                "tag:chinese"
            ]
        },
        {
            "title": "Events",
            "featured": true,
            "tags": ["EknSetObject"],
            "childTags": [
                "Events"
            ]
        },
        {
            "title": "Interviews",
            "featured": true,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:cctalkswith"
            ]
        },
        {
            "title": "Policy, Advocacy, & Copyright Reform",
            "featured": true,
            "tags": ["EknSetObject"],
            "childTags": [
                "Policy / advocacy / copyright reform"
            ]
        },
        {
            "title": "Blog Posts",
            "featured": true,
            "tags": ["EknSetObject"],
            "childTags": [
                "Arts / culture",
                "Education / OER",
                "Global affiliates",
                "Legal tools / licenses",
                "Open access",
                "Weblog"
            ]
        },
        {
            "title": "Advocacy",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:advocacy"
            ]
        },
        {
            "title": "Art",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:art"
            ]
        },
        {
            "title": "Arts & Culture",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "Arts / culture"
            ]
        },
        {
            "title": "CC Licenses",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "Legal tools / licenses"
            ]
        },
        {
            "title": "Copyright Reform",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:#fixcopyright",
                "tag:copyright reform",
                "tag:eu copyright reform"
            ]
        },
        {
            "title": "Copyright Week",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:#copyrightweek",
                "tag:#coyrightweek",
                "tag:Copyright Week 2018"
            ]
        },
        {
            "title": "Education & OER",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "Education / OER"
            ]
        },
        {
            "title": "Emerging Media",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:AR",
                "tag:VR",
                "tag:augmented reality",
                "tag:emerging media",
                "tag:immersive media",
                "tag:virtual reality"
            ]
        },
        {
            "title": "Global Summit",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:CC Global Summit",
                "tag:CC summit",
                "tag:Global Summit",
                "tag:ccglobalsummit",
                "tag:ccsummit",
                "tag:ccsummit18",
                "tag:global summit 2018"
            ]
        },
        {
            "title": "Humans of the Commons",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:humans of the commons",
                "tag:humansofthecommons"
            ]
        },
        {
            "title": "Net Neutrality",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:#netneutrality",
                "tag:net neutrality",
                "tag:FCC"
            ]
        },
        {
            "title": "Open access",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "Open access"
            ]
        },
        {
            "title": "Policy",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:policy",
                "tag:public policy"
            ]
        },
        {
            "title": "Public Domain",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:public domain",
                "tag:CC0"
            ]
        },
        {
            "title": "Trade Agreements",
            "featured": false,
            "tags": ["EknSetObject"],
            "childTags": [
                "tag:free trade agreement",
                "tag:trade agreements"
            ]
        }
    ]
}

The results of the search are