Add user-facing templates and pages
This commit is contained in:
55
templates/base.tmpl
Normal file
55
templates/base.tmpl
Normal file
@@ -0,0 +1,55 @@
|
||||
{{define "base"}}<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
{{ template "head" . }}
|
||||
<link rel="stylesheet" type="text/css" href="{{.Host}}/css/{{.Theme}}.css" />
|
||||
<link rel="shortcut icon" href="{{.Host}}/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<meta name="application-name" content="{{.SiteName}}">
|
||||
<meta name="application-url" content="{{.Host}}">
|
||||
<meta property="og:site_name" content="{{.SiteName}}" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="overlay"></div>
|
||||
<header>
|
||||
<h2><a href="/">{{.SiteName}}</a></h2>
|
||||
{{if .HeaderNav}}
|
||||
<nav id="user-nav">
|
||||
<nav class="tabs">
|
||||
<a href="/about"{{if eq .Path "/about"}} class="selected"{{end}}>About</a>
|
||||
<a href="/login"{{if eq .Path "/login"}} class="selected"{{end}}>Log in</a>
|
||||
</nav>
|
||||
</nav>
|
||||
{{end}}
|
||||
</header>
|
||||
|
||||
<div id="official-writing">
|
||||
{{ template "content" . }}
|
||||
</div>
|
||||
|
||||
{{ template "footer" . }}
|
||||
|
||||
{{if not .JSDisabled}}
|
||||
<script type="text/javascript">
|
||||
{{if .WebFonts}}
|
||||
try { // Google Fonts
|
||||
WebFontConfig = {
|
||||
custom: { families: [ 'Lora:400,700:latin', 'Open+Sans:400,700:latin' ], urls: [ '/css/fonts.css' ] }
|
||||
};
|
||||
(function() {
|
||||
var wf = document.createElement('script');
|
||||
wf.src = '/js/webfont.js';
|
||||
wf.type = 'text/javascript';
|
||||
wf.async = 'true';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})();
|
||||
} catch (e) { /* ¯\_(ツ)_/¯ */ }
|
||||
{{end}}
|
||||
</script>
|
||||
{{else}}
|
||||
{{if .WebFonts}}<link href="{{.Host}}/css/fonts.css" rel="stylesheet" type="text/css" />{{end}}
|
||||
{{end}}
|
||||
</body>
|
||||
</html>{{end}}
|
135
templates/collection-post.tmpl
Normal file
135
templates/collection-post.tmpl
Normal file
@@ -0,0 +1,135 @@
|
||||
{{define "post"}}<!DOCTYPE HTML>
|
||||
<html {{if .Language.Valid}}lang="{{.Language.String}}"{{end}} dir="{{.Direction}}">
|
||||
<head prefix="og: http://ogp.me/ns# article: http://ogp.me/ns/article#">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>{{.PlainDisplayTitle}} — {{.Collection.DisplayTitle}}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/write.css" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="canonical" href="{{.CanonicalURL}}" />
|
||||
<meta name="generator" content="Write Freely">
|
||||
<meta name="title" content="{{.PlainDisplayTitle}} — {{if .Collection.Title}}{{.Collection.Title}}{{else}}{{.Collection.Alias}}{{end}}">
|
||||
<meta name="description" content="{{.Summary}}">
|
||||
{{if gt .Views 1}}<meta name="twitter:label1" value="Views">
|
||||
<meta name="twitter:data1" value="{{largeNumFmt .Views}}">{{end}}
|
||||
<meta name="author" content="{{.Collection.Title}}" />
|
||||
<meta itemprop="description" content="{{.Summary}}">
|
||||
<meta itemprop="datePublished" content="{{.CreatedDate}}" />
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:description" content="{{.Summary}}">
|
||||
<meta name="twitter:title" content="{{.PlainDisplayTitle}} — {{if .Collection.Title}}{{.Collection.Title}}{{else}}{{.Collection.Alias}}{{end}}">
|
||||
{{if gt (len .Images) 0}}<meta name="twitter:image" content="{{index .Images 0}}">{{else}}<meta name="twitter:image" content="https://write.as/img/w-sq-light.png">{{end}}
|
||||
<meta property="og:title" content="{{.PlainDisplayTitle}}" />
|
||||
<meta property="og:description" content="{{.Summary}}" />
|
||||
<meta property="og:site_name" content="{{.Collection.DisplayTitle}}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="{{.CanonicalURL}}" />
|
||||
<meta property="og:updated_time" content="{{.Created8601}}" />
|
||||
{{range .Images}}<meta property="og:image" content="{{.}}" />{{else}}<meta property="og:image" content="https://write.as/img/w-sq-light.png">{{end}}
|
||||
<meta property="article:published_time" content="{{.Created8601}}">
|
||||
{{if .Collection.StyleSheet}}<style type="text/css">{{.Collection.StyleSheetDisplay}}</style>{{end}}
|
||||
{{if .Collection.RenderMathJax}}
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
extensions: ["tex2jax.js"],
|
||||
jax: ["input/TeX", "output/HTML-CSS"],
|
||||
tex2jax: {
|
||||
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
|
||||
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
||||
processEscapes: true
|
||||
},
|
||||
"HTML-CSS": { fonts: ["TeX"] }
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML" async></script>{{end}}
|
||||
|
||||
</head>
|
||||
<body id="post">
|
||||
|
||||
<div id="overlay"></div>
|
||||
|
||||
<header>
|
||||
<h1 dir="{{.Direction}}" id="blog-title"><a rel="author" href="{{if .IsTopLevel}}/{{else}}/{{.Collection.Alias}}/{{end}}" class="h-card p-author">{{.Collection.DisplayTitle}}</a></h1>
|
||||
<nav>
|
||||
{{if .PinnedPosts}}
|
||||
{{range .PinnedPosts}}<a class="pinned{{if eq .Slug.String $.Slug.String}} selected{{end}}" href="{{if $.IsOwner}}/{{$.Collection.Alias}}/{{.Slug.String}}{{else}}{{.CanonicalURL}}{{end}}">{{.PlainDisplayTitle}}</a>{{end}}
|
||||
{{end}}
|
||||
{{ if .IsOwner }}<span class="views" dir="ltr"><strong>{{largeNumFmt .Views}}</strong> {{pluralize "view" "views" .Views}}</span>
|
||||
<a class="xtra-feature" href="/{{.Collection.Alias}}/{{.Slug.String}}/edit" dir="{{.Direction}}">Edit</a>
|
||||
{{if .IsPinned}}<a class="xtra-feature unpin" href="/{{.Collection.Alias}}/{{.Slug.String}}/unpin" dir="{{.Direction}}" onclick="unpinPost(event, '{{.ID}}')">Unpin</a>{{end}}
|
||||
{{ end }}
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<article id="post-body" class="{{.Font}} h-entry">{{if .IsScheduled}}<p class="badge">Scheduled</p>{{end}}{{if .Title.String}}<h2 id="title" class="p-name">{{.FormattedDisplayTitle}}</h2>{{end}}<div class="e-content">{{.HTMLContent}}</div></article>
|
||||
|
||||
{{ if .Collection.ShowFooterBranding }}
|
||||
<footer dir="ltr"><hr><nav><p style="font-size: 0.9em">{{localhtml "published with write.as" .Language.String}}</p></nav></footer>
|
||||
{{ end }}
|
||||
</body>
|
||||
|
||||
{{if .Collection.CanShowScript}}
|
||||
{{range .Collection.ExternalScripts}}<script type="text/javascript" src="{{.}}" async></script>{{end}}
|
||||
{{if .Collection.Script}}<script type="text/javascript">{{.Collection.ScriptDisplay}}</script>{{end}}
|
||||
{{end}}
|
||||
<script type="text/javascript">
|
||||
|
||||
var pinning = false;
|
||||
function unpinPost(e, postID) {
|
||||
e.preventDefault();
|
||||
if (pinning) {
|
||||
return;
|
||||
}
|
||||
pinning = true;
|
||||
|
||||
var $header = document.getElementsByTagName('header')[0];
|
||||
var callback = function() {
|
||||
// Hide current page
|
||||
var $pinnedNavLink = $header.getElementsByTagName('nav')[0].querySelector('.pinned.selected');
|
||||
$pinnedNavLink.style.display = 'none';
|
||||
try { _paq.push(['trackEvent', 'Post', 'unpin', 'post']); } catch(e) {}
|
||||
};
|
||||
|
||||
var $pinBtn = $header.getElementsByClassName('unpin')[0];
|
||||
$pinBtn.innerHTML = '...';
|
||||
|
||||
var http = new XMLHttpRequest();
|
||||
var url = "/api/collections/{{.Collection.Alias}}/unpin";
|
||||
var params = [ { "id": postID } ];
|
||||
http.open("POST", url, true);
|
||||
http.setRequestHeader("Content-type", "application/json");
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState == 4) {
|
||||
pinning = false;
|
||||
if (http.status == 200) {
|
||||
callback();
|
||||
$pinBtn.style.display = 'none';
|
||||
$pinBtn.innerHTML = 'Pin';
|
||||
} else if (http.status == 409) {
|
||||
$pinBtn.innerHTML = 'Unpin';
|
||||
} else {
|
||||
$pinBtn.innerHTML = 'Unpin';
|
||||
alert("Failed to unpin." + (http.status>=500?" Please try again.":""));
|
||||
}
|
||||
}
|
||||
}
|
||||
http.send(JSON.stringify(params));
|
||||
};
|
||||
|
||||
try { // Fonts
|
||||
WebFontConfig = {
|
||||
custom: { families: [ 'Lora:400,700:latin', 'Open+Sans:400,700:latin' ], urls: [ '/css/fonts.css' ] }
|
||||
};
|
||||
(function() {
|
||||
var wf = document.createElement('script');
|
||||
wf.src = '/js/webfont.js';
|
||||
wf.type = 'text/javascript';
|
||||
wf.async = 'true';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})();
|
||||
} catch (e) { /* ¯\_(ツ)_/¯ */ }
|
||||
</script>
|
||||
</html>{{end}}
|
198
templates/collection-tags.tmpl
Normal file
198
templates/collection-tags.tmpl
Normal file
@@ -0,0 +1,198 @@
|
||||
{{define "collection-tags"}}<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head prefix="og: http://ogp.me/ns# article: http://ogp.me/ns/article#">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>{{.Tag}} — {{.Collection.DisplayTitle}}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{if .IsCustomDomain}}https://files.writeas.org{{end}}/css/write.css" />
|
||||
<link rel="shortcut icon" href="{{ if .Collection.ShowFooterBranding }}{{if .IsCustomDomain}}https://files.writeas.org{{end}}/favicon.ico{{ else }}/none.ico{{ end }}" />
|
||||
{{if not .Collection.IsPrivate}}<link rel="alternate" type="application/rss+xml" title="{{.Tag}} posts on {{.DisplayTitle}}" href="{{.CanonicalURL}}tag:{{.Tag}}/feed/" />{{end}}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="canonical" href="{{.CanonicalURL}}tag:{{.Tag | tolower}}" />
|
||||
<meta name="generator" content="Write.as">
|
||||
<meta name="title" content="{{.Tag}} — {{.Collection.DisplayTitle}}">
|
||||
<meta name="description" content="{{.Tag}} posts on {{.Collection.DisplayTitle}}">
|
||||
<meta name="application-name" content="Write.as">
|
||||
<meta name="application-url" content="https://write.as">
|
||||
{{if gt .Views 1}}<meta name="twitter:label1" value="Views">
|
||||
<meta name="twitter:data1" value="{{largeNumFmt .Views}}">{{end}}
|
||||
<meta itemprop="name" content="{{.Collection.DisplayTitle}}">
|
||||
<meta itemprop="description" content="{{.Tag}} posts on {{.Collection.DisplayTitle}}">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@writeas__">
|
||||
<meta name="twitter:description" content="{{.Tag}} posts on {{.Collection.DisplayTitle}}">
|
||||
<meta name="twitter:title" content="{{.Tag}} — {{.Collection.DisplayTitle}}">
|
||||
<meta property="og:title" content="{{.Tag}} — {{.Collection.DisplayTitle}}" />
|
||||
<meta property="og:site_name" content="{{.DisplayTitle}}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="{{.CanonicalURL}}tag:{{.Tag}}" />
|
||||
{{if .Collection.StyleSheet}}<style type="text/css">{{.Collection.StyleSheetDisplay}}</style>{{end}}
|
||||
{{if .Collection.RenderMathJax}}
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
extensions: ["tex2jax.js"],
|
||||
jax: ["input/TeX", "output/HTML-CSS"],
|
||||
tex2jax: {
|
||||
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
|
||||
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
||||
processEscapes: true
|
||||
},
|
||||
"HTML-CSS": { fonts: ["TeX"] }
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML" async></script>{{end}}
|
||||
|
||||
</head>
|
||||
<body id="subpage">
|
||||
|
||||
<div id="overlay"></div>
|
||||
|
||||
<header>
|
||||
<h1 dir="{{.Direction}}" id="blog-title"><a href="{{if .IsTopLevel}}/{{else}}/{{.Collection.Alias}}/{{end}}" class="h-card p-author">{{.Collection.DisplayTitle}}</a></h1>
|
||||
<nav>
|
||||
{{if .PinnedPosts}}
|
||||
{{range .PinnedPosts}}<a class="pinned" href="{{if $.IsOwner}}/{{$.Collection.Alias}}/{{.Slug.String}}{{else}}{{.CanonicalURL}}{{end}}">{{.DisplayTitle}}</a>{{end}}
|
||||
{{end}}
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
{{if .Posts}}<section id="wrapper" itemscope itemtype="http://schema.org/Blog">{{else}}<div id="wrapper">{{end}}
|
||||
<h1>{{.Tag}}</h1>
|
||||
{{template "posts" .}}
|
||||
{{if .Posts}}</section>{{else}}</div>{{end}}
|
||||
|
||||
{{ if .Collection.ShowFooterBranding }}
|
||||
<footer dir="ltr">
|
||||
<hr>
|
||||
<nav>
|
||||
<p style="font-size: 0.9em"><a class="home pubd" href="/">{{.SiteName}}</a> · powered by <a style="margin-left:0" href="https://writefreely.org">write freely</a></p>
|
||||
</nav>
|
||||
</footer>
|
||||
{{ end }}
|
||||
</body>
|
||||
|
||||
{{if .CanShowScript}}
|
||||
{{range .ExternalScripts}}<script type="text/javascript" src="{{.}}" async></script>{{end}}
|
||||
{{if .Collection.Script}}<script type="text/javascript">{{.ScriptDisplay}}</script>{{end}}
|
||||
{{end}}
|
||||
{{if .IsOwner}}
|
||||
<script src="/js/h.js"></script>
|
||||
<script src="/js/postactions.js"></script>
|
||||
{{end}}
|
||||
<script type="text/javascript">
|
||||
{{if .IsOwner}}
|
||||
var deleting = false;
|
||||
function delPost(e, id, owned) {
|
||||
e.preventDefault();
|
||||
if (deleting) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: UNDO!
|
||||
if (window.confirm('Are you sure you want to delete this post?')) {
|
||||
// AJAX
|
||||
deletePost(id, "", function() {
|
||||
// Remove post from list
|
||||
var $postEl = document.getElementById('post-' + id);
|
||||
$postEl.parentNode.removeChild($postEl);
|
||||
// TODO: add next post from this collection at the bottom
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var deletePost = function(postID, token, callback) {
|
||||
deleting = true;
|
||||
|
||||
var $delBtn = document.getElementById('post-' + postID).getElementsByClassName('delete action')[0];
|
||||
$delBtn.innerHTML = '...';
|
||||
|
||||
var http = new XMLHttpRequest();
|
||||
var url = "/api/posts/" + postID;
|
||||
http.open("DELETE", url, true);
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState == 4) {
|
||||
deleting = false;
|
||||
if (http.status == 204) {
|
||||
callback();
|
||||
} else if (http.status == 409) {
|
||||
$delBtn.innerHTML = 'delete';
|
||||
alert("Post is synced to another account. Delete the post from that account instead.");
|
||||
// TODO: show "remove" button instead of "delete" now
|
||||
// Persist that state.
|
||||
// Have it remove the post locally only.
|
||||
} else {
|
||||
$delBtn.innerHTML = 'delete';
|
||||
alert("Failed to delete." + (http.status>=500?" Please try again.":""));
|
||||
}
|
||||
}
|
||||
}
|
||||
http.send();
|
||||
};
|
||||
|
||||
var pinning = false;
|
||||
function pinPost(e, postID, slug, title) {
|
||||
e.preventDefault();
|
||||
if (pinning) {
|
||||
return;
|
||||
}
|
||||
pinning = true;
|
||||
|
||||
var callback = function() {
|
||||
// Visibly remove post from collection
|
||||
var $postEl = document.getElementById('post-' + postID);
|
||||
$postEl.parentNode.removeChild($postEl);
|
||||
var $header = document.getElementsByTagName('header')[0];
|
||||
var $pinnedNavs = $header.getElementsByTagName('nav');
|
||||
// Add link to nav
|
||||
var link = '<a class="pinned" href="/{{.Alias}}/'+slug+'">'+title+'</a>';
|
||||
if ($pinnedNavs.length == 0) {
|
||||
$header.insertAdjacentHTML("beforeend", '<nav>'+link+'</nav>');
|
||||
} else {
|
||||
$pinnedNavs[0].insertAdjacentHTML("beforeend", link);
|
||||
}
|
||||
};
|
||||
|
||||
var $pinBtn = document.getElementById('post-' + postID).getElementsByClassName('pin action')[0];
|
||||
$pinBtn.innerHTML = '...';
|
||||
|
||||
var http = new XMLHttpRequest();
|
||||
var url = "/api/collections/{{.Alias}}/pin";
|
||||
var params = [ { "id": postID } ];
|
||||
http.open("POST", url, true);
|
||||
http.setRequestHeader("Content-type", "application/json");
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState == 4) {
|
||||
pinning = false;
|
||||
if (http.status == 200) {
|
||||
callback();
|
||||
} else if (http.status == 409) {
|
||||
$pinBtn.innerHTML = 'pin';
|
||||
alert("Post is synced to another account. Delete the post from that account instead.");
|
||||
// TODO: show "remove" button instead of "delete" now
|
||||
// Persist that state.
|
||||
// Have it remove the post locally only.
|
||||
} else {
|
||||
$pinBtn.innerHTML = 'pin';
|
||||
alert("Failed to pin." + (http.status>=500?" Please try again.":""));
|
||||
}
|
||||
}
|
||||
}
|
||||
http.send(JSON.stringify(params));
|
||||
};
|
||||
{{end}}
|
||||
try { // Fonts
|
||||
WebFontConfig = {
|
||||
custom: { families: [ 'Lora:400,700:latin', 'Open+Sans:400,700:latin' ], urls: [ '{{if .IsCustomDomain}}https://files.writeas.org{{end}}/css/fonts.css' ] }
|
||||
};
|
||||
(function() {
|
||||
var wf = document.createElement('script');
|
||||
wf.src = '{{if .IsCustomDomain}}https://files.writeas.org{{end}}/js/webfont.js';
|
||||
wf.type = 'text/javascript';
|
||||
wf.async = 'true';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})();
|
||||
} catch (e) { /* ¯\_(ツ)_/¯ */ }
|
||||
</script>
|
||||
</html>{{end}}
|
225
templates/collection.tmpl
Normal file
225
templates/collection.tmpl
Normal file
@@ -0,0 +1,225 @@
|
||||
{{define "collection"}}<!DOCTYPE HTML>
|
||||
<html {{if .Language}}lang="{{.Language}}"{{end}} dir="{{.Direction}}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>{{.DisplayTitle}}{{if not .SingleUser}} — {{.SiteName}}{{end}}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/write.css" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<link rel="canonical" href="{{.CanonicalURL}}">
|
||||
{{if gt .CurrentPage 1}}<link rel="prev" href="{{.PrevPageURL .Prefix .CurrentPage .IsTopLevel}}">{{end}}
|
||||
{{if lt .CurrentPage .TotalPages}}<link rel="next" href="{{.NextPageURL .Prefix .CurrentPage .IsTopLevel}}">{{end}}
|
||||
{{if not .IsPrivate}}<link rel="alternate" type="application/rss+xml" title="{{.DisplayTitle}} » Feed" href="{{.CanonicalURL}}feed/" />{{end}}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<meta name="generator" content="Write Freely">
|
||||
<meta name="description" content="{{.Description}}">
|
||||
<meta itemprop="name" content="{{.DisplayTitle}}">
|
||||
<meta itemprop="description" content="{{.Description}}">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="{{.DisplayTitle}}">
|
||||
<meta name="twitter:description" content="{{.Description}}">
|
||||
<meta property="og:title" content="{{.DisplayTitle}}" />
|
||||
<meta property="og:site_name" content="{{.DisplayTitle}}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="{{.CanonicalURL}}" />
|
||||
<meta property="og:description" content="{{.Description}}" />
|
||||
{{if .StyleSheet}}<style type="text/css">{{.StyleSheetDisplay}}</style>{{end}}
|
||||
{{if .RenderMathJax}}
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
extensions: ["tex2jax.js"],
|
||||
jax: ["input/TeX", "output/HTML-CSS"],
|
||||
tex2jax: {
|
||||
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
|
||||
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
||||
processEscapes: true
|
||||
},
|
||||
"HTML-CSS": { fonts: ["TeX"] }
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML" async></script>{{end}}
|
||||
|
||||
</head>
|
||||
<body id="collection" itemscope itemtype="http://schema.org/WebPage">
|
||||
{{if .IsOwner}}<nav id="manage"><ul>
|
||||
<li><a onclick="void(0)">☰ Menu</a>
|
||||
<ul>
|
||||
<li><a href="/#{{.Alias}}" class="write">{{.SiteName}}</a></li>
|
||||
<li><a href="/me/c/{{.Alias}}">Customize</a></li>
|
||||
<li><a href="/me/c/{{.Alias}}/stats">Stats</a></li>
|
||||
<li class="separator"><hr /></li>
|
||||
<li><a href="/me/c/"><img class="ic-18dp" src="/img/ic_blogs_dark@2x.png" /> View Blogs</a></li>
|
||||
<li><a href="/me/posts/"><img class="ic-18dp" src="/img/ic_list_dark@2x.png" /> View Drafts</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul></nav>{{end}}
|
||||
|
||||
<header>
|
||||
<h1 dir="{{.Direction}}" id="blog-title">{{if .Posts}}{{else}}<span class="writeas-prefix"><a href="/">write.as</a></span> {{end}}<a href="/{{if .IsTopLevel}}{{else}}{{.Prefix}}{{.Alias}}/{{end}}" class="h-card p-author u-url" rel="me author">{{.DisplayTitle}}</a></h1>
|
||||
{{if .Description}}<p class="description p-note">{{.Description}}</p>{{end}}
|
||||
{{/*if not .Public/*}}
|
||||
<!--p class="meta-note"><span>Private collection</span>. Only you can see this page.</p-->
|
||||
{{/*end*/}}
|
||||
{{if .PinnedPosts}}<nav>
|
||||
{{range .PinnedPosts}}<a class="pinned" href="{{if $.IsOwner}}/{{$.Alias}}/{{.Slug.String}}{{else}}{{.CanonicalURL}}{{end}}">{{.PlainDisplayTitle}}</a>{{end}}</nav>
|
||||
{{end}}
|
||||
</header>
|
||||
|
||||
{{if .Posts}}<section id="wrapper" itemscope itemtype="http://schema.org/Blog">{{else}}<div id="wrapper">{{end}}
|
||||
|
||||
{{if .IsWelcome}}
|
||||
<div id="welcome">
|
||||
<h2>Welcome, <strong>{{.Username}}</strong>!</h2>
|
||||
<p>This is your new blog.</p>
|
||||
<p><a class="simple-cta" href="/#{{.Alias}}">Start writing</a>, or <a class="simple-cta" href="/me/c/{{.Alias}}">customize</a> your blog.</p>
|
||||
<p>Check out our <a class="simple-cta" href="https://guides.write.as/writing/?pk_campaign=welcome">writing guide</a> to see what else you can do, and <a class="simple-cta" href="/contact">get in touch</a> anytime with questions or feedback.</p>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{template "posts" .}}
|
||||
|
||||
{{if gt .TotalPages 1}}<nav id="paging" class="content-container clearfix">
|
||||
{{if or (and .Format.Ascending (lt .CurrentPage .TotalPages)) (isRTL .Direction)}}
|
||||
{{if gt .CurrentPage 1}}<a href="{{.PrevPageURL .Prefix .CurrentPage .IsTopLevel}}">⇠ {{if and .Format.Ascending (lt .CurrentPage .TotalPages)}}Previous{{else}}Newer{{end}}</a>{{end}}
|
||||
{{if lt .CurrentPage .TotalPages}}<a style="float:right;" href="{{.NextPageURL .Prefix .CurrentPage .IsTopLevel}}">{{if and .Format.Ascending (lt .CurrentPage .TotalPages)}}Next{{else}}Older{{end}} ⇢</a>{{end}}
|
||||
{{else}}
|
||||
{{if lt .CurrentPage .TotalPages}}<a href="{{.NextPageURL .Prefix .CurrentPage .IsTopLevel}}">⇠ Older</a>{{end}}
|
||||
{{if gt .CurrentPage 1}}<a style="float:right;" href="{{.PrevPageURL .Prefix .CurrentPage .IsTopLevel}}">Newer ⇢</a>{{end}}
|
||||
{{end}}
|
||||
</nav>{{end}}
|
||||
|
||||
{{if .Posts}}</section>{{else}}</div>{{end}}
|
||||
|
||||
{{if .ShowFooterBranding }}
|
||||
<footer>
|
||||
<hr />
|
||||
<nav dir="ltr">
|
||||
<a class="home pubd" href="/">{{.SiteName}}</a> · powered by <a style="margin-left:0" href="https://writefreely.org">write freely</a>
|
||||
</nav>
|
||||
</footer>
|
||||
{{ end }}
|
||||
</body>
|
||||
|
||||
{{if .CanShowScript}}
|
||||
{{range .ExternalScripts}}<script type="text/javascript" src="{{.}}" async></script>{{end}}
|
||||
{{if .Script}}<script type="text/javascript">{{.ScriptDisplay}}</script>{{end}}
|
||||
{{end}}
|
||||
<script src="/js/h.js"></script>
|
||||
<script src="/js/postactions.js"></script>
|
||||
<script type="text/javascript">
|
||||
var deleting = false;
|
||||
function delPost(e, id, owned) {
|
||||
e.preventDefault();
|
||||
if (deleting) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: UNDO!
|
||||
if (window.confirm('Are you sure you want to delete this post?')) {
|
||||
// AJAX
|
||||
deletePost(id, "", function() {
|
||||
// Remove post from list
|
||||
var $postEl = document.getElementById('post-' + id);
|
||||
$postEl.parentNode.removeChild($postEl);
|
||||
// TODO: add next post from this collection at the bottom
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var deletePost = function(postID, token, callback) {
|
||||
deleting = true;
|
||||
|
||||
var $delBtn = document.getElementById('post-' + postID).getElementsByClassName('delete action')[0];
|
||||
$delBtn.innerHTML = '...';
|
||||
|
||||
var http = new XMLHttpRequest();
|
||||
var url = "/api/posts/" + postID;
|
||||
http.open("DELETE", url, true);
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState == 4) {
|
||||
deleting = false;
|
||||
if (http.status == 204) {
|
||||
callback();
|
||||
} else if (http.status == 409) {
|
||||
$delBtn.innerHTML = 'delete';
|
||||
alert("Post is synced to another account. Delete the post from that account instead.");
|
||||
// TODO: show "remove" button instead of "delete" now
|
||||
// Persist that state.
|
||||
// Have it remove the post locally only.
|
||||
} else {
|
||||
$delBtn.innerHTML = 'delete';
|
||||
alert("Failed to delete." + (http.status>=500?" Please try again.":""));
|
||||
}
|
||||
}
|
||||
}
|
||||
http.send();
|
||||
};
|
||||
|
||||
var pinning = false;
|
||||
function pinPost(e, postID, slug, title) {
|
||||
e.preventDefault();
|
||||
if (pinning) {
|
||||
return;
|
||||
}
|
||||
pinning = true;
|
||||
|
||||
var callback = function() {
|
||||
// Visibly remove post from collection
|
||||
var $postEl = document.getElementById('post-' + postID);
|
||||
$postEl.parentNode.removeChild($postEl);
|
||||
var $header = document.getElementsByTagName('header')[0];
|
||||
var $pinnedNavs = $header.getElementsByTagName('nav');
|
||||
// Add link to nav
|
||||
var link = '<a class="pinned" href="/{{.Alias}}/'+slug+'">'+title+'</a>';
|
||||
if ($pinnedNavs.length == 0) {
|
||||
$header.insertAdjacentHTML("beforeend", '<nav>'+link+'</nav>');
|
||||
} else {
|
||||
$pinnedNavs[0].insertAdjacentHTML("beforeend", link);
|
||||
}
|
||||
};
|
||||
|
||||
var $pinBtn = document.getElementById('post-' + postID).getElementsByClassName('pin action')[0];
|
||||
$pinBtn.innerHTML = '...';
|
||||
|
||||
var http = new XMLHttpRequest();
|
||||
var url = "/api/collections/{{.Alias}}/pin";
|
||||
var params = [ { "id": postID } ];
|
||||
http.open("POST", url, true);
|
||||
http.setRequestHeader("Content-type", "application/json");
|
||||
http.onreadystatechange = function() {
|
||||
if (http.readyState == 4) {
|
||||
pinning = false;
|
||||
if (http.status == 200) {
|
||||
callback();
|
||||
} else if (http.status == 409) {
|
||||
$pinBtn.innerHTML = 'pin';
|
||||
alert("Post is synced to another account. Delete the post from that account instead.");
|
||||
// TODO: show "remove" button instead of "delete" now
|
||||
// Persist that state.
|
||||
// Have it remove the post locally only.
|
||||
} else {
|
||||
$pinBtn.innerHTML = 'pin';
|
||||
alert("Failed to pin." + (http.status>=500?" Please try again.":""));
|
||||
}
|
||||
}
|
||||
}
|
||||
http.send(JSON.stringify(params));
|
||||
};
|
||||
|
||||
try {
|
||||
WebFontConfig = {
|
||||
custom: { families: [ 'Lora:400,700:latin', 'Open+Sans:400,700:latin' ], urls: [ '/css/fonts.css' ] }
|
||||
};
|
||||
(function() {
|
||||
var wf = document.createElement('script');
|
||||
wf.src = '/js/webfont.js';
|
||||
wf.type = 'text/javascript';
|
||||
wf.async = 'true';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})();
|
||||
} catch (e) {}
|
||||
</script>
|
||||
</html>{{end}}
|
371
templates/edit-meta.tmpl
Normal file
371
templates/edit-meta.tmpl
Normal file
@@ -0,0 +1,371 @@
|
||||
{{define "edit-meta"}}<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<title>Edit metadata: {{if .Post.Title}}{{.Post.Title}}{{else}}{{.Post.Id}}{{end}} — {{.SiteName}}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/write.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style type="text/css">
|
||||
dt {
|
||||
width: 8em;
|
||||
}
|
||||
.error {
|
||||
display: none;
|
||||
}
|
||||
.mono {
|
||||
font-style: normal;
|
||||
}
|
||||
#set-now {
|
||||
font-style: italic;
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
.content-container h2 a {
|
||||
font-size: .6em;
|
||||
font-weight: normal;
|
||||
margin-left: 1em;
|
||||
}
|
||||
.content-container h2 a:link, .content-container h2 a:visited {
|
||||
color: blue;
|
||||
}
|
||||
.content-container h2 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body id="pad-sub" class="light">
|
||||
|
||||
<header id="tools">
|
||||
<div id="clip">
|
||||
<h1>{{if .User}}<a href="/me/posts/" style="font-weight:normal"><span style="font-size:1.2em;font-weight:bold;margin-right:0.5em">w</span></a>{{else}}<a href="/">w<span class="if-room">rite.as</span></a>{{end}}
|
||||
</h1>
|
||||
<nav id="target" class=""><ul>
|
||||
<li>{{if .EditCollection}}<a href="{{.EditCollection.CanonicalURL}}">{{.EditCollection.Title}}</a>{{else}}<a>Anonymous</a>{{end}}</li>
|
||||
</ul></nav>
|
||||
</div>
|
||||
<div id="belt">
|
||||
<div class="tool if-room"><a href="{{if .EditCollection}}{{.EditCollection.CanonicalURL}}{{.Post.Slug}}/edit{{else}}/{{.Post.Id}}/edit{{end}}" title="Edit post" id="edit"><img class="ic-24dp" src="/img/ic_edit_dark@2x.png" /></a></div>
|
||||
<div class="tool if-room room-2"><a href="#theme" title="Toggle theme" id="toggle-theme"><img class="ic-24dp" src="/img/ic_brightness_dark@2x.png" /></a></div>
|
||||
<div class="tool if-room room-1"><a href="{{if not .User}}/pad/posts{{else}}/me/posts/{{end}}" title="View posts" id="view-posts"><img class="ic-24dp" src="/img/ic_list_dark@2x.png" /></a></div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content-container tight">
|
||||
<form action="/api/{{if .EditCollection}}collections/{{.EditCollection.Alias}}/{{end}}posts/{{.Post.Id}}" method="post" onsubmit="return updateMeta()">
|
||||
<h2>Edit metadata: {{if .Post.Title}}{{.Post.Title}}{{else}}{{.Post.Id}}{{end}} <a href="/{{if .EditCollection}}{{.EditCollection.Alias}}/{{.Post.Slug}}{{else}}{{.Post.Id}}{{end}}">view post</a></h2>
|
||||
|
||||
{{if .Flashes}}<ul class="errors">
|
||||
{{range .Flashes}}<li class="urgent">{{.}}</li>{{end}}
|
||||
</ul>{{end}}
|
||||
|
||||
<dl class="dl-horizontal">
|
||||
{{if .EditCollection}}
|
||||
<dt><label for="slug">Slug</label></dt>
|
||||
<dd><input type="text" id="slug" name="slug" value="{{.Post.Slug}}" /></dd>
|
||||
{{end}}
|
||||
<dt><label for="lang">Language</label></dt>
|
||||
<dd>
|
||||
<select name="lang" id="lang" dir="auto">
|
||||
<option value=""></option>
|
||||
<option value="ab"{{if eq "ab" .Post.Language.String}} selected="selected"{{end}}>аҧсуа бызшәа, аҧсшәа</option>
|
||||
<option value="aa"{{if eq "aa" .Post.Language.String}} selected="selected"{{end}}>Afaraf</option>
|
||||
<option value="af"{{if eq "af" .Post.Language.String}} selected="selected"{{end}}>Afrikaans</option>
|
||||
<option value="ak"{{if eq "ak" .Post.Language.String}} selected="selected"{{end}}>Akan</option>
|
||||
<option value="sq"{{if eq "sq" .Post.Language.String}} selected="selected"{{end}}>Shqip</option>
|
||||
<option value="am"{{if eq "am" .Post.Language.String}} selected="selected"{{end}}>አማርኛ</option>
|
||||
<option dir="rtl" value="ar"{{if eq "ar" .Post.Language.String}} selected="selected"{{end}}>العربية</option>
|
||||
<option value="an"{{if eq "an" .Post.Language.String}} selected="selected"{{end}}>aragonés</option>
|
||||
<option value="hy"{{if eq "hy" .Post.Language.String}} selected="selected"{{end}}>Հայերեն</option>
|
||||
<option value="as"{{if eq "as" .Post.Language.String}} selected="selected"{{end}}>অসমীয়া</option>
|
||||
<option value="av"{{if eq "av" .Post.Language.String}} selected="selected"{{end}}>авар мацӀ, магӀарул мацӀ</option>
|
||||
<option value="ae"{{if eq "ae" .Post.Language.String}} selected="selected"{{end}}>avesta</option>
|
||||
<option value="ay"{{if eq "ay" .Post.Language.String}} selected="selected"{{end}}>aymar aru</option>
|
||||
<option value="az"{{if eq "az" .Post.Language.String}} selected="selected"{{end}}>azərbaycan dili</option>
|
||||
<option value="bm"{{if eq "bm" .Post.Language.String}} selected="selected"{{end}}>bamanankan</option>
|
||||
<option value="ba"{{if eq "ba" .Post.Language.String}} selected="selected"{{end}}>башҡорт теле</option>
|
||||
<option value="eu"{{if eq "eu" .Post.Language.String}} selected="selected"{{end}}>euskara, euskera</option>
|
||||
<option value="be"{{if eq "be" .Post.Language.String}} selected="selected"{{end}}>беларуская мова</option>
|
||||
<option value="bn"{{if eq "bn" .Post.Language.String}} selected="selected"{{end}}>বাংলা</option>
|
||||
<option value="bh"{{if eq "bh" .Post.Language.String}} selected="selected"{{end}}>भोजपुरी</option>
|
||||
<option value="bi"{{if eq "bi" .Post.Language.String}} selected="selected"{{end}}>Bislama</option>
|
||||
<option value="bs"{{if eq "bs" .Post.Language.String}} selected="selected"{{end}}>bosanski jezik</option>
|
||||
<option value="br"{{if eq "br" .Post.Language.String}} selected="selected"{{end}}>brezhoneg</option>
|
||||
<option value="bg"{{if eq "bg" .Post.Language.String}} selected="selected"{{end}}>български език</option>
|
||||
<option value="my"{{if eq "my" .Post.Language.String}} selected="selected"{{end}}>ဗမာစာ</option>
|
||||
<option value="ca"{{if eq "ca" .Post.Language.String}} selected="selected"{{end}}>català</option>
|
||||
<option value="ch"{{if eq "ch" .Post.Language.String}} selected="selected"{{end}}>Chamoru</option>
|
||||
<option value="ce"{{if eq "ce" .Post.Language.String}} selected="selected"{{end}}>нохчийн мотт</option>
|
||||
<option value="ny"{{if eq "ny" .Post.Language.String}} selected="selected"{{end}}>chiCheŵa, chinyanja</option>
|
||||
<option value="zh"{{if eq "zh" .Post.Language.String}} selected="selected"{{end}}>中文 (Zhōngwén), 汉语, 漢語</option>
|
||||
<option value="cv"{{if eq "cv" .Post.Language.String}} selected="selected"{{end}}>чӑваш чӗлхи</option>
|
||||
<option value="kw"{{if eq "kw" .Post.Language.String}} selected="selected"{{end}}>Kernewek</option>
|
||||
<option value="co"{{if eq "co" .Post.Language.String}} selected="selected"{{end}}>corsu, lingua corsa</option>
|
||||
<option value="cr"{{if eq "cr" .Post.Language.String}} selected="selected"{{end}}>ᓀᐦᐃᔭᐍᐏᐣ</option>
|
||||
<option value="hr"{{if eq "hr" .Post.Language.String}} selected="selected"{{end}}>hrvatski jezik</option>
|
||||
<option value="cs"{{if eq "cs" .Post.Language.String}} selected="selected"{{end}}>čeština, český jazyk</option>
|
||||
<option value="da"{{if eq "da" .Post.Language.String}} selected="selected"{{end}}>dansk</option>
|
||||
<option dir="rtl" value="dv"{{if eq "dv" .Post.Language.String}} selected="selected"{{end}}>ދިވެހި</option>
|
||||
<option value="nl"{{if eq "nl" .Post.Language.String}} selected="selected"{{end}}>Nederlands, Vlaams</option>
|
||||
<option value="dz"{{if eq "dz" .Post.Language.String}} selected="selected"{{end}}>རྫོང་ཁ</option>
|
||||
<option value="en"{{if eq "en" .Post.Language.String}} selected="selected"{{end}}>English</option>
|
||||
<option value="eo"{{if eq "eo" .Post.Language.String}} selected="selected"{{end}}>Esperanto</option>
|
||||
<option value="et"{{if eq "et" .Post.Language.String}} selected="selected"{{end}}>eesti, eesti keel</option>
|
||||
<option value="ee"{{if eq "ee" .Post.Language.String}} selected="selected"{{end}}>Eʋegbe</option>
|
||||
<option value="fo"{{if eq "fo" .Post.Language.String}} selected="selected"{{end}}>føroyskt</option>
|
||||
<option value="fj"{{if eq "fj" .Post.Language.String}} selected="selected"{{end}}>vosa Vakaviti</option>
|
||||
<option value="fi"{{if eq "fi" .Post.Language.String}} selected="selected"{{end}}>suomi, suomen kieli</option>
|
||||
<option value="fr"{{if eq "fr" .Post.Language.String}} selected="selected"{{end}}>français, langue française</option>
|
||||
<option value="ff"{{if eq "ff" .Post.Language.String}} selected="selected"{{end}}>Fulfulde, Pulaar, Pular</option>
|
||||
<option value="gl"{{if eq "gl" .Post.Language.String}} selected="selected"{{end}}>Galego</option>
|
||||
<option value="ka"{{if eq "ka" .Post.Language.String}} selected="selected"{{end}}>ქართული</option>
|
||||
<option value="de"{{if eq "de" .Post.Language.String}} selected="selected"{{end}}>Deutsch</option>
|
||||
<option value="el"{{if eq "el" .Post.Language.String}} selected="selected"{{end}}>ελληνικά</option>
|
||||
<option value="gn"{{if eq "gn" .Post.Language.String}} selected="selected"{{end}}>Avañe'ẽ</option>
|
||||
<option value="gu"{{if eq "gu" .Post.Language.String}} selected="selected"{{end}}>ગુજરાતી</option>
|
||||
<option value="ht"{{if eq "ht" .Post.Language.String}} selected="selected"{{end}}>Kreyòl ayisyen</option>
|
||||
<option dir="rtl" value="ha"{{if eq "ha" .Post.Language.String}} selected="selected"{{end}}>(Hausa) هَوُسَ</option>
|
||||
<option dir="rtl" value="he"{{if eq "he" .Post.Language.String}} selected="selected"{{end}}>עברית</option>
|
||||
<option value="hz"{{if eq "hz" .Post.Language.String}} selected="selected"{{end}}>Otjiherero</option>
|
||||
<option value="hi"{{if eq "hi" .Post.Language.String}} selected="selected"{{end}}>हिन्दी, हिंदी</option>
|
||||
<option value="ho"{{if eq "ho" .Post.Language.String}} selected="selected"{{end}}>Hiri Motu</option>
|
||||
<option value="hu"{{if eq "hu" .Post.Language.String}} selected="selected"{{end}}>magyar</option>
|
||||
<option value="ia"{{if eq "ia" .Post.Language.String}} selected="selected"{{end}}>Interlingua</option>
|
||||
<option value="id"{{if eq "id" .Post.Language.String}} selected="selected"{{end}}>Bahasa Indonesia</option>
|
||||
<option value="ie"{{if eq "ie" .Post.Language.String}} selected="selected"{{end}}>Interlingue</option>
|
||||
<option value="ga"{{if eq "ga" .Post.Language.String}} selected="selected"{{end}}>Gaeilge</option>
|
||||
<option value="ig"{{if eq "ig" .Post.Language.String}} selected="selected"{{end}}>Asụsụ Igbo</option>
|
||||
<option value="ik"{{if eq "ik" .Post.Language.String}} selected="selected"{{end}}>Iñupiaq, Iñupiatun</option>
|
||||
<option value="io"{{if eq "io" .Post.Language.String}} selected="selected"{{end}}>Ido</option>
|
||||
<option value="is"{{if eq "is" .Post.Language.String}} selected="selected"{{end}}>Íslenska</option>
|
||||
<option value="it"{{if eq "it" .Post.Language.String}} selected="selected"{{end}}>Italiano</option>
|
||||
<option value="iu"{{if eq "iu" .Post.Language.String}} selected="selected"{{end}}>ᐃᓄᒃᑎᑐᑦ</option>
|
||||
<option value="ja"{{if eq "ja" .Post.Language.String}} selected="selected"{{end}}>日本語 (にほんご)</option>
|
||||
<option value="jv"{{if eq "jv" .Post.Language.String}} selected="selected"{{end}}>ꦧꦱꦗꦮ, Basa Jawa</option>
|
||||
<option value="kl"{{if eq "kl" .Post.Language.String}} selected="selected"{{end}}>kalaallisut, kalaallit oqaasii</option>
|
||||
<option value="kn"{{if eq "kn" .Post.Language.String}} selected="selected"{{end}}>ಕನ್ನಡ</option>
|
||||
<option value="kr"{{if eq "kr" .Post.Language.String}} selected="selected"{{end}}>Kanuri</option>
|
||||
<option value="ks"{{if eq "ks" .Post.Language.String}} selected="selected"{{end}}>कश्मीरी, كشميري</option>
|
||||
<option value="kk"{{if eq "kk" .Post.Language.String}} selected="selected"{{end}}>қазақ тілі</option>
|
||||
<option value="km"{{if eq "km" .Post.Language.String}} selected="selected"{{end}}>ខ្មែរ, ខេមរភាសា, ភាសាខ្មែរ</option>
|
||||
<option value="ki"{{if eq "ki" .Post.Language.String}} selected="selected"{{end}}>Gĩkũyũ</option>
|
||||
<option value="rw"{{if eq "rw" .Post.Language.String}} selected="selected"{{end}}>Ikinyarwanda</option>
|
||||
<option value="ky"{{if eq "ky" .Post.Language.String}} selected="selected"{{end}}>Кыргызча, Кыргыз тили</option>
|
||||
<option value="kv"{{if eq "kv" .Post.Language.String}} selected="selected"{{end}}>коми кыв</option>
|
||||
<option value="kg"{{if eq "kg" .Post.Language.String}} selected="selected"{{end}}>Kikongo</option>
|
||||
<option value="ko"{{if eq "ko" .Post.Language.String}} selected="selected"{{end}}>한국어</option>
|
||||
<option value="ku"{{if eq "ku" .Post.Language.String}} selected="selected"{{end}}>Kurdî, كوردی</option>
|
||||
<option value="kj"{{if eq "kj" .Post.Language.String}} selected="selected"{{end}}>Kuanyama</option>
|
||||
<option value="la"{{if eq "la" .Post.Language.String}} selected="selected"{{end}}>latine, lingua latina</option>
|
||||
<option value="lb"{{if eq "lb" .Post.Language.String}} selected="selected"{{end}}>Lëtzebuergesch</option>
|
||||
<option value="lg"{{if eq "lg" .Post.Language.String}} selected="selected"{{end}}>Luganda</option>
|
||||
<option value="li"{{if eq "li" .Post.Language.String}} selected="selected"{{end}}>Limburgs</option>
|
||||
<option value="ln"{{if eq "ln" .Post.Language.String}} selected="selected"{{end}}>Lingála</option>
|
||||
<option value="lo"{{if eq "lo" .Post.Language.String}} selected="selected"{{end}}>ພາສາລາວ</option>
|
||||
<option value="lt"{{if eq "lt" .Post.Language.String}} selected="selected"{{end}}>lietuvių kalba</option>
|
||||
<option value="lu"{{if eq "lu" .Post.Language.String}} selected="selected"{{end}}>Kiluba</option>
|
||||
<option value="lv"{{if eq "lv" .Post.Language.String}} selected="selected"{{end}}>Latviešu Valoda</option>
|
||||
<option value="gv"{{if eq "gv" .Post.Language.String}} selected="selected"{{end}}>Gaelg, Gailck</option>
|
||||
<option value="mk"{{if eq "mk" .Post.Language.String}} selected="selected"{{end}}>македонски јазик</option>
|
||||
<option value="mg"{{if eq "mg" .Post.Language.String}} selected="selected"{{end}}>fiteny malagasy</option>
|
||||
<option value="ms"{{if eq "ms" .Post.Language.String}} selected="selected"{{end}}>Bahasa Melayu, بهاس ملايو</option>
|
||||
<option value="ml"{{if eq "ml" .Post.Language.String}} selected="selected"{{end}}>മലയാളം</option>
|
||||
<option value="mt"{{if eq "mt" .Post.Language.String}} selected="selected"{{end}}>Malti</option>
|
||||
<option value="mi"{{if eq "mi" .Post.Language.String}} selected="selected"{{end}}>te reo Māori</option>
|
||||
<option value="mr"{{if eq "mr" .Post.Language.String}} selected="selected"{{end}}>मराठी</option>
|
||||
<option value="mh"{{if eq "mh" .Post.Language.String}} selected="selected"{{end}}>Kajin M̧ajeļ</option>
|
||||
<option value="mn"{{if eq "mn" .Post.Language.String}} selected="selected"{{end}}>Монгол хэл</option>
|
||||
<option value="na"{{if eq "na" .Post.Language.String}} selected="selected"{{end}}>Dorerin Naoero</option>
|
||||
<option value="nv"{{if eq "nv" .Post.Language.String}} selected="selected"{{end}}>Diné bizaad</option>
|
||||
<option value="nd"{{if eq "nd" .Post.Language.String}} selected="selected"{{end}}>isiNdebele</option>
|
||||
<option value="ne"{{if eq "ne" .Post.Language.String}} selected="selected"{{end}}>नेपाली</option>
|
||||
<option value="ng"{{if eq "ng" .Post.Language.String}} selected="selected"{{end}}>Owambo</option>
|
||||
<option value="nb"{{if eq "nb" .Post.Language.String}} selected="selected"{{end}}>Norsk Bokmål</option>
|
||||
<option value="nn"{{if eq "nn" .Post.Language.String}} selected="selected"{{end}}>Norsk Nynorsk</option>
|
||||
<option value="no"{{if eq "no" .Post.Language.String}} selected="selected"{{end}}>Norsk</option>
|
||||
<option value="ii"{{if eq "ii" .Post.Language.String}} selected="selected"{{end}}>ꆈꌠ꒿ Nuosuhxop</option>
|
||||
<option value="nr"{{if eq "nr" .Post.Language.String}} selected="selected"{{end}}>isiNdebele</option>
|
||||
<option value="oc"{{if eq "oc" .Post.Language.String}} selected="selected"{{end}}>occitan, lenga d'òc</option>
|
||||
<option value="oj"{{if eq "oj" .Post.Language.String}} selected="selected"{{end}}>ᐊᓂᔑᓈᐯᒧᐎᓐ</option>
|
||||
<option value="cu"{{if eq "cu" .Post.Language.String}} selected="selected"{{end}}>ѩзыкъ словѣньскъ</option>
|
||||
<option value="om"{{if eq "om" .Post.Language.String}} selected="selected"{{end}}>Afaan Oromoo</option>
|
||||
<option value="or"{{if eq "or" .Post.Language.String}} selected="selected"{{end}}>ଓଡ଼ିଆ</option>
|
||||
<option value="os"{{if eq "os" .Post.Language.String}} selected="selected"{{end}}>ирон æвзаг</option>
|
||||
<option value="pa"{{if eq "pa" .Post.Language.String}} selected="selected"{{end}}>ਪੰਜਾਬੀ</option>
|
||||
<option value="pi"{{if eq "pi" .Post.Language.String}} selected="selected"{{end}}>पाऴि</option>
|
||||
<option dir="rtl" value="fa"{{if eq "fa" .Post.Language.String}} selected="selected"{{end}}>فارسی</option>
|
||||
<option value="pl"{{if eq "pl" .Post.Language.String}} selected="selected"{{end}}>Język Polski, Polszczyzna</option>
|
||||
<option dir="rtl" value="ps"{{if eq "ps" .Post.Language.String}} selected="selected"{{end}}>پښتو</option>
|
||||
<option value="pt"{{if eq "pt" .Post.Language.String}} selected="selected"{{end}}>Português</option>
|
||||
<option value="qu"{{if eq "qu" .Post.Language.String}} selected="selected"{{end}}>Runa Simi, Kichwa</option>
|
||||
<option value="rm"{{if eq "rm" .Post.Language.String}} selected="selected"{{end}}>Rumantsch Grischun</option>
|
||||
<option value="rn"{{if eq "rn" .Post.Language.String}} selected="selected"{{end}}>Ikirundi</option>
|
||||
<option value="ro"{{if eq "ro" .Post.Language.String}} selected="selected"{{end}}>Română</option>
|
||||
<option value="ru"{{if eq "ru" .Post.Language.String}} selected="selected"{{end}}>Русский</option>
|
||||
<option value="sa"{{if eq "sa" .Post.Language.String}} selected="selected"{{end}}>संस्कृतम्</option>
|
||||
<option value="sc"{{if eq "sc" .Post.Language.String}} selected="selected"{{end}}>sardu</option>
|
||||
<option value="sd"{{if eq "sd" .Post.Language.String}} selected="selected"{{end}}>सिन्धी, سنڌي، سندھی</option>
|
||||
<option value="se"{{if eq "se" .Post.Language.String}} selected="selected"{{end}}>Davvisámegiella</option>
|
||||
<option value="sm"{{if eq "sm" .Post.Language.String}} selected="selected"{{end}}>gagana fa'a Samoa</option>
|
||||
<option value="sg"{{if eq "sg" .Post.Language.String}} selected="selected"{{end}}>yângâ tî sängö</option>
|
||||
<option value="sr"{{if eq "sr" .Post.Language.String}} selected="selected"{{end}}>српски језик</option>
|
||||
<option value="gd"{{if eq "gd" .Post.Language.String}} selected="selected"{{end}}>Gàidhlig</option>
|
||||
<option value="sn"{{if eq "sn" .Post.Language.String}} selected="selected"{{end}}>chiShona</option>
|
||||
<option value="si"{{if eq "si" .Post.Language.String}} selected="selected"{{end}}>සිංහල</option>
|
||||
<option value="sk"{{if eq "sk" .Post.Language.String}} selected="selected"{{end}}>Slovenčina, Slovenský Jazyk</option>
|
||||
<option value="sl"{{if eq "sl" .Post.Language.String}} selected="selected"{{end}}>Slovenski Jezik, Slovenščina</option>
|
||||
<option value="so"{{if eq "so" .Post.Language.String}} selected="selected"{{end}}>Soomaaliga, af Soomaali</option>
|
||||
<option value="st"{{if eq "st" .Post.Language.String}} selected="selected"{{end}}>Sesotho</option>
|
||||
<option value="es"{{if eq "es" .Post.Language.String}} selected="selected"{{end}}>Español</option>
|
||||
<option value="su"{{if eq "su" .Post.Language.String}} selected="selected"{{end}}>Basa Sunda</option>
|
||||
<option value="sw"{{if eq "sw" .Post.Language.String}} selected="selected"{{end}}>Kiswahili</option>
|
||||
<option value="ss"{{if eq "ss" .Post.Language.String}} selected="selected"{{end}}>SiSwati</option>
|
||||
<option value="sv"{{if eq "sv" .Post.Language.String}} selected="selected"{{end}}>Svenska</option>
|
||||
<option value="ta"{{if eq "ta" .Post.Language.String}} selected="selected"{{end}}>தமிழ்</option>
|
||||
<option value="te"{{if eq "te" .Post.Language.String}} selected="selected"{{end}}>తెలుగు</option>
|
||||
<option value="tg"{{if eq "tg" .Post.Language.String}} selected="selected"{{end}}>тоҷикӣ, toçikī, تاجیکی</option>
|
||||
<option value="th"{{if eq "th" .Post.Language.String}} selected="selected"{{end}}>ไทย</option>
|
||||
<option value="ti"{{if eq "ti" .Post.Language.String}} selected="selected"{{end}}>ትግርኛ</option>
|
||||
<option value="bo"{{if eq "bo" .Post.Language.String}} selected="selected"{{end}}>བོད་ཡིག</option>
|
||||
<option value="tk"{{if eq "tk" .Post.Language.String}} selected="selected"{{end}}>Türkmen, Түркмен</option>
|
||||
<option value="tl"{{if eq "tl" .Post.Language.String}} selected="selected"{{end}}>Wikang Tagalog</option>
|
||||
<option value="tn"{{if eq "tn" .Post.Language.String}} selected="selected"{{end}}>Setswana</option>
|
||||
<option value="to"{{if eq "to" .Post.Language.String}} selected="selected"{{end}}>Faka Tonga</option>
|
||||
<option value="tr"{{if eq "tr" .Post.Language.String}} selected="selected"{{end}}>Türkçe</option>
|
||||
<option value="ts"{{if eq "ts" .Post.Language.String}} selected="selected"{{end}}>Xitsonga</option>
|
||||
<option value="tt"{{if eq "tt" .Post.Language.String}} selected="selected"{{end}}>татар теле, tatar tele</option>
|
||||
<option value="tw"{{if eq "tw" .Post.Language.String}} selected="selected"{{end}}>Twi</option>
|
||||
<option value="ty"{{if eq "ty" .Post.Language.String}} selected="selected"{{end}}>Reo Tahiti</option>
|
||||
<option value="ug"{{if eq "ug" .Post.Language.String}} selected="selected"{{end}}>ئۇيغۇرچە, Uyghurche</option>
|
||||
<option value="uk"{{if eq "uk" .Post.Language.String}} selected="selected"{{end}}>Українська</option>
|
||||
<option dir="rtl" value="ur"{{if eq "ur" .Post.Language.String}} selected="selected"{{end}}>اردو</option>
|
||||
<option value="uz"{{if eq "uz" .Post.Language.String}} selected="selected"{{end}}>Oʻzbek, Ўзбек, أۇزبېك</option>
|
||||
<option value="ve"{{if eq "ve" .Post.Language.String}} selected="selected"{{end}}>Tshivenḓa</option>
|
||||
<option value="vi"{{if eq "vi" .Post.Language.String}} selected="selected"{{end}}>Tiếng Việt</option>
|
||||
<option value="vo"{{if eq "vo" .Post.Language.String}} selected="selected"{{end}}>Volapük</option>
|
||||
<option value="wa"{{if eq "wa" .Post.Language.String}} selected="selected"{{end}}>Walon</option>
|
||||
<option value="cy"{{if eq "cy" .Post.Language.String}} selected="selected"{{end}}>Cymraeg</option>
|
||||
<option value="wo"{{if eq "wo" .Post.Language.String}} selected="selected"{{end}}>Wollof</option>
|
||||
<option value="fy"{{if eq "fy" .Post.Language.String}} selected="selected"{{end}}>Frysk</option>
|
||||
<option value="xh"{{if eq "xh" .Post.Language.String}} selected="selected"{{end}}>isiXhosa</option>
|
||||
<option dir="rtl" value="yi"{{if eq "yi" .Post.Language.String}} selected="selected"{{end}}>ייִדיש</option>
|
||||
<option value="yo"{{if eq "yo" .Post.Language.String}} selected="selected"{{end}}>Yorùbá</option>
|
||||
<option value="za"{{if eq "za" .Post.Language.String}} selected="selected"{{end}}>Saɯ cueŋƅ, Saw cuengh</option>
|
||||
<option value="zu"{{if eq "zu" .Post.Language.String}} selected="selected"{{end}}>isiZulu</option>
|
||||
</select>
|
||||
</dd>
|
||||
<dt><label for="rtl">Direction</label></dt>
|
||||
<dd><input type="checkbox" id="rtl" name="rtl" {{if .Post.IsRTL.Bool}}checked="checked"{{end}} /><label for="rtl"> right-to-left</label></dd>
|
||||
<dt><label for="created">Created</label></dt>
|
||||
<dd>
|
||||
<input type="text" id="created" name="created" value="{{.Post.UserFacingCreated}}" data-time="{{.Post.Created8601}}" placeholder="YYYY-MM-DD HH:MM:SS" maxlength="19" /> <span id="tz">UTC</span> <a href="#" id="set-now">now</a>
|
||||
<p class="error" id="create-error">Date format should be: <span class="mono"><abbr title="The full year">YYYY</abbr>-<abbr title="The numeric month of the year, where January = 1, with a zero in front if less than 10">MM</abbr>-<abbr title="The day of the month, with a zero in front if less than 10">DD</abbr> <abbr title="The hour (00-23), with a zero in front if less than 10.">HH</abbr>:<abbr title="The minute of the hour (00-59), with a zero in front if less than 10.">MM</abbr>:<abbr title="The seconds (00-59), with a zero in front if less than 10.">SS</abbr></span></p>
|
||||
</dd>
|
||||
<dt> </dt><dd><input type="submit" value="Save changes" /></dd>
|
||||
</dl>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script src="/js/h.js"></script>
|
||||
<script>
|
||||
function updateMeta() {
|
||||
document.getElementById('create-error').style.display = 'none';
|
||||
var $created = document.getElementById('created');
|
||||
var dateStr = $created.value.trim();
|
||||
var m = dateStr.match(/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}( [0-9]{1,2}:[0-9]{1,2}(:[0-9]{1,2})?)?$/);
|
||||
if (!m) {
|
||||
document.getElementById('create-error').style.display = 'block';
|
||||
return false;
|
||||
}
|
||||
// Break up the date and parse. This ensures cross-browser compatibility
|
||||
var p = dateStr.split(/[^0-9]/);
|
||||
var d = new Date(p[0], p[1]-1, p[2], p[3] ? p[3] : 0, p[4] ? p[4] : 0, p[5] ? p[5] : 0);
|
||||
$created.value = d.getUTCFullYear() + '-' + ('0' + (d.getUTCMonth()+1)).slice(-2) + '-' + ('0' + d.getUTCDate()).slice(-2)+' '+('0'+d.getUTCHours()).slice(-2)+':'+('0'+d.getUTCMinutes()).slice(-2)+':'+('0'+d.getUTCSeconds()).slice(-2);
|
||||
var $tz = document.getElementById('tz');
|
||||
$tz.style.display = "inline";
|
||||
var $submit = document.querySelector('input[type=submit]');
|
||||
$submit.value = "Saving...";
|
||||
$submit.disabled = true;
|
||||
return true;
|
||||
}
|
||||
function dateToStr(d) {
|
||||
return d.getFullYear() + '-' + ('0' + (d.getMonth()+1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2)+' '+('0'+d.getHours()).slice(-2)+':'+('0'+d.getMinutes()).slice(-2)+':'+('0'+d.getSeconds()).slice(-2);
|
||||
}
|
||||
function setLocalTime() {
|
||||
var $created = document.getElementById('created');
|
||||
var d = new Date($created.getAttribute('data-time'));
|
||||
$created.value = dateToStr(d);
|
||||
var $tz = document.getElementById('tz');
|
||||
$tz.style.display = "none";
|
||||
}
|
||||
setLocalTime();
|
||||
function setToNow() {
|
||||
var $created = document.getElementById('created');
|
||||
$created.value = dateToStr(new Date());
|
||||
}
|
||||
H.getEl('set-now').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
setToNow();
|
||||
});
|
||||
function toggleTheme() {
|
||||
var btns = Array.prototype.slice.call(document.getElementById('tools').querySelectorAll('a img'));
|
||||
if (document.body.className == 'light') {
|
||||
document.body.className = 'dark';
|
||||
for (var i=0; i<btns.length; i++) {
|
||||
btns[i].src = btns[i].src.replace('_dark@2x.png', '@2x.png');
|
||||
}
|
||||
} else {
|
||||
document.body.className = 'light';
|
||||
for (var i=0; i<btns.length; i++) {
|
||||
btns[i].src = btns[i].src.replace('@2x.png', '_dark@2x.png');
|
||||
}
|
||||
}
|
||||
H.set('padTheme', document.body.className);
|
||||
}
|
||||
if (H.get('padTheme', 'light') != 'light') {
|
||||
toggleTheme();
|
||||
}
|
||||
|
||||
var setButtonStates = function() {
|
||||
if (!canPublish) {
|
||||
$btnPublish.el.className = 'disabled';
|
||||
return;
|
||||
}
|
||||
if ($writer.el.value.length === 0 || (draftDoc != 'lastDoc' && $writer.el.value == origDoc)) {
|
||||
$btnPublish.el.className = 'disabled';
|
||||
} else {
|
||||
$btnPublish.el.className = '';
|
||||
}
|
||||
};
|
||||
|
||||
H.getEl('toggle-theme').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
try {
|
||||
var newTheme = 'light';
|
||||
if (document.body.className == 'light') {
|
||||
newTheme = 'dark';
|
||||
}
|
||||
} catch(e) {}
|
||||
toggleTheme();
|
||||
});
|
||||
|
||||
WebFontConfig = {
|
||||
custom: { families: [ 'Lora:400,700:latin' ], urls: [ '/css/fonts.css' ] }
|
||||
};
|
||||
try {
|
||||
(function() {
|
||||
var wf=document.createElement('script');
|
||||
wf.src = '/js/webfont.js';
|
||||
wf.type='text/javascript';
|
||||
wf.async='true';
|
||||
var s=document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})();
|
||||
} catch (e) {
|
||||
// whatevs
|
||||
}
|
||||
</script>
|
||||
<noscript><p><img src="https://analytics.write.as/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
|
||||
<link href="/css/icons.css" rel="stylesheet">
|
||||
</body>
|
||||
</html>{{end}}
|
25
templates/include/footer.tmpl
Normal file
25
templates/include/footer.tmpl
Normal file
@@ -0,0 +1,25 @@
|
||||
{{define "footer"}}
|
||||
<footer class="contain-me">
|
||||
<hr />
|
||||
<div class="marketing-section">
|
||||
<div class="clearfix blurbs">
|
||||
<div class="half">
|
||||
<h3><a class="home" href="/">{{.SiteName}}</a></h3>
|
||||
<ul>
|
||||
<li><a href="/about">about</a></li>
|
||||
<li><a href="/privacy">privacy</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="half">
|
||||
<h3><a href="https://writefreely.org">write freely</a></h3>
|
||||
<ul>
|
||||
<li><a href="https://writefreely.org/apps">apps</a></li>
|
||||
<li><a href="https://developers.write.as/" title="Build on Write Freely with our open developer API.">developers</a></li>
|
||||
<li><a href="https://github.com/writeas/writefreely">source code</a></li>
|
||||
<li style="margin-top:0.8em">{{.Version}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
{{end}}
|
53
templates/include/posts.tmpl
Normal file
53
templates/include/posts.tmpl
Normal file
@@ -0,0 +1,53 @@
|
||||
{{ define "posts" }}
|
||||
{{ range $el := .Posts }}<article id="post-{{.ID}}" class="{{.Font}} h-entry" itemscope itemtype="http://schema.org/BlogPosting">
|
||||
{{if .IsScheduled}}<p class="badge">Scheduled</p>{{end}}
|
||||
{{if .Title.String}}<h2 class="post-title" itemprop="name" class="p-name">{{if .HasTitleLink}}{{.HTMLTitle}} <a class="user hidden action" href="{{if $.IsOwner}}/{{$.Alias}}/{{.Slug.String}}{{else}}{{$.CanonicalURL}}{{.Slug.String}}{{end}}">view</a>{{else}}<a href="{{if $.IsOwner}}/{{$.Alias}}/{{.Slug.String}}{{else}}{{$.CanonicalURL}}{{.Slug.String}}{{end}}" itemprop="url" class="u-url">{{.HTMLTitle}}</a>{{end}}
|
||||
{{if $.IsOwner}}
|
||||
<a class="user hidden action" href="/{{$.Alias}}/{{.Slug.String}}/edit">edit</a>
|
||||
{{if $.CanPin}}<a class="user hidden pin action" href="/{{$.Alias}}/{{.Slug.String}}/pin" onclick="pinPost(event, '{{.ID}}', '{{.Slug.String}}', '{{.PlainDisplayTitle}}')">pin</a>{{end}}
|
||||
<a class="user hidden delete action" onclick="delPost(event, '{{.ID}}')" href="/{{$.Alias}}/{{.Slug.String}}/delete">delete</a>
|
||||
{{if gt (len $.Collections) 1}}<div class="user hidden action flat-select">
|
||||
<select id="move-{{.ID}}" onchange="postActions.multiMove(this, '{{.ID}}')" title="Move this post to another blog">
|
||||
<option style="display:none"></option>
|
||||
<option value="|anonymous|" style="font-style:italic">Draft</option>
|
||||
{{range $.Collections}}{{if ne .Alias $.Alias}}<option value="{{.Alias}}">{{.DisplayTitle}}</option>{{end}}{{end}}
|
||||
</select>
|
||||
<label for="move-{{.ID}}">move to...</label>
|
||||
<img class="ic-18dp" src="/img/ic_down_arrow_dark@2x.png" />
|
||||
</div>{{else}}
|
||||
{{range $.Collections}}
|
||||
<a class="user hidden action" href="/{{$el.ID}}" title="Change to a draft" onclick="postActions.move(this, '{{$el.ID}}', '|anonymous|');return false">change to <em>draft</em></a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</h2>
|
||||
{{if $.Format.ShowDates}}<time class="dt-published" datetime="{{.Created}}" pubdate itemprop="datePublished" content="{{.Created}}">{{if not .Title.String}}<a href="{{$.CanonicalURL}}{{.Slug.String}}" itemprop="url">{{end}}{{.DisplayDate}}{{if not .Title.String}}</a>{{end}}</time>{{end}}
|
||||
{{else}}
|
||||
<h2 class="post-title" itemprop="name">
|
||||
{{if $.Format.ShowDates}}<time class="dt-published" datetime="{{.Created}}" pubdate itemprop="datePublished" content="{{.Created}}"><a href="{{if $.IsOwner}}/{{$.Alias}}/{{.Slug.String}}{{else}}{{$.CanonicalURL}}{{.Slug.String}}{{end}}" itemprop="url" class="u-url">{{.DisplayDate}}</a></time>{{end}}
|
||||
{{if $.IsOwner}}
|
||||
{{if not $.Format.ShowDates}}<a class="user hidden action" href="{{if $.IsOwner}}/{{$.Alias}}/{{.Slug.String}}{{else}}{{$.CanonicalURL}}{{.Slug.String}}{{end}}">view</a>{{end}}
|
||||
<a class="user hidden action" href="/{{$.Alias}}/{{.Slug.String}}/edit">edit</a>
|
||||
{{if $.CanPin}}<a class="user hidden pin action" href="/{{$.Alias}}/{{.Slug.String}}/pin" onclick="pinPost(event, '{{.ID}}', '{{.Slug.String}}', '{{.PlainDisplayTitle}}')">pin</a>{{end}}
|
||||
<a class="user hidden delete action" onclick="delPost(event, '{{.ID}}')" href="/{{$.Alias}}/{{.Slug.String}}/delete">delete</a>
|
||||
{{if gt (len $.Collections) 1}}<div class="user hidden action flat-select">
|
||||
<select id="move-{{.ID}}" onchange="postActions.multiMove(this, '{{.ID}}')" title="Move this post to another blog">
|
||||
<option style="display:none"></option>
|
||||
<option value="|anonymous|" style="font-style:italic">Draft</option>
|
||||
{{range $.Collections}}{{if ne .Alias $.Alias}}<option value="{{.Alias}}">{{.DisplayTitle}}</option>{{end}}{{end}}
|
||||
</select>
|
||||
<label for="move-{{.ID}}">move to...</label>
|
||||
<img class="ic-18dp" src="/img/ic_down_arrow_dark@2x.png" />
|
||||
</div>{{else}}
|
||||
{{range $.Collections}}
|
||||
<a class="user hidden action" href="/{{$el.ID}}" title="Change to a draft" onclick="postActions.move(this, '{{$el.ID}}', '|anonymous|');return false">change to <em>draft</em></a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</h2>
|
||||
{{end}}
|
||||
|
||||
{{if .Excerpt}}<div {{if .Language}}lang="{{.Language.String}}"{{end}} dir="{{.Direction}}" class="book p-summary">{{if and (and (not $.IsOwner) (not $.Format.ShowDates)) (not .Title.String)}}<a class="hidden action" href="{{if $.IsOwner}}/{{$.Alias}}/{{.Slug.String}}{{else}}{{$.CanonicalURL}}{{.Slug.String}}{{end}}">view</a>{{end}}{{.Excerpt}}</div>
|
||||
|
||||
<a class="read-more" href="{{$.CanonicalURL}}{{.Slug.String}}">{{localstr "Read more..." .Language.String}}</a>{{else}}<div {{if .Language}}lang="{{.Language.String}}"{{end}} dir="{{.Direction}}" class="book e-content">{{if and (and (not $.IsOwner) (not $.Format.ShowDates)) (not .Title.String)}}<a class="hidden action" href="{{if $.IsOwner}}/{{$.Alias}}/{{.Slug.String}}{{else}}{{$.CanonicalURL}}{{.Slug.String}}{{end}}">view</a>{{end}}{{.HTMLContent}}</div>{{end}}</article>{{ end }}
|
||||
{{ end }}
|
75
templates/password-collection.tmpl
Normal file
75
templates/password-collection.tmpl
Normal file
@@ -0,0 +1,75 @@
|
||||
{{define "password-collection"}}<!DOCTYPE HTML>
|
||||
<html {{if .Language}}lang="{{.Language}}"{{end}} dir="{{.Direction}}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>{{.DisplayTitle}}{{if not .SingleUser}} — {{.SiteName}}{{end}}</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/css/write.css" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<link rel="canonical" href="{{.CanonicalURL}}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<meta name="description" content="{{.Description}}">
|
||||
<meta itemprop="name" content="{{.DisplayTitle}}">
|
||||
<meta itemprop="description" content="{{.Description}}">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="{{.DisplayTitle}}">
|
||||
<meta name="twitter:description" content="{{.Description}}">
|
||||
<meta property="og:title" content="{{.DisplayTitle}}" />
|
||||
<meta property="og:site_name" content="{{.DisplayTitle}}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="{{.CanonicalURL}}" />
|
||||
<meta property="og:description" content="{{.Description}}" />
|
||||
{{if .StyleSheet}}<style type="text/css">{{.StyleSheetDisplay}}</style>{{end}}
|
||||
|
||||
</head>
|
||||
<body id="collection" itemscope itemtype="http://schema.org/WebPage">
|
||||
<header>
|
||||
<h1 dir="{{.Direction}}" id="blog-title"><a href="/{{.Alias}}/" class="h-card p-author u-url" rel="me author">{{.DisplayTitle}}</a></h1>
|
||||
</header>
|
||||
|
||||
<div id="wrapper">
|
||||
|
||||
<div class="access">
|
||||
<form method="post" action="/api/auth/read">
|
||||
{{if .Flashes}}<ul class="errors">
|
||||
{{range .Flashes}}<li class="urgent">{{.}}</li>{{end}}
|
||||
</ul>{{else}}
|
||||
<h2>This blog requires a password.</h2>
|
||||
{{end}}
|
||||
<input type="hidden" name="alias" value="{{.Alias}}" />
|
||||
<input type="hidden" name="to" value="{{.Next}}" />
|
||||
<input type="password" autocomplete="new-password" name="password" tabindex="1" autofocus />
|
||||
<p><input type="submit" value="Enter" /></p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<hr />
|
||||
<nav dir="ltr">
|
||||
<a class="home pubd" href="/">{{.SiteName}}</a> · powered by <a style="margin-left:0" href="https://writefreely.org">write freely</a>
|
||||
</nav>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
{{if and .Script .CanShowScript}}<script type="text/javascript">{{.ScriptDisplay}}</script>{{end}}
|
||||
<script src="/js/h.js"></script>
|
||||
<script src="/js/postactions.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
WebFontConfig = {
|
||||
custom: { families: [ 'Lora:400,700:latin', 'Open+Sans:400,700:latin' ], urls: [ '/css/fonts.css' ] }
|
||||
};
|
||||
(function() {
|
||||
var wf = document.createElement('script');
|
||||
wf.src = '/js/webfont.js';
|
||||
wf.type = 'text/javascript';
|
||||
wf.async = 'true';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})();
|
||||
} catch (e) {}
|
||||
</script>
|
||||
</html>{{end}}
|
97
templates/post.tmpl
Normal file
97
templates/post.tmpl
Normal file
@@ -0,0 +1,97 @@
|
||||
{{define "post"}}<!DOCTYPE HTML>
|
||||
<html {{if .Language}}lang="{{.Language}}"{{end}} dir="{{.Direction}}">
|
||||
<head prefix="og: http://ogp.me/ns#">
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>{{if .Title}}{{.Title}}{{else}}{{.GenTitle}}{{end}} — {{.SiteName}}</title>
|
||||
|
||||
{{if .IsCode}}
|
||||
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/mono-blue.min.css">
|
||||
{{end}}
|
||||
<link rel="stylesheet" type="text/css" href="/css/write.css" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" />
|
||||
<link rel="canonical" href="{{.Host}}/{{.ID}}" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<meta name="generator" content="{{.SiteName}}">
|
||||
<meta name="title" content="{{if .Title}}{{.Title}}{{else}}{{.GenTitle}}{{end}}">
|
||||
<meta name="description" content="{{.Description}}">
|
||||
<meta itemprop="name" content="{{.SiteName}}">
|
||||
<meta itemprop="description" content="{{.Description}}">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:title" content="{{if .Title}}{{.Title}}{{else}}{{.GenTitle}}{{end}}">
|
||||
<meta name="twitter:description" content="{{.Description}}">
|
||||
{{if gt .Views 1}}<meta name="twitter:label1" value="Views">
|
||||
<meta name="twitter:data1" value="{{largeNumFmt .Views}}">{{end}}
|
||||
<meta name="twitter:image" content="https://write.as/img/w-sq-light.png">
|
||||
<meta property="og:title" content="{{if .Title}}{{.Title}}{{else}}{{.GenTitle}}{{end}}" />
|
||||
<meta property="og:site_name" content="{{.SiteName}}" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:url" content="https://write.as/{{.ID}}" />
|
||||
<meta property="og:description" content="{{.Description}}" />
|
||||
<meta property="og:image" content="https://write.as/img/w-sq-light.png">
|
||||
{{if .Author}}<meta property="article:author" content="https://{{.Author}}" />{{end}}
|
||||
|
||||
</head>
|
||||
<body id="post">
|
||||
|
||||
<header>
|
||||
<h1 dir="{{.Direction}}"><a href="/">{{.SiteName}}</a></h1>
|
||||
<nav>
|
||||
<span class="views{{if not .IsOwner}} owner-visible{{end}}" dir="ltr"><strong>{{largeNumFmt .Views}}</strong> {{pluralize "view" "views" .Views}}</span>
|
||||
{{if .IsCode}}<a href="/{{.ID}}.txt" rel="noindex" dir="{{.Direction}}">View raw</a>{{end}}
|
||||
{{ if .Username }}
|
||||
{{if .IsOwner}}
|
||||
<a href="/{{.ID}}/edit" dir="{{.Direction}}">Edit</a>
|
||||
{{end}}
|
||||
<a class="xtra-feature dash-nav" href="/me/posts/" dir="{{.Direction}}">Drafts</a>
|
||||
{{ end }}
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<article class="{{.Font}} h-entry">{{if .Title}}<h2 id="title" class="p-name">{{.Title}}</h2>{{end}}{{ if .IsPlainText }}<p id="post-body" class="e-content">{{.Content}}</p>{{ else }}<div id="post-body" class="e-content">{{.HTMLContent}}</div>{{ end }}</article>
|
||||
|
||||
<footer dir="ltr"><hr><nav><p style="font-size: 0.9em">{{localhtml "published with write.as" .Language}}</p></nav></footer>
|
||||
</body>
|
||||
|
||||
{{if .IsCode}}
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/highlight.min.js"></script>
|
||||
<script>
|
||||
hljs.highlightBlock(document.getElementById('post-body'));
|
||||
</script>
|
||||
{{else}}
|
||||
<script src="/js/h.js"></script>
|
||||
{{if .IsPlainText}}<script src="/js/twitter-text.min.js"></script>{{end}}
|
||||
{{end}}
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
WebFontConfig = {
|
||||
custom: { families: [ 'Lora:400,700:latin'{{if eq .Font "sans"}}, 'Open+Sans:400,700:latin'{{end}} ], urls: [ '/css/fonts.css' ] }
|
||||
};
|
||||
(function() {
|
||||
var wf = document.createElement('script');
|
||||
wf.src = '/js/webfont.js';
|
||||
wf.type = 'text/javascript';
|
||||
wf.async = 'true';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(wf, s);
|
||||
})();
|
||||
} catch (e) { /* ¯\_(ツ)_/¯ */ }
|
||||
|
||||
var posts = localStorage.getItem('posts');
|
||||
if (posts != null) {
|
||||
posts = JSON.parse(posts);
|
||||
var $nav = document.getElementsByTagName('nav')[0];
|
||||
for (var i=0; i<posts.length; i++) {
|
||||
if (posts[i].id == "{{.ID}}") {
|
||||
$nav.innerHTML = $nav.innerHTML + '<a class="xtra-feature" href="/edit/{{.ID}}" dir="{{.Direction}}">Edit</a>';
|
||||
var $ownerVis = document.querySelectorAll('.owner-visible');
|
||||
for (var i=0; i<$ownerVis.length; i++) {
|
||||
$ownerVis[i].classList.remove('owner-visible');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</html>{{end}}
|
Reference in New Issue
Block a user