serif 0.0.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +3 -0
- data/Gemfile.lock +48 -0
- data/README.md +243 -0
- data/bin/serif +81 -0
- data/lib/serif/admin_server.rb +186 -0
- data/lib/serif/config.rb +25 -0
- data/lib/serif/content_file.rb +154 -0
- data/lib/serif/draft.rb +58 -0
- data/lib/serif/markup_renderer.rb +24 -0
- data/lib/serif/post.rb +65 -0
- data/lib/serif/server.rb +32 -0
- data/lib/serif/site.rb +148 -0
- data/lib/serif.rb +19 -0
- data/serif.gemspec +28 -0
- data/statics/assets/js/jquery.autosize.js +175 -0
- data/statics/assets/js/mousetrap.min.js +28 -0
- data/statics/skeleton/_config.yml +14 -0
- data/statics/skeleton/_layouts/default.html +6 -0
- data/statics/skeleton/_templates/post.html +5 -0
- data/statics/skeleton/index.html +9 -0
- data/statics/templates/admin/edit_draft.liquid +54 -0
- data/statics/templates/admin/edit_post.liquid +36 -0
- data/statics/templates/admin/index.liquid +15 -0
- data/statics/templates/admin/layout.liquid +539 -0
- data/statics/templates/admin/new_draft.liquid +35 -0
- metadata +175 -6
- data/serif-stub.gemspec +0 -10
@@ -0,0 +1,28 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2012 Craig Campbell
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*
|
16
|
+
* Mousetrap is a simple keyboard shortcut library for Javascript with
|
17
|
+
* no external dependencies
|
18
|
+
*
|
19
|
+
* @version 1.1.4
|
20
|
+
* @url craig.is/killing/mice
|
21
|
+
*/
|
22
|
+
(function(){function q(a,c,b){if(a.addEventListener)return a.addEventListener(c,b,!1);a.attachEvent("on"+c,b)}function w(a){return"keypress"==a.type?String.fromCharCode(a.which):h[a.which]?h[a.which]:x[a.which]?x[a.which]:String.fromCharCode(a.which).toLowerCase()}function r(a){var a=a||{},c=!1,b;for(b in l)a[b]?c=!0:l[b]=0;c||(n=!1)}function y(a,c,b,d,F){var g,e,f=[],i=b.type;if(!k[a])return[];"keyup"==i&&s(a)&&(c=[a]);for(g=0;g<k[a].length;++g)if(e=k[a][g],!(e.seq&&l[e.seq]!=e.level)&&i==e.action&&
|
23
|
+
("keypress"==i&&!b.metaKey&&!b.ctrlKey||c.sort().join(",")===e.modifiers.sort().join(",")))d&&e.combo==F&&k[a].splice(g,1),f.push(e);return f}function t(a,c){!1===a(c)&&(c.preventDefault&&c.preventDefault(),c.stopPropagation&&c.stopPropagation(),c.returnValue=!1,c.cancelBubble=!0)}function u(a){"number"!==typeof a.which&&(a.which=a.keyCode);var c=w(a);if(c)if("keyup"==a.type&&v==c)v=!1;else{var b=a.target||a.srcElement,d=b.tagName;if(!(-1<(" "+b.className+" ").indexOf(" mousetrap ")?0:"INPUT"==d||
|
24
|
+
"SELECT"==d||"TEXTAREA"==d||b.contentEditable&&"true"==b.contentEditable)){b=[];a.shiftKey&&b.push("shift");a.altKey&&b.push("alt");a.ctrlKey&&b.push("ctrl");a.metaKey&&b.push("meta");for(var b=y(c,b,a),f={},g=!1,d=0;d<b.length;++d)b[d].seq?(g=!0,f[b[d].seq]=1,t(b[d].callback,a)):!g&&!n&&t(b[d].callback,a);a.type==n&&!s(c)&&r(f)}}}function s(a){return"shift"==a||"ctrl"==a||"alt"==a||"meta"==a}function z(a,c,b){if(!b){if(!p){p={};for(var d in h)95<d&&112>d||h.hasOwnProperty(d)&&(p[h[d]]=d)}b=p[a]?
|
25
|
+
"keydown":"keypress"}"keypress"==b&&c.length&&(b="keydown");return b}function A(a,c,b,d,f){var a=a.replace(/\s+/g," "),g=a.split(" "),e,h,i=[];if(1<g.length){var j=a,m=b;l[j]=0;m||(m=z(g[0],[]));a=function(){n=m;++l[j];clearTimeout(B);B=setTimeout(r,1E3)};b=function(a){t(c,a);"keyup"!==m&&(v=w(a));setTimeout(r,10)};for(d=0;d<g.length;++d)A(g[d],d<g.length-1?a:b,m,j,d)}else{h="+"===a?["+"]:a.split("+");for(g=0;g<h.length;++g)e=h[g],C[e]&&(e=C[e]),b&&("keypress"!=b&&D[e])&&(e=D[e],i.push("shift")),
|
26
|
+
s(e)&&i.push(e);b=z(e,i,b);k[e]||(k[e]=[]);y(e,i,{type:b},!d,a);k[e][d?"unshift":"push"]({callback:c,modifiers:i,action:b,seq:d,level:f,combo:a})}}for(var h={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",224:"meta"},x={106:"*",107:"+",109:"-",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",
|
27
|
+
221:"]",222:"'"},D={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"},C={option:"alt",command:"meta","return":"enter",escape:"esc"},p,k={},j={},l={},B,v=!1,n=!1,f=1;20>f;++f)h[111+f]="f"+f;for(f=0;9>=f;++f)h[f+96]=f;q(document,"keypress",u);q(document,"keydown",u);q(document,"keyup",u);var E={bind:function(a,c,b){for(var d=a instanceof Array?a:[a],f=0;f<d.length;++f)A(d[f],c,b);j[a+":"+b]=c;return this},
|
28
|
+
unbind:function(a,c){j[a+":"+c]&&(delete j[a+":"+c],this.bind(a,function(){},c));return this},trigger:function(a,c){j[a+":"+c]();return this},reset:function(){k={};j={};return this}};window.Mousetrap=E;"function"==typeof define&&define.amd&&define("mousetrap",function(){return E})})();
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This is the Serif config file. It must be a valid YAML document.
|
2
|
+
#
|
3
|
+
# Some configuration options:
|
4
|
+
#
|
5
|
+
# admin:
|
6
|
+
# username: [a username for the admin web interface]
|
7
|
+
# password: [a password for the admin web interface]
|
8
|
+
# permalink: [permalink format for generated posts]
|
9
|
+
#
|
10
|
+
# See the README for information on permalink formats.
|
11
|
+
|
12
|
+
admin:
|
13
|
+
username: changethisusername
|
14
|
+
password: changethispassword
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<h2>{{ post.title }}</h2>
|
2
|
+
|
3
|
+
{{ post.content | markdown }}
|
4
|
+
|
5
|
+
<p><a href="http://twitter.com/share?text={{ post.title | encode_uri_component }}&url={{ 'http://www.mysite.com' | encode_uri_component }}{{ post.url | encode_uri_component }}">Submit this to Twitter.</p>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
{% if error_message %}
|
2
|
+
<div id="error-message">
|
3
|
+
<p>{{ error_message }}</p>
|
4
|
+
</div>
|
5
|
+
{% endif %}
|
6
|
+
|
7
|
+
<div id="edit">
|
8
|
+
<form action="/admin/edit/{% if post.draft %}drafts{% else %}posts{% endif %}" method="post">
|
9
|
+
{% if post.slug %}<input type="hidden" name="original_slug" value="{{ post.slug | escape }}">{% endif %}
|
10
|
+
|
11
|
+
<h2 id="slug">
|
12
|
+
<code>
|
13
|
+
<span>{{ post.type }}s/</span><span><input{% if post.published %}{{ " disabled" }}{% endif %}{% if conflicting_name %}{{ ' class="error" title="Pick a different name"' }}{% endif %} name="slug" placeholder="a-url-fragment" value="{{ post.slug | escape }}"{% if autofocus == "slug" %}{{ " autofocus" }}{% endif %}></span>
|
14
|
+
</code>
|
15
|
+
</h2>
|
16
|
+
|
17
|
+
<div class="post{% if post.draft %} draft{% endif %}">
|
18
|
+
<header>
|
19
|
+
<h1 id="heading" class="post">
|
20
|
+
<textarea spellcheck="false" placeholder="It was a dark and stormy night" name="title"{% if autofocus == "title" %}{{ " autofocus" }}{% endif %}>{% if post.title %}{{ post.title | escape }}{% endif %}</textarea>
|
21
|
+
</h1>
|
22
|
+
|
23
|
+
{% if post.draft %}
|
24
|
+
<time datetime="{{ 'now' | date: "%Y-%m-%d" }}">{{ 'now' | date: "%B %d %Y" }}</time>
|
25
|
+
{% else %}
|
26
|
+
<time datetime="{{ post.created | date: "%Y-%m-%d" }}">{{ post.created | date: "%B %d %Y" }}</time>
|
27
|
+
{% endif %}
|
28
|
+
</header>
|
29
|
+
</div>
|
30
|
+
<div id="content-areas">
|
31
|
+
<textarea spellcheck="false" id="content" placeholder="Lorem ipsum dolor sit amet." name="markdown"{% if autofocus == "markdown" %}{{ " autofocus" }}{% endif %}>{{ post.content | strip | escape }}</textarea>
|
32
|
+
|
33
|
+
<article id="entry" class="post" data-state="hidden"></article>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
<input id="save" type="submit" value="Update {{ post.type | escape }}">
|
37
|
+
|
38
|
+
<input type="checkbox" id="render-preview"> <label class="preview" for="render-preview">Preview</label>
|
39
|
+
|
40
|
+
{% if post.draft %}
|
41
|
+
<input type="checkbox" name="publish" value="yes" id="publish"> <label for="publish">Publish?</label>
|
42
|
+
{% endif %}
|
43
|
+
|
44
|
+
</form>
|
45
|
+
|
46
|
+
{% if post.draft %}
|
47
|
+
<form id="delete" method="post" action="/admin/delete">
|
48
|
+
{% if post.slug %}<input type="hidden" name="original_slug" value="{{ post.slug | escape }}">{% endif %}
|
49
|
+
<input type="checkbox" name="confirm_delete" value="yes" id="confirm-delete"> <label for="confirm-delete">Confirm</label>
|
50
|
+
<input type="submit" value="Delete">
|
51
|
+
</form>
|
52
|
+
{% endif %}
|
53
|
+
|
54
|
+
</div>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
{% if error_message %}
|
2
|
+
<div id="error-message">
|
3
|
+
<p>{{ error_message }}</p>
|
4
|
+
</div>
|
5
|
+
{% endif %}
|
6
|
+
|
7
|
+
<div id="edit">
|
8
|
+
<form action="/admin/edit/posts" method="post">
|
9
|
+
<input type="hidden" name="original_slug" value="{{ post.slug | escape }}">
|
10
|
+
|
11
|
+
<h2 id="slug">
|
12
|
+
<code>
|
13
|
+
<span>posts/</span><span><input disabled name="slug" placeholder="a-url-fragment" value="{{ post.slug | escape }}"></span>
|
14
|
+
</code>
|
15
|
+
</h2>
|
16
|
+
|
17
|
+
<div class="post draft">
|
18
|
+
<header>
|
19
|
+
<h1 id="heading" class="post">
|
20
|
+
<textarea spellcheck="false" placeholder="It was a dark and stormy night" name="title" autofocus>{{ post.title | escape }}</textarea>
|
21
|
+
</h1>
|
22
|
+
|
23
|
+
<time datetime="{{ post.created | date: "%Y-%m-%d" }}">{{ post.created | date: "%B %d %Y" }}</time>
|
24
|
+
</header>
|
25
|
+
</div>
|
26
|
+
<div id="content-areas">
|
27
|
+
<textarea spellcheck="false" id="content" placeholder="Lorem ipsum dolor sit amet." name="markdown">{{ post.content | strip | escape }}</textarea>
|
28
|
+
|
29
|
+
<article id="entry" class="post" data-state="hidden"></article>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<input id="save" type="submit" value="Update post">
|
33
|
+
|
34
|
+
<input type="checkbox" id="render-preview"> <label class="preview" for="render-preview">Preview</label>
|
35
|
+
</form>
|
36
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<h1>Drafts</h1>
|
2
|
+
|
3
|
+
<ul>
|
4
|
+
{% for draft in drafts %}
|
5
|
+
<li><a href="/admin/edit/drafts/{{ draft.slug }}">{% if draft.slug != empty %}{{ draft.slug }}{% else %}<em>(untitled)</em>{% endif %}</a></li>
|
6
|
+
{% endfor %}
|
7
|
+
</ul>
|
8
|
+
|
9
|
+
<h1>Posts</h1>
|
10
|
+
|
11
|
+
<ul>
|
12
|
+
{% for post in posts %}
|
13
|
+
<li><a href="/admin/edit/posts/{{ post.slug }}">{% if post.title != empty %}{{ post.title }}{% else %}<em>(untitled)</em>{% endif %}</a></li>
|
14
|
+
{% endfor %}
|
15
|
+
</ul>
|