refactor #1
14
config.yaml
14
config.yaml
@ -1,12 +1,8 @@
|
|||||||
author: Jim Shepich III
|
author: Jim Shepich III
|
||||||
templates_folder: ./templates
|
templates_folder: ./site/templates
|
||||||
site_defaults:
|
|
||||||
templates:
|
|
||||||
partials: ./templates/partials
|
|
||||||
components: ./templates/components
|
|
||||||
pages: ./templates/pages
|
|
||||||
sites:
|
sites:
|
||||||
main:
|
main:
|
||||||
|
title: Jimlab
|
||||||
base_url: http://localhost:8000
|
base_url: http://localhost:8000
|
||||||
web_root: ./dist
|
web_root: ./dist
|
||||||
build_cache: ./site
|
build_cache: ./site
|
||||||
@ -14,14 +10,20 @@ sites:
|
|||||||
- /assets
|
- /assets
|
||||||
articles:
|
articles:
|
||||||
- ./pages/*.md
|
- ./pages/*.md
|
||||||
|
template_selections:
|
||||||
|
article: templates.components.simple_article
|
||||||
|
|
||||||
resume:
|
resume:
|
||||||
|
title: Resume
|
||||||
base_url: http://localhost:8000
|
base_url: http://localhost:8000
|
||||||
web_root: ./dist
|
web_root: ./dist
|
||||||
git_repo: ssh://gitea/jim/resume.git
|
git_repo: ssh://gitea/jim/resume.git
|
||||||
build_cache: ./build/resume
|
build_cache: ./build/resume
|
||||||
assets:
|
assets:
|
||||||
- 'shepich_resume.pdf'
|
- 'shepich_resume.pdf'
|
||||||
|
|
||||||
dogma_jimfinium:
|
dogma_jimfinium:
|
||||||
|
title: Dogma Jimfinium
|
||||||
base_url: http://localhost:8080/dogma-jimfinium
|
base_url: http://localhost:8080/dogma-jimfinium
|
||||||
git_repo: ssh://gitea/jim/dogma-jimfinium.git
|
git_repo: ssh://gitea/jim/dogma-jimfinium.git
|
||||||
build_cache: ./build/dogma-jimfinium
|
build_cache: ./build/dogma-jimfinium
|
||||||
|
|||||||
@ -10,11 +10,11 @@ from typing import Optional
|
|||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from dotmap import DotMap
|
from dotmap import DotMap
|
||||||
|
|
||||||
from .common import filepath_or_string, GlobalVars, SiteConfig
|
from .common import filepath_or_string, GlobalVars, SiteConfig, dotmap_access
|
||||||
from .templating import format_html_template, map_templates
|
from .templating import format_html_template, map_templates, TemplateSelections
|
||||||
from .assets import pull_git_repo, copy_assets
|
from .assets import pull_git_repo, copy_assets
|
||||||
from .articles import ArticleMetadata, load_markdown, build_articles, build_index
|
from .articles import ArticleMetadata, load_markdown, build_articles, build_index
|
||||||
|
from .blog import build_blog_archive, build_rss_feed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -25,6 +25,10 @@ from .articles import ArticleMetadata, load_markdown, build_articles, build_inde
|
|||||||
|
|
||||||
def build_site(site: SiteConfig, templates: DotMap):
|
def build_site(site: SiteConfig, templates: DotMap):
|
||||||
|
|
||||||
|
# Do not build a site marked as unpublished.
|
||||||
|
if not site.published:
|
||||||
|
return None
|
||||||
|
|
||||||
# Initialize the build cache and web root, in case they do not exist.
|
# Initialize the build cache and web root, in case they do not exist.
|
||||||
os.makedirs(site.build_cache, exist_ok = True)
|
os.makedirs(site.build_cache, exist_ok = True)
|
||||||
os.makedirs(site.web_root, exist_ok = True)
|
os.makedirs(site.web_root, exist_ok = True)
|
||||||
@ -39,8 +43,15 @@ def build_site(site: SiteConfig, templates: DotMap):
|
|||||||
# Load the site's articles into an index.
|
# Load the site's articles into an index.
|
||||||
index = build_index(site)
|
index = build_index(site)
|
||||||
|
|
||||||
|
# Determine which templates are to be used for explicit applications, e.g.
|
||||||
|
# the tag component.
|
||||||
|
template_selections = TemplateSelections(site, templates)
|
||||||
|
|
||||||
# Generate HTML pages for the articles.
|
# Generate HTML pages for the articles.
|
||||||
build_articles(site, index, templates)
|
build_articles(site, index, templates, template_selections)
|
||||||
|
|
||||||
|
if len(site.articles or []):
|
||||||
|
build_blog_archive(site, index, template_selections, templates = templates)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
@ -8,7 +8,7 @@ from dotmap import DotMap
|
|||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from .common import filepath_or_string, SiteConfig
|
from .common import filepath_or_string, SiteConfig
|
||||||
from .templating import format_html_template
|
from .templating import format_html_template, TemplateSelections
|
||||||
|
|
||||||
class ArticleMetadata(pydantic.BaseModel):
|
class ArticleMetadata(pydantic.BaseModel):
|
||||||
title: str
|
title: str
|
||||||
@ -70,30 +70,39 @@ def build_index(site: SiteConfig) -> dict:
|
|||||||
return index
|
return index
|
||||||
|
|
||||||
|
|
||||||
def format_article_tags(tags: list[str], template = 'templates/components/blog_tag.html') -> list[str]:
|
def format_article_tags(tags: list[str], tag_template, **kwargs) -> list[str]:
|
||||||
'''Generates HTML article tag components from a list of tag names.'''
|
'''Generates HTML article tag components from a list of tag names.'''
|
||||||
return [
|
return [
|
||||||
format_html_template(template, tag_name = t) for t in tags
|
format_html_template(tag_template, tag_name = t, **kwargs) for t in tags
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def build_articles(site: SiteConfig, index: dict[str, tuple[ArticleMetadata, str]], templates: DotMap):
|
def build_articles(
|
||||||
|
site: SiteConfig,
|
||||||
|
index: dict[str, tuple[ArticleMetadata, str]],
|
||||||
|
templates: DotMap,
|
||||||
|
template_selections: TemplateSelections
|
||||||
|
):
|
||||||
'''Generates HTML files for all of a given site's Markdown articles
|
'''Generates HTML files for all of a given site's Markdown articles
|
||||||
by interpolating the contents and metadata into the HTML templates.'''
|
by interpolating the contents and metadata into the HTML templates.'''
|
||||||
|
|
||||||
for filestem, (metadata, content) in index.items():
|
for filestem, (metadata, content) in index.items():
|
||||||
article = format_html_template(
|
article = format_html_template(
|
||||||
templates.components.blog_article,
|
template_selections['article'],
|
||||||
content = content,
|
content = content,
|
||||||
blog_tags = ' '.join(format_article_tags(metadata.tags)),
|
blog_tags = ' '.join(format_article_tags(
|
||||||
|
metadata.tags, template_selections['tag'], site = site
|
||||||
|
)),
|
||||||
metadata = metadata,
|
metadata = metadata,
|
||||||
templates = templates
|
templates = templates,
|
||||||
|
site = site
|
||||||
)
|
)
|
||||||
|
|
||||||
page = format_html_template(
|
page = format_html_template(
|
||||||
templates.pages.default,
|
template_selections['page'],
|
||||||
content = article,
|
content = article,
|
||||||
templates = templates
|
templates = templates,
|
||||||
|
site = site
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -4,14 +4,13 @@ import datetime
|
|||||||
|
|
||||||
from .common import SiteConfig
|
from .common import SiteConfig
|
||||||
from .articles import ArticleMetadata, format_article_tags
|
from .articles import ArticleMetadata, format_article_tags
|
||||||
from .templating import format_html_template
|
from .templating import format_html_template, TemplateSelections
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def build_blog_archive(
|
def build_blog_archive(
|
||||||
|
site: SiteConfig,
|
||||||
index: dict[str, tuple[str, str]],
|
index: dict[str, tuple[str, str]],
|
||||||
page_template = 'templates/pages/default.html',
|
template_selections: TemplateSelections,
|
||||||
li_template = 'templates/components/blog_archive_li.html',
|
|
||||||
**kwargs
|
**kwargs
|
||||||
) -> str:
|
) -> str:
|
||||||
'''Converts an index, formatted as filestem: (metadata, contents) dict,
|
'''Converts an index, formatted as filestem: (metadata, contents) dict,
|
||||||
@ -22,27 +21,50 @@ def build_blog_archive(
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
# Add each article as a list item to an unordered list.
|
# Add each article as a list item to an unordered list.
|
||||||
archive_html_content = '<ul>'
|
archive_html_list = '<ul>'
|
||||||
for article, (metadata, contents) in sorted(index.items(), key = lambda item: item[1][0].date)[::-1]:
|
for article, (metadata, contents) in sorted(index.items(), key = lambda item: item[1][0].date)[::-1]:
|
||||||
|
|
||||||
# Generate HTML for the article (including metadata tags).
|
# Generate HTML for the article (including metadata tags).
|
||||||
archive_html_content += format_html_template(
|
archive_html_list += format_html_template(
|
||||||
li_template,
|
template_selections['archive_li'],
|
||||||
article_filestem = article,
|
article_filestem = article,
|
||||||
blog_tags = ' '.join(format_article_tags(metadata.tags)),
|
blog_tags = ' '.join(format_article_tags(metadata.tags, template_selections['tag'], site = site)),
|
||||||
metadata = metadata
|
metadata = metadata,
|
||||||
|
site = site,
|
||||||
|
**kwargs
|
||||||
)
|
)
|
||||||
archive_html_content +='</ul>'
|
archive_html_list +='</ul>'
|
||||||
|
|
||||||
|
# Generate the archive article.
|
||||||
|
archive_html_article = format_html_template(
|
||||||
|
template_selections['archive_article'],
|
||||||
|
content = archive_html_list,
|
||||||
|
site = site,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
# Interpolate the article into the overall page template.
|
# Interpolate the article into the overall page template.
|
||||||
archive_html_page = format_html_template(
|
archive_html_page = format_html_template(
|
||||||
page_template,
|
template_selections['page'],
|
||||||
content = archive_html_content,
|
content = archive_html_article,
|
||||||
|
site = site,
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
return archive_html_page
|
with open(f'{site.web_root.rstrip('/')}/archive.html', 'w') as f:
|
||||||
|
f.write(archive_html_page)
|
||||||
|
|
||||||
|
|
||||||
|
def build_tag_reference(index: dict[str, tuple[str, str]]):
|
||||||
|
tag_index = {}
|
||||||
|
for article, (metadata, content) in index.items():
|
||||||
|
for tag in metadata.tags:
|
||||||
|
tag_index[tag] = (tag_index.get(tag,[])) + [article]
|
||||||
|
|
||||||
|
for tag, articles in tag_index.items():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: Finish
|
# TODO: Finish
|
||||||
def build_rss_feed(site: SiteConfig, index: dict[str, tuple[ArticleMetadata, str]]):
|
def build_rss_feed(site: SiteConfig, index: dict[str, tuple[ArticleMetadata, str]]):
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
|
import inspect
|
||||||
import subprocess
|
import subprocess
|
||||||
import pydantic
|
import pydantic
|
||||||
|
from dotmap import DotMap
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
|
|
||||||
@ -28,6 +30,42 @@ class SiteConfig(pydantic.BaseModel):
|
|||||||
base_url: str
|
base_url: str
|
||||||
web_root: str
|
web_root: str
|
||||||
build_cache: str
|
build_cache: str
|
||||||
|
title: str
|
||||||
|
published: Optional[bool] = True
|
||||||
git_repo: Optional[str] = None
|
git_repo: Optional[str] = None
|
||||||
assets: Optional[list] = None
|
assets: Optional[list] = None
|
||||||
articles: Optional[list] = None
|
articles: Optional[list] = None
|
||||||
|
template_selections: Optional[dict] = {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_var_names(var):
|
||||||
|
'''Gets the name(s) of an input variable.
|
||||||
|
From https://stackoverflow.com/questions/18425225/getting-the-name-of-a-variable-as-a-string.'''
|
||||||
|
callers_local_vars = inspect.currentframe().f_back.f_back.f_locals.items()
|
||||||
|
return [var_name for var_name, var_val in callers_local_vars if var_val is var]
|
||||||
|
|
||||||
|
|
||||||
|
def dotmap_access(d: DotMap, s: str):
|
||||||
|
'''Facilitates nested subscripting into a DotMap using a
|
||||||
|
string containing period-delimited keys.
|
||||||
|
|
||||||
|
# Example
|
||||||
|
```python
|
||||||
|
dd = DotMap({'a':{'b':{'c':42}}})
|
||||||
|
dotmap_access(dd, 'dd.a.b.c')
|
||||||
|
>>> 42
|
||||||
|
```
|
||||||
|
'''
|
||||||
|
|
||||||
|
keys = s.split('.')
|
||||||
|
|
||||||
|
# If the string starts with the dotmap's name, ignore it.
|
||||||
|
if keys[0] in get_var_names(d):
|
||||||
|
keys.pop(0)
|
||||||
|
|
||||||
|
# Iteratively subscript into the nested dotmap until it's done.
|
||||||
|
result = d
|
||||||
|
for k in keys:
|
||||||
|
result = result[k]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from dotmap import DotMap
|
from dotmap import DotMap
|
||||||
from .common import filepath_or_string, GlobalVars
|
from .common import filepath_or_string, GlobalVars, SiteConfig, dotmap_access
|
||||||
|
|
||||||
|
|
||||||
def extract_placeholders(s: str) -> set:
|
def extract_placeholders(s: str) -> set:
|
||||||
@ -120,4 +120,33 @@ def map_templates(dir: str, parent = '') -> DotMap:
|
|||||||
|
|
||||||
output[filestem] = html
|
output[filestem] = html
|
||||||
|
|
||||||
return DotMap(output)
|
return DotMap(output)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Come up with a more consistent naming scheme for defaults.
|
||||||
|
|
||||||
|
class TemplateSelections:
|
||||||
|
'''An interface for retrieving templates that are explicitly used in the
|
||||||
|
compiler, such as the article and tag components, as well as the default page.
|
||||||
|
|
||||||
|
Relies on `SiteConfig.template_selection` for custom overrides, falling back on
|
||||||
|
`config[template_default_selections]`, and finally on defaults hard-coded into
|
||||||
|
the definition of this class.
|
||||||
|
'''
|
||||||
|
def __init__(self, site: SiteConfig, templates: DotMap, config: dict = None):
|
||||||
|
self.site = site
|
||||||
|
self.templates = templates
|
||||||
|
self.defaults = dict(
|
||||||
|
tag = 'templates.components.blog_tag',
|
||||||
|
article = 'templates.components.blog_article',
|
||||||
|
page = 'templates.pages.default',
|
||||||
|
archive_li = 'templates.components.blog_archive_li',
|
||||||
|
archive_article = 'templates.components.blog_archive'
|
||||||
|
) | (config or {}).get('template_default_selections', {})
|
||||||
|
|
||||||
|
def __getitem__(self, key: str) -> str:
|
||||||
|
|
||||||
|
# Templates variable must be named `templates` for dotmap_access to work correctly.
|
||||||
|
templates = self.templates
|
||||||
|
return dotmap_access(templates, self.site.template_selections.get(key, self.defaults[key]))
|
||||||
|
|
||||||
|
|||||||
129
site/assets/img/favicon.svg
Normal file
129
site/assets/img/favicon.svg
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="190.6763mm"
|
||||||
|
height="190.67599mm"
|
||||||
|
viewBox="0 0 190.67628 190.676"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
sodipodi:docname="jimlab.svg"
|
||||||
|
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:zoom="0.46774"
|
||||||
|
inkscape:cx="153.93167"
|
||||||
|
inkscape:cy="366.65669"
|
||||||
|
inkscape:window-width="1280"
|
||||||
|
inkscape:window-height="727"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs1">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient18"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#666666;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop19" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#d9d9d9;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop20" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient18"
|
||||||
|
id="linearGradient20"
|
||||||
|
x1="109.12461"
|
||||||
|
y1="131.25221"
|
||||||
|
x2="92.506081"
|
||||||
|
y2="321.20288"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-5.4771806,-130.88957)">
|
||||||
|
<path
|
||||||
|
id="rect1-6-0-6"
|
||||||
|
style="display:inline;fill:url(#linearGradient20);fill-opacity:1;stroke:none;stroke-width:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
inkscape:label="hourglass"
|
||||||
|
d="m 10.305609,180.9727 45.2546,45.25461 -45.254596,45.25512 h 90.509717 90.50972 l -45.2546,-45.25512 45.2546,-45.2546 -90.50921,-1e-5 h -5.1e-4 -5.2e-4 z" />
|
||||||
|
<g
|
||||||
|
id="g14"
|
||||||
|
inkscape:label="blue-diamond"
|
||||||
|
transform="rotate(45,-14.34779,124.80922)"
|
||||||
|
style="display:inline">
|
||||||
|
<rect
|
||||||
|
style="display:inline;fill:#39b8ab;fill-opacity:1;stroke:none;stroke-width:1.54489;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect1-6-0"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
x="106.79844"
|
||||||
|
y="83.090195"
|
||||||
|
inkscape:label="big-trim" />
|
||||||
|
<rect
|
||||||
|
style="display:inline;fill:#47edda;fill-opacity:1;stroke:none;stroke-width:1.44834;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect1-6"
|
||||||
|
width="60"
|
||||||
|
height="60"
|
||||||
|
x="108.79844"
|
||||||
|
y="85.090195"
|
||||||
|
inkscape:label="big-fill" />
|
||||||
|
<rect
|
||||||
|
style="display:inline;fill:#39b8ab;fill-opacity:1;stroke:none;stroke-width:1.5831;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect1-6-7-0"
|
||||||
|
width="32"
|
||||||
|
height="32.000004"
|
||||||
|
x="122.79843"
|
||||||
|
y="99.090187"
|
||||||
|
inkscape:label="small-trim" />
|
||||||
|
<rect
|
||||||
|
style="display:inline;fill:#47edda;fill-opacity:1;stroke:none;stroke-width:1.3852;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect1-6-7"
|
||||||
|
width="28"
|
||||||
|
height="28.000002"
|
||||||
|
x="124.79843"
|
||||||
|
y="101.09019"
|
||||||
|
inkscape:label="small-fill" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#39b8ab;stroke-width:2.2595;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 108.89019,85.181941 15.81649,15.816499"
|
||||||
|
id="path11"
|
||||||
|
inkscape:label="top-trim" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#39b8ab;stroke-width:2.16775;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 153.56485,100.32377 168.73912,85.149504"
|
||||||
|
id="path12"
|
||||||
|
inkscape:label="right-trim" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#39b8ab;stroke-width:1.77778;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 152.79843,129.09019 16,16"
|
||||||
|
id="path13"
|
||||||
|
inkscape:label="bottom-trim" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#39b8ab;stroke-width:2;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 124.79843,129.09019 -15.99999,16"
|
||||||
|
id="path14"
|
||||||
|
inkscape:label="left-trim" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.5 KiB |
@ -1,22 +0,0 @@
|
|||||||
<html>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<head>
|
|
||||||
{templates.partials.default_css}
|
|
||||||
{templates.partials.header}
|
|
||||||
{templates.partials.nav}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<main>
|
|
||||||
<article>
|
|
||||||
<h1 class="headline">{metadata.title}</h1>
|
|
||||||
<p class="byline">
|
|
||||||
<address class="author">By <a rel="author" href="mailto:admin@jimlab.io">Jim Shepich III</a></address>
|
|
||||||
<br/>First published: <time pubdate datetime="{metadata.date}">{metadata.date}</time>
|
|
||||||
<br/>Last modified: <time pubdate datetime="{metadata.lastmod}">{metadata.lastmod}</time>
|
|
||||||
</p>
|
|
||||||
{content}
|
|
||||||
</article>
|
|
||||||
</main>
|
|
||||||
{templates.partials.footer}
|
|
||||||
</body>
|
|
||||||
5
site/templates/components/blog_archive.html
Normal file
5
site/templates/components/blog_archive.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<article>
|
||||||
|
<h1 class="headline">{site.title} Archive</h1>
|
||||||
|
<hr />
|
||||||
|
{content}
|
||||||
|
</article>
|
||||||
@ -1 +1 @@
|
|||||||
<a href='tags/{tag_name}.html'><span class='blog-tag'>{tag_name}</span></a>
|
<a href='{site.base_url}/tags/{tag_name}.html'><span class='blog-tag'>{tag_name}</span></a>
|
||||||
5
site/templates/components/simple_article.html
Normal file
5
site/templates/components/simple_article.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<article>
|
||||||
|
<h1 class="headline">{metadata.title}</h1>
|
||||||
|
<hr />
|
||||||
|
{content}
|
||||||
|
</article>
|
||||||
@ -5,6 +5,8 @@
|
|||||||
{templates.partials.default_css}
|
{templates.partials.default_css}
|
||||||
{templates.partials.header}
|
{templates.partials.header}
|
||||||
{templates.partials.nav}
|
{templates.partials.nav}
|
||||||
|
<title>{site.title}</title>
|
||||||
|
<link rel="icon" type="image/svg" href="/assets/img/favicon.svg">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<nav id="main-navbar" class="no-highlight">
|
<nav id="main-navbar" class="no-highlight">
|
||||||
<a href='/home.html' target='_self'><div class='nav-tab'><span class='nav-text'>Home</span></div></a>
|
<a href='/home.html' target='_self'><div class='nav-tab'><span class='nav-text'>Home</span></div></a>
|
||||||
<a href='/shepich_resume.pdf' target='_blank'><div class='nav-tab'><span class='nav-text'>Resume</span></div></a>
|
<a href='/shepich_resume.pdf' target='_blank'><div class='nav-tab'><span class='nav-text'>Resume</span></div></a>
|
||||||
<a href='/dogma-jimfinium/index.html' target='_self'><div class='nav-tab'><span class='nav-text'>Dogma Jimfinium</span></div></a>
|
<a href='/dogma-jimfinium/archive.html' target='_self'><div class='nav-tab'><span class='nav-text'>Dogma Jimfinium</span></div></a>
|
||||||
</nav>
|
</nav>
|
||||||
@ -1,14 +0,0 @@
|
|||||||
<html>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<head>
|
|
||||||
{templates.partials.default_css}
|
|
||||||
{templates.partials.header}
|
|
||||||
{templates.partials.nav}
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<main>
|
|
||||||
{content}
|
|
||||||
</main>
|
|
||||||
{templates.partials.footer}
|
|
||||||
</body>
|
|
||||||
@ -25,6 +25,14 @@
|
|||||||
"from jimsite import *"
|
"from jimsite import *"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "68b107f1",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 3,
|
"execution_count": 3,
|
||||||
@ -120,13 +128,74 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"execution_count": 4,
|
||||||
"id": "a28b95a6",
|
"id": "a28b95a6",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [
|
||||||
|
{
|
||||||
|
"ename": "NameError",
|
||||||
|
"evalue": "name 'build_site' is not defined",
|
||||||
|
"output_type": "error",
|
||||||
|
"traceback": [
|
||||||
|
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||||||
|
"\u001b[31mNameError\u001b[39m Traceback (most recent call last)",
|
||||||
|
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43mbuild_site\u001b[49m(sites[\u001b[33m'\u001b[39m\u001b[33mresume\u001b[39m\u001b[33m'\u001b[39m])\n",
|
||||||
|
"\u001b[31mNameError\u001b[39m: name 'build_site' is not defined"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"build_site(sites['resume'])"
|
"build_site(sites['resume'])"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 5,
|
||||||
|
"id": "60378277",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import inspect"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "cd7fb9f3",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"DotMap(a=DotMap(b=DotMap(c=42)))\n",
|
||||||
|
"a\n",
|
||||||
|
"DotMap(b=DotMap(c=42))\n",
|
||||||
|
"b\n",
|
||||||
|
"DotMap(c=42)\n",
|
||||||
|
"c\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"42"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 29,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "fcd2faf5",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user