Skip to content

Instantly share code, notes, and snippets.

@cyle
Last active November 26, 2021 17:35
Show Gist options
  • Save cyle/ae03689903128a73bd174ba16d3ad195 to your computer and use it in GitHub Desktop.
Save cyle/ae03689903128a73bd174ba16d3ad195 to your computer and use it in GitHub Desktop.
NPF powered tumblr theme prototype
<!--
Note that this is a very rough, incomplete prototype.
More info on how to possibly leverage it here: https://github.com/tumblr/docs/issues/49
-->
<!DOCTYPE html>
<html>
<head>
{MobileAppHeaders}
<meta charset="utf-8">
<title>{Title}{block:SearchPage} ({lang:Search results for SearchQuery}){/block:SearchPage}{block:PermalinkPage}{block:PostSummary} — {PostSummary}{/block:PostSummary}{/block:PermalinkPage}</title>
{block:Description}
<meta name="description" content="{MetaDescription}">
{/block:Description}
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="theme-color" content="#35465D">
<link rel="shortcut icon" href="{Favicon}">
<link rel="apple-touch-icon-precomposed" href="{PortraitURL-128}">
<link rel="alternate" type="application/rss+xml" href="{RSS}">
<link rel="stylesheet" href="https://static.tumblr.com/xu1kvii/TNpppppa3/main-min.css">
{PostTypographyStyles}
<style>
/* Colors */
body {
background: {BackgroundColor};
}
.blog-title {
font-family: {TitleFont}, "Helvetica Neue", HelveticaNeue, Arial, sans-serif;
font-weight: {TitleFontWeight};
}
.blog-title a,
.description,
.search-no-results,
.likes-no-likes,
.related-posts-wrapper > h2,
.loader .loader-bar,
.widget-title {
color: {TitleColor};
}
a {
color: {AccentColor};
}
#pagination a,
.nav-wrapper .nav-item .label {
color: {AccentColor};
}
#pagination a.next:after {
border-left-color: {AccentColor};
}
#pagination a.previous:after {
border-right-color: {AccentColor};
}
.header-image.cover {
background-image: url({HeaderImage});
}
.user-avatar {
background-color: {BackgroundColor};
border-color: {BackgroundColor};
}
.avatar-style-square .user-avatar {
-webkit-box-shadow: 0 0 0 4px {BackgroundColor};
box-shadow: 0 0 0 4px {BackgroundColor};
}
.no-header-image .logo-wrapper,
.contain-header-image .logo-wrapper {
color: {AccentColor};
}
div.npf_post {
border: 1px solid black;
padding: 1em;
margin-bottom: 3em;
}
div.npf_trail div.npf_post {
border: 1px solid gray;
margin-bottom: 1em;
}
p.npf_attribution {
font-size: 0.75rem;
}
p.npf_unknown_block {
color: red;
font-family: monospace;
}
div.npf_content img {
width: 100%;
height: auto;
}
/* Custom CSS */
{CustomCSS}
</style>
</head>
<body data-urlencoded-name="{URLEncodedName}" class="{select:Layout}{block:IndexPage} index-page{/block:IndexPage}{block:PermalinkPage} permalink{/block:PermalinkPage}{block:LikesPage} likes-page{/block:LikesPage}{block:FollowingPage} following-page{/block:FollowingPage}{block:SearchPage} search-page{block:NoSearchResults} no-results{/block:NoSearchResults}{block:NoLikes} no-likes{/block:NoLikes}{block:NoPosts} no-posts{/block:NoPosts}{block:NoFollowing} no-following{/block:NoFollowing}{/block:SearchPage}{block:HideHeaderImage} no-header-image{/block:HideHeaderImage}{block:NoStretchHeaderImage} contain-header-image{/block:NoStretchHeaderImage}{block:IfRelatedPosts} display-related-posts{/block:IfRelatedPosts}{block:ShowAdsOnThisPage} show-ads{/block:ShowAdsOnThisPage}">
<section id="page">
<div class="header-wrapper
{block:HideTitle}{block:HideDescription}no-title-desc {/block:HideDescription}{/block:HideTitle}
{block:HideHeaderImage}no-image {/block:HideHeaderImage}
{block:HideAvatar}avatar-hidden{/block:HideAvatar}
{block:ShowAvatar}avatar-style-{AvatarShape}{/block:ShowAvatar}">
<header id="header" class="top-blog-header">
{block:ShowHeaderImage}
<div class="header-image-wrapper {block:NoStretchHeaderImage}contain{/block:NoStretchHeaderImage}">
<a href="/" class="header-image {block:IfSlidingHeader}parallax{/block:IfSlidingHeader} {block:StretchHeaderImage}cover{/block:StretchHeaderImage} {block:NoStretchHeaderImage}contain{/block:NoStretchHeaderImage}" data-bg-image="{HeaderImage}">
{block:NoStretchHeaderImage}
<img src="{HeaderImage}" alt="">
{/block:NoStretchHeaderImage}
</a>
<div class="loader-bg"></div>
</div>
{/block:ShowHeaderImage}
<div class="blog-title-wrapper content">
<figure class="avatar-wrapper{block:IndexPage} animate{/block:IndexPage}">
<a href="/" style="background-image: url({PortraitURL-128})" class="user-avatar"><img src="{PortraitURL-128}" alt="" class="print-only invisible"></a>
</figure>
<div class="title-group{block:IndexPage} animate{/block:IndexPage}">
{block:ShowTitle}
<h1 class="blog-title"><a href="/">{Title}</a></h1>
{/block:ShowTitle}
{block:ShowDescription}
<span class="description">
{Description}
</span>
{/block:ShowDescription}
</div>
</div>
</header>
</div>
{block:IfShowNavigation}
<div class="{block:HideTitle}{block:HideDescription}no-title-desc {/block:HideDescription}{/block:HideTitle}nav-wrapper nav-responsive">
<nav class="nav-menu">
<ul class="inline-nav">
<li class="nav-item nav-item--archive">
<a href="/archive" class="label external-page">{lang:Archive}</a>
</li>
</ul>
</nav>
</div>
{/block:IfShowNavigation}
{block:SearchPage}
{block:NoSearchResults}
<div class="search-no-results content">
{lang:Sorry no search results found}.
</div>
{/block:NoSearchResults}
{/block:SearchPage}
{block:IndexPage}
{block:NoPosts}
<div class="posts-no-posts content"></div>
{/block:NoPosts}
{/block:IndexPage}
<section id="posts" class="content clearfix {block:HideTitle}{block:HideDescription}no-title-desc {/block:HideDescription}{/block:HideTitle}{block:HideHeaderImage}no-image {/block:HideHeaderImage} {block:ShowAvatar}avatar-style-{AvatarShape}{/block:ShowAvatar} {block:HideAvatar}avatar-hidden{/block:HideAvatar} {block:IfShowNavigation}show-nav{/block:IfShowNavigation}">
<div class="container">
<div class="main">
<script>var posts = new Array();</script>
{block:Posts}
<script>
posts['{PostId}'] = {NPF};
</script>
{/block:Posts}
<div id="post-list"></div>
</div>
</div>
</section>
<footer id="footer" class="content clearfix">
{block:IndexPage}
{block:Pagination}
<div id="pagination">
{block:PreviousPage}
<a href="{PreviousPage}" class="previous" data-current-page="{CurrentPage}" data-total-pages="{TotalPages}">{lang:Previous}<span class="bg"></span></a>
{/block:PreviousPage}
{block:NextPage}
<a href="{NextPage}" class="next" data-current-page="{CurrentPage}" data-total-pages="{TotalPages}">{lang:Next}<span class="bg"></span></a>
{/block:NextPage}
<div class="loader"><div class="loader-bar"></div><div class="loader-bar"></div><div class="loader-bar"></div></div>
</div>
{/block:Pagination}
{/block:IndexPage}
</footer>
</section>
<script>
const posts_div = document.getElementById('post-list');
console.log(posts);
for (let id in posts) {
const post_content_element = renderPostContent(posts[id], id);
posts_div.appendChild(post_content_element);
}
function renderPostContent(npf_data, id) {
const post_content = npf_data.content;
const post_trail = npf_data.trail;
const post_layout = npf_data.layout;
const post_blog_info = npf_data.blog;
let post_div = document.createElement('div');
post_div.setAttribute('class', 'npf_post');
// dumb stuff for debugging
let dummy_paragraph = document.createElement('p');
dummy_paragraph.setAttribute('class', 'npf_attribution');
let blog_name = 'this blog';
if (post_blog_info !== undefined) {
blog_name = post_blog_info.name;
}
let dummy_text = document.createTextNode('Post ID #' + id + ' by ' + blog_name);
dummy_paragraph.appendChild(dummy_text);
post_div.appendChild(dummy_paragraph);
// handle the trail if one exists
let trail_div = document.createElement('div');
trail_div.setAttribute('class', 'npf_trail');
if (post_trail !== undefined && post_trail.length > 0) {
for (let i in post_trail) {
const post_trail_data = post_trail[i];
const trail_content_element = renderPostContent(post_trail_data, post_trail_data.post.id);
trail_div.appendChild(trail_content_element);
}
}
post_div.appendChild(trail_div);
// handle the content if any exist
let content_div = document.createElement('div');
content_div.setAttribute('class', 'npf_content');
if (post_content.length > 0) {
for (let i in post_content) {
const content_block = post_content[i];
if (content_block.type === undefined) {
console.error('ran into a content block with no type!');
continue;
}
let content_block_element;
switch (content_block.type) {
case 'text':
content_block_element = renderTextBlock(content_block);
break;
case 'image':
content_block_element = renderImageBlock(content_block);
break;
default:
content_block_element = renderUnknownBlock(content_block);
}
if (content_block_element !== undefined) {
content_div.appendChild(content_block_element);
}
}
}
post_div.appendChild(content_div);
// not doing anything with layout yet
return post_div;
}
function renderTextBlock(text_content_block) {
let paragraph = document.createElement('p');
let text = document.createTextNode(text_content_block.text);
paragraph.appendChild(text);
return paragraph;
}
function renderImageBlock(image_content_block) {
let image = document.createElement('img');
image.setAttribute('src', image_content_block.media[0].url);
return image;
}
function renderUnknownBlock(content_block) {
let paragraph = document.createElement('p');
paragraph.setAttribute('class', 'npf_unknown_block');
let text = document.createTextNode("Dunno how to handle the '" + content_block.type + "' block type yet!");
paragraph.appendChild(text);
return paragraph;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment