Added blog archive
This commit is contained in:
parent
8b38b3e86d
commit
006aeab2c1
@ -145,3 +145,31 @@ summary.heading{
|
|||||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.blog-tag{
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 3px 3px 3px 3px;
|
||||||
|
background-color: var(--azure);
|
||||||
|
color: white;
|
||||||
|
font-size: 0.6em;
|
||||||
|
padding: 0.1em;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.blog-tag:hover{
|
||||||
|
background-color: var(--azure-tint-20);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:has(> span.blog-tag){
|
||||||
|
vertical-align: middle;
|
||||||
|
color: unset;
|
||||||
|
text-decoration: unset;
|
||||||
|
font-weight: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > hr{
|
||||||
|
border: 0.1rem solid var(--silver);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
32
main.py
32
main.py
@ -77,3 +77,35 @@ def load_partials() -> dict:
|
|||||||
current_year = datetime.now().year
|
current_year = datetime.now().year
|
||||||
)
|
)
|
||||||
return partials
|
return partials
|
||||||
|
|
||||||
|
|
||||||
|
def import_resume():
|
||||||
|
|
||||||
|
# Use a sentinel value for the loop.
|
||||||
|
max_date = '0000-00-00'
|
||||||
|
|
||||||
|
# Loop through the folders in the resume repo to find the most recent one.
|
||||||
|
for resume_folder in os.listdir('build/resume'):
|
||||||
|
|
||||||
|
# Skip folders that are not in YYYY-MM-DD format.
|
||||||
|
try:
|
||||||
|
datetime.strptime(resume_folder,'%Y-%m-%d')
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Keep track of the most recent date.
|
||||||
|
if resume_folder > max_date:
|
||||||
|
max_date = resume_folder
|
||||||
|
|
||||||
|
# Copy the resume into the /dist directory.
|
||||||
|
run(f'cp build/resume/{max_date}/shepich_resume.pdf dist/shepich_resume.pdf')
|
||||||
|
|
||||||
|
|
||||||
|
def format_blog_tags(tags: list[str], template = 'templates/components/blog_tag.html') -> list[str]:
|
||||||
|
'''Generates HTML blog tag components from a list of tag names.'''
|
||||||
|
return [
|
||||||
|
format_html_template(template, tag_name = t) for t in tags
|
||||||
|
]
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
pass
|
||||||
@ -1,5 +1,4 @@
|
|||||||
<html>
|
<html>
|
||||||
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<head>
|
<head>
|
||||||
@ -7,9 +6,8 @@
|
|||||||
{partials__header}
|
{partials__header}
|
||||||
{partials__nav}
|
{partials__nav}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<main>
|
||||||
<article>
|
<article>
|
||||||
<h1 class="headline">{metadata__title}</h1>
|
<h1 class="headline">{metadata__title}</h1>
|
||||||
<p class="byline">
|
<p class="byline">
|
||||||
@ -19,5 +17,6 @@
|
|||||||
</p>
|
</p>
|
||||||
{content}
|
{content}
|
||||||
</article>
|
</article>
|
||||||
|
</main>
|
||||||
{partials__footer}
|
{partials__footer}
|
||||||
</body>
|
</body>
|
||||||
1
templates/components/blog_archive_li.html
Normal file
1
templates/components/blog_archive_li.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<li>{metadata__date} - <a href='{article_filestem}.html'>{metadata__title}</a> {blog_tags}</li>
|
||||||
11
templates/components/blog_article.html
Normal file
11
templates/components/blog_article.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<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}
|
||||||
|
<hr />
|
||||||
|
<p>{blog_tags}</p>
|
||||||
|
</article>
|
||||||
1
templates/components/blog_tag.html
Normal file
1
templates/components/blog_tag.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<a href='tags/{tag_name}.html'><span class='blog-tag'>{tag_name}</span></a>
|
||||||
@ -1,4 +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>
|
||||||
</nav>
|
</nav>
|
||||||
14
templates/simple.html
Normal file
14
templates/simple.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<html>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<head>
|
||||||
|
{partials__default_css}
|
||||||
|
{partials__header}
|
||||||
|
{partials__nav}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
{content}
|
||||||
|
</main>
|
||||||
|
{partials__footer}
|
||||||
|
</body>
|
||||||
101
testbench.ipynb
101
testbench.ipynb
@ -11,7 +11,7 @@
|
|||||||
"- [] Determine static website structure\n",
|
"- [] Determine static website structure\n",
|
||||||
" - Where to put assets for subsites like dogma jimfinium\n",
|
" - Where to put assets for subsites like dogma jimfinium\n",
|
||||||
" - How to otherwise organize pages\n",
|
" - How to otherwise organize pages\n",
|
||||||
"- [] Resolve markdown links\n",
|
"- [x] ~~Resolve markdown links~~\n",
|
||||||
"- [] Consider separating article templates and overall page templates\n",
|
"- [] Consider separating article templates and overall page templates\n",
|
||||||
"- [] RSS feed\n",
|
"- [] RSS feed\n",
|
||||||
"\n",
|
"\n",
|
||||||
@ -27,7 +27,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 1,
|
"execution_count": 11,
|
||||||
"id": "207d2510",
|
"id": "207d2510",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@ -44,7 +44,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 9,
|
"execution_count": 12,
|
||||||
"id": "d2361c42",
|
"id": "d2361c42",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
@ -55,13 +55,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 10,
|
"execution_count": 31,
|
||||||
"id": "ed7b3b2f",
|
"id": "ed7b3b2f",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"PARTIALS = load_partials()\n",
|
"PARTIALS = load_partials()\n",
|
||||||
"html = format_html_template('templates/default.html', content = content, **{'metadata__'+k:v for k,v in metadata.items()}, **PARTIALS)\n",
|
"html = format_html_template('templates/blog_post.html', content = content, **{'metadata__'+k:v for k,v in metadata.items()}, **PARTIALS)\n",
|
||||||
"with open('dist/home.html', 'w') as f:\n",
|
"with open('dist/home.html', 'w') as f:\n",
|
||||||
" f.write(html)"
|
" f.write(html)"
|
||||||
]
|
]
|
||||||
@ -98,23 +98,92 @@
|
|||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"source": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 58,
|
||||||
|
"id": "944a5efd",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"def get_latest_resume():\n",
|
"run(f'rm -rf dist/dogma-jimfinium && mkdir -p dist/dogma-jimfinium')\n",
|
||||||
" max_date = '0000-00-00'\n",
|
"run(f'cp -r build/dogma-jimfinium/assets dist/dogma-jimfinium')\n",
|
||||||
" for resume_folder in os.listdir('build/resume'):\n",
|
"\n",
|
||||||
" try:\n",
|
"index = {}\n",
|
||||||
" datetime.strptime(resume_folder,'%Y-%m-%d')\n",
|
"\n",
|
||||||
" except Exception:\n",
|
"for article in os.listdir('build/dogma-jimfinium'):\n",
|
||||||
|
" metadata, content = load_markdown(f'build/dogma-jimfinium/{article}')\n",
|
||||||
|
"\n",
|
||||||
|
" # Skip unpublished articles.\n",
|
||||||
|
" if not metadata.get('published'):\n",
|
||||||
" continue\n",
|
" continue\n",
|
||||||
"\n",
|
"\n",
|
||||||
" if resume_folder > max_date:\n",
|
" article_filestem = os.path.splitext(article)[0]\n",
|
||||||
" max_date = resume_folder\n",
|
"\n",
|
||||||
|
" # Add the article to the index.\n",
|
||||||
|
" index[article_filestem] = (metadata, content)\n",
|
||||||
|
"\n",
|
||||||
|
" # Interpolate the article contents into the webpage template.\n",
|
||||||
|
" article_html = format_html_template(\n",
|
||||||
|
" 'templates/components/blog_article.html',\n",
|
||||||
|
" content = content,\n",
|
||||||
|
" blog_tags = ' '.join(format_blog_tags(metadata['tags'])),\n",
|
||||||
|
" **{'metadata__'+k:v for k,v in metadata.items()}\n",
|
||||||
|
" )\n",
|
||||||
|
" html = format_html_template('templates/simple.html', content = article_html, **PARTIALS)\n",
|
||||||
|
" \n",
|
||||||
|
" # Write the HTML file to /dist/dogma-jimfinium.\n",
|
||||||
|
" with open(f'dist/dogma-jimfinium/{article_filestem}.html', 'w') as f:\n",
|
||||||
|
" f.write(html)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
" print(max_date)\n",
|
"index_html = build_blog_archive(index, metadata__title = 'Dogma Jimfinium | Index')\n",
|
||||||
" # print(max_date.strftime('%Y-%m-%d'))\n",
|
"# Write the HTML file to /dist/dogma-jimfinium.\n",
|
||||||
|
"with open(f'dist/dogma-jimfinium/index.html', 'w') as f:\n",
|
||||||
|
" f.write(index_html)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "e32458c7",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "e3171afd",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"def build_blog_archive(index: dict[str, tuple[str, str]], template = 'templates/simple.html', **kwargs) -> str:\n",
|
||||||
|
" '''Converts an index, formatted as filestem: (metadata, contents) dict,\n",
|
||||||
|
" into an HTML page containing the list of articles, sorted from newest to oldest.'''\n",
|
||||||
"\n",
|
"\n",
|
||||||
" run(f'cp build/resume/{max_date}/shepich_resume.pdf dist/shepich_resume.pdf')"
|
" # Add each article in the format `YYYY-MM-DD - Title`\n",
|
||||||
|
" index_html_content = '<ul>'\n",
|
||||||
|
" for article, (metadata, contents) in sorted(index.items(), key = lambda item: item[1][0]['date'])[::-1]:\n",
|
||||||
|
" blog_tags = ' '.join(format_blog_tags(metadata['tags']))\n",
|
||||||
|
" index_html_content += format_html_template(\n",
|
||||||
|
" 'templates/components/blog_archive_li.html',\n",
|
||||||
|
" article_filestem = article,\n",
|
||||||
|
" blog_tags = blog_tags,\n",
|
||||||
|
" **{'metadata__'+k:v for k,v in metadata.items()}\n",
|
||||||
|
" \n",
|
||||||
|
" )\n",
|
||||||
|
" index_html_content +='</ul>'\n",
|
||||||
|
"\n",
|
||||||
|
" index_html_page = format_html_template(\n",
|
||||||
|
" template, \n",
|
||||||
|
" content = index_html_content, \n",
|
||||||
|
" **kwargs,\n",
|
||||||
|
" **PARTIALS\n",
|
||||||
|
" )\n",
|
||||||
|
" \n",
|
||||||
|
" return index_html_page"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user