A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 

261 rinda
10 KiB

  1. {{define "collection"}}<!DOCTYPE HTML>
  2. <html {{if .Language}}lang="{{.Language}}"{{end}} dir="{{.Direction}}">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>{{.DisplayTitle}}{{if not .SingleUser}} &mdash; {{.SiteName}}{{end}}</title>
  6. <link rel="stylesheet" type="text/css" href="/css/write.css" />
  7. {{if .CustomCSS}}<link rel="stylesheet" type="text/css" href="/local/custom.css" />{{end}}
  8. <link rel="shortcut icon" href="/favicon.ico" />
  9. <link rel="canonical" href="{{.CanonicalURL}}">
  10. {{if gt .CurrentPage 1}}<link rel="prev" href="{{.PrevPageURL .Prefix .CurrentPage .IsTopLevel}}">{{end}}
  11. {{if lt .CurrentPage .TotalPages}}<link rel="next" href="{{.NextPageURL .Prefix .CurrentPage .IsTopLevel}}">{{end}}
  12. {{if not .IsPrivate}}<link rel="alternate" type="application/rss+xml" title="{{.DisplayTitle}} &raquo; Feed" href="{{.CanonicalURL}}feed/" />{{end}}
  13. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  14. <meta name="generator" content="WriteFreely">
  15. <meta name="description" content="{{.PlainDescription}}">
  16. <meta itemprop="name" content="{{.DisplayTitle}}">
  17. <meta itemprop="description" content="{{.PlainDescription}}">
  18. <meta name="twitter:card" content="summary">
  19. <meta name="twitter:title" content="{{.DisplayTitle}}">
  20. <meta name="twitter:image" content="{{.AvatarURL}}">
  21. <meta name="twitter:description" content="{{.PlainDescription}}">
  22. <meta property="og:title" content="{{.DisplayTitle}}" />
  23. <meta property="og:site_name" content="{{.DisplayTitle}}" />
  24. <meta property="og:type" content="article" />
  25. <meta property="og:url" content="{{.CanonicalURL}}" />
  26. <meta property="og:description" content="{{.PlainDescription}}" />
  27. <meta property="og:image" content="{{.AvatarURL}}">
  28. {{template "collection-meta" .}}
  29. {{if .StyleSheet}}<style type="text/css">{{.StyleSheetDisplay}}</style>{{end}}
  30. {{if .RenderMathJax}}
  31. <!-- Add mathjax logic -->
  32. {{template "mathjax" .}}
  33. {{end}}
  34. <!-- Add highlighting logic -->
  35. {{template "highlighting" . }}
  36. </head>
  37. <body id="collection" itemscope itemtype="http://schema.org/WebPage">
  38. {{if or .IsOwner .SingleUser}}
  39. <nav id="manage"><ul>
  40. <li class="has-submenu"><a onclick="void(0)">&#9776; Menu</a>
  41. <ul>
  42. {{ if .IsOwner }}
  43. {{if .SingleUser}}
  44. <li><a href="/me/new">New Post</a></li>
  45. {{else}}
  46. <li><a href="/#{{.Alias}}" class="write">{{.SiteName}}</a></li>
  47. {{end}}
  48. {{if .SimpleNav}}<li><a href="/new#{{.Alias}}">New Post</a></li>{{end}}
  49. <li><a href="/me/c/{{.Alias}}">Customize</a></li>
  50. <li><a href="/me/c/{{.Alias}}/stats">Stats</a></li>
  51. <li class="separator"><hr /></li>
  52. {{if not .SingleUser}}<li><a href="/me/c/"><img class="ic-18dp" src="/img/ic_blogs_dark@2x.png" /> View Blogs</a></li>{{end}}
  53. <li><a href="/me/posts/"><img class="ic-18dp" src="/img/ic_list_dark@2x.png" /> View Drafts</a></li>
  54. {{ else }}
  55. <li><a href="/login">Log in{{if .IsProtected}} to {{.DisplayTitle}}{{end}}</a></li>
  56. {{if .IsProtected}}
  57. <li class="separator"><hr /></li>
  58. <li><a href="/logout">Log out</a></li>
  59. {{end}}
  60. {{ end }}
  61. </ul>
  62. </li>
  63. </ul></nav>
  64. {{else if .IsCollLoggedIn}}
  65. <nav id="manage" class="shiny"><ul>
  66. <li class="has-submenu"><a onclick="void(0)">&#9776; Menu</a>
  67. <ul>
  68. <li class="menu-heading" style="padding: .5rem .75rem; box-sizing: border-box;">{{.DisplayTitle}}</li>
  69. <li><a href="{{.CanonicalURL}}logout">Log out</a></li>
  70. </ul>
  71. </li>
  72. </ul></nav>
  73. {{end}}
  74. <header>
  75. {{if .Silenced}}
  76. {{template "user-silenced"}}
  77. {{end}}
  78. <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>
  79. {{if .Description}}<p class="description p-note">{{.DisplayDescription}}</p>{{end}}
  80. {{/*if not .Public/*}}
  81. <!--p class="meta-note"><span>Private collection</span>. Only you can see this page.</p-->
  82. {{/*end*/}}
  83. {{if .PinnedPosts}}<nav>
  84. {{range .PinnedPosts}}<a class="pinned" href="{{if not $.SingleUser}}/{{$.Alias}}/{{.Slug.String}}{{else}}{{.CanonicalURL $.Host}}{{end}}">{{.PlainDisplayTitle}}</a>{{end}}</nav>
  85. {{end}}
  86. </header>
  87. {{if .Posts}}<section id="wrapper" itemscope itemtype="http://schema.org/Blog">{{else}}<div id="wrapper">{{end}}
  88. {{if .IsWelcome}}
  89. <div id="welcome">
  90. <h2>Welcome, <strong>{{.Username}}</strong>!</h2>
  91. <p>This is your new blog.</p>
  92. <p><a class="simple-cta" href="/#{{.Alias}}">Start writing</a>, or <a class="simple-cta" href="/me/c/{{.Alias}}">customize</a> your blog.</p>
  93. <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>
  94. </div>
  95. {{end}}
  96. {{if .Flash}}
  97. <div class="alert success flash">
  98. <p>{{.Flash}}</p>
  99. </div>
  100. {{end}}
  101. {{template "posts" .}}
  102. {{if gt .TotalPages 1}}<nav id="paging" class="content-container clearfix">
  103. {{if or (and .Format.Ascending (le .CurrentPage .TotalPages)) (isRTL .Direction)}}
  104. {{if gt .CurrentPage 1}}<a href="{{.PrevPageURL .Prefix .CurrentPage .IsTopLevel}}">&#8672; {{if and .Format.Ascending (le .CurrentPage .TotalPages)}}Previous{{else}}Newer{{end}}</a>{{end}}
  105. {{if lt .CurrentPage .TotalPages}}<a style="float:right;" href="{{.NextPageURL .Prefix .CurrentPage .IsTopLevel}}">{{if and .Format.Ascending (lt .CurrentPage .TotalPages)}}Next{{else}}Older{{end}} &#8674;</a>{{end}}
  106. {{else}}
  107. {{if lt .CurrentPage .TotalPages}}<a href="{{.NextPageURL .Prefix .CurrentPage .IsTopLevel}}">&#8672; Older</a>{{end}}
  108. {{if gt .CurrentPage 1}}<a style="float:right;" href="{{.PrevPageURL .Prefix .CurrentPage .IsTopLevel}}">Newer &#8674;</a>{{end}}
  109. {{end}}
  110. </nav>{{end}}
  111. {{if not .IsWelcome}}{{template "emailsubscribe" .}}{{end}}
  112. {{if .Posts}}</section>{{else}}</div>{{end}}
  113. {{if .ShowFooterBranding }}
  114. <footer>
  115. <hr />
  116. <nav dir="ltr">
  117. {{if not .SingleUser}}<a class="home pubd" href="/">{{.SiteName}}</a> &middot; {{end}}powered by <a style="margin-left:0" href="https://writefreely.org">writefreely</a>
  118. </nav>
  119. </footer>
  120. {{ end }}
  121. </body>
  122. {{if .CanShowScript}}
  123. {{range .ExternalScripts}}<script type="text/javascript" src="{{.}}" async></script>{{end}}
  124. {{if .Script}}<script type="text/javascript">{{.ScriptDisplay}}</script>{{end}}
  125. {{end}}
  126. <script src="/js/h.js"></script>
  127. <script src="/js/postactions.js"></script>
  128. <script src="/js/localdate.js"></script>
  129. <script type="text/javascript" src="/js/menu.js"></script>
  130. <script type="text/javascript">
  131. var deleting = false;
  132. function delPost(e, id, owned) {
  133. e.preventDefault();
  134. if (deleting) {
  135. return;
  136. }
  137. // TODO: UNDO!
  138. if (window.confirm('Are you sure you want to delete this post?')) {
  139. // AJAX
  140. deletePost(id, "", function() {
  141. // Remove post from list
  142. var $postEl = document.getElementById('post-' + id);
  143. $postEl.parentNode.removeChild($postEl);
  144. // TODO: add next post from this collection at the bottom
  145. });
  146. }
  147. }
  148. var deletePost = function(postID, token, callback) {
  149. deleting = true;
  150. var $delBtn = document.getElementById('post-' + postID).getElementsByClassName('delete action')[0];
  151. $delBtn.innerHTML = '...';
  152. var http = new XMLHttpRequest();
  153. var url = "/api/posts/" + postID;
  154. http.open("DELETE", url, true);
  155. http.onreadystatechange = function() {
  156. if (http.readyState == 4) {
  157. deleting = false;
  158. if (http.status == 204) {
  159. callback();
  160. } else if (http.status == 409) {
  161. $delBtn.innerHTML = 'delete';
  162. alert("Post is synced to another account. Delete the post from that account instead.");
  163. // TODO: show "remove" button instead of "delete" now
  164. // Persist that state.
  165. // Have it remove the post locally only.
  166. } else {
  167. $delBtn.innerHTML = 'delete';
  168. alert("Failed to delete." + (http.status>=500?" Please try again.":""));
  169. }
  170. }
  171. }
  172. http.send();
  173. };
  174. var pinning = false;
  175. function pinPost(e, postID, slug, title) {
  176. e.preventDefault();
  177. if (pinning) {
  178. return;
  179. }
  180. pinning = true;
  181. var callback = function() {
  182. // Visibly remove post from collection
  183. var $postEl = document.getElementById('post-' + postID);
  184. $postEl.parentNode.removeChild($postEl);
  185. var $header = document.getElementsByTagName('header')[0];
  186. var $pinnedNavs = $header.getElementsByTagName('nav');
  187. // Add link to nav
  188. var link = '<a class="pinned" href="{{if not .SingleUser}}/{{.Alias}}/{{end}}'+slug+'">'+title+'</a>';
  189. if ($pinnedNavs.length == 0) {
  190. $header.insertAdjacentHTML("beforeend", '<nav>'+link+'</nav>');
  191. } else {
  192. $pinnedNavs[0].insertAdjacentHTML("beforeend", link);
  193. }
  194. };
  195. var $pinBtn = document.getElementById('post-' + postID).getElementsByClassName('pin action')[0];
  196. $pinBtn.innerHTML = '...';
  197. var http = new XMLHttpRequest();
  198. var url = "/api/collections/{{.Alias}}/pin";
  199. var params = [ { "id": postID } ];
  200. http.open("POST", url, true);
  201. http.setRequestHeader("Content-type", "application/json");
  202. http.onreadystatechange = function() {
  203. if (http.readyState == 4) {
  204. pinning = false;
  205. if (http.status == 200) {
  206. callback();
  207. } else if (http.status == 409) {
  208. $pinBtn.innerHTML = 'pin';
  209. alert("Post is synced to another account. Delete the post from that account instead.");
  210. // TODO: show "remove" button instead of "delete" now
  211. // Persist that state.
  212. // Have it remove the post locally only.
  213. } else {
  214. $pinBtn.innerHTML = 'pin';
  215. alert("Failed to pin." + (http.status>=500?" Please try again.":""));
  216. }
  217. }
  218. }
  219. http.send(JSON.stringify(params));
  220. };
  221. try {
  222. WebFontConfig = {
  223. custom: { families: [ 'Lora:400,700:latin', 'Open+Sans:400,700:latin' ], urls: [ '/css/fonts.css' ] }
  224. };
  225. (function() {
  226. var wf = document.createElement('script');
  227. wf.src = '/js/webfont.js';
  228. wf.type = 'text/javascript';
  229. wf.async = 'true';
  230. var s = document.getElementsByTagName('script')[0];
  231. s.parentNode.insertBefore(wf, s);
  232. })();
  233. } catch (e) {}
  234. </script>
  235. </html>{{end}}