serif 0.0.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|