persona 0.0.1
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/.gitignore +3 -0
- data/Gemfile +4 -0
- data/README.rdoc +5 -0
- data/Rakefile +2 -0
- data/bin/persona +12 -0
- data/lib/persona/file.rb +24 -0
- data/lib/persona/page.rb +13 -0
- data/lib/persona/post.rb +38 -0
- data/lib/persona/version.rb +3 -0
- data/lib/persona.rb +78 -0
- data/lib/tasks/persona_tasks.rb +10 -0
- data/persona.gemspec +21 -0
- data/template/Gemfile +1 -0
- data/template/config/persona.yaml +4 -0
- data/template/config.ru +9 -0
- data/template/contents/pages/about.txt +5 -0
- data/template/contents/posts/1900-01-01-hello-world.txt +5 -0
- data/template/public/css/main.css +108 -0
- data/template/views/index.erb +26 -0
- data/template/views/layout.erb +41 -0
- data/template/views/not_found.erb +10 -0
- data/template/views/page.erb +4 -0
- data/template/views/post.erb +4 -0
- metadata +101 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
data/Rakefile
ADDED
data/bin/persona
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.join(File.dirname(__FILE__), "..", "lib", "tasks", "persona_tasks")
|
3
|
+
|
4
|
+
|
5
|
+
def create_site(name)
|
6
|
+
p Dir.new('.').entries
|
7
|
+
end
|
8
|
+
|
9
|
+
if (ARGV.length == 2 and ARGV[0] == 'create_site')
|
10
|
+
PersonaTasks.create_site Dir.new('.'), ARGV[1]
|
11
|
+
end
|
12
|
+
|
data/lib/persona/file.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class File
|
4
|
+
|
5
|
+
def content_as_string
|
6
|
+
doc_started = false
|
7
|
+
metadata, data = '', ''
|
8
|
+
self.each_line do |line|
|
9
|
+
doc_started = true if line.chop == ''
|
10
|
+
if (doc_started)
|
11
|
+
data += line
|
12
|
+
else
|
13
|
+
metadata +=line
|
14
|
+
end
|
15
|
+
end
|
16
|
+
@metadata = YAML.parse(metadata)
|
17
|
+
return data
|
18
|
+
end
|
19
|
+
|
20
|
+
def metadata(name)
|
21
|
+
@metadata[name].value
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/lib/persona/page.rb
ADDED
data/lib/persona/post.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
class Post
|
2
|
+
|
3
|
+
attr_reader :content, :title, :author, :url, :date, :excerpt, :is_excerpt
|
4
|
+
|
5
|
+
def initialize(file_name)
|
6
|
+
f = File.open("./contents/posts/#{file_name}","r")
|
7
|
+
@content = f.content_as_string
|
8
|
+
@title = f.metadata 'title'
|
9
|
+
@author = f.metadata 'author'
|
10
|
+
@date = Date.strptime(f.metadata('date'), '%Y/%m/%d')
|
11
|
+
@excerpt = create_excerpt(@content)
|
12
|
+
|
13
|
+
splits = /(\d{4}-\d{2}-\d{2})-([^\/]*)\.txt$/.match file_name
|
14
|
+
if splits
|
15
|
+
@url = splits[1].gsub(/[-]/, "/") + "/" + splits[2] + "/"
|
16
|
+
end
|
17
|
+
|
18
|
+
f.close
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.from_url(y,m,d,name)
|
22
|
+
Post.new "#{y}-#{m}-#{d}-#{name}.txt"
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
MORE_TAG = '<!--more-->'
|
28
|
+
|
29
|
+
def create_excerpt(content)
|
30
|
+
if content.include? MORE_TAG
|
31
|
+
@is_excerpt = true
|
32
|
+
content.partition(MORE_TAG)[0] + "(... continued ...) "
|
33
|
+
else
|
34
|
+
content
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/lib/persona.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'erb'
|
3
|
+
require 'bundler'
|
4
|
+
require 'sinatra'
|
5
|
+
require 'builder'
|
6
|
+
|
7
|
+
require File.join(File.dirname(__FILE__), './persona', 'file')
|
8
|
+
autoload :Post, 'persona/post'
|
9
|
+
autoload :Page, 'persona/page'
|
10
|
+
|
11
|
+
|
12
|
+
#ROUTES
|
13
|
+
|
14
|
+
get '/' do
|
15
|
+
@posts = load_posts
|
16
|
+
erb :index
|
17
|
+
end
|
18
|
+
|
19
|
+
get '/feed/' do
|
20
|
+
builder do |xml|
|
21
|
+
xml.instruct! :xml, :version => '1.0'
|
22
|
+
xml.rss :version => "2.0" do
|
23
|
+
xml.channel do
|
24
|
+
xml.title ($config['site']['title'])
|
25
|
+
xml.description ($config['site']['description'])
|
26
|
+
xml.link ($config['site']['url'])
|
27
|
+
|
28
|
+
load_posts.first(10).each do |post|
|
29
|
+
xml.item do
|
30
|
+
xml.title post.title
|
31
|
+
xml.link(($config['site']['url'])+"/"+post.url)
|
32
|
+
xml.description post.content
|
33
|
+
xml.pubDate post.date.strftime("%a, %d %b %Y %H:%M:%S %z")
|
34
|
+
xml.guid(($config['site']['url'])+"/"+post.url)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
get '/feed' do
|
43
|
+
redirect '/feed/'
|
44
|
+
end
|
45
|
+
|
46
|
+
get '/:y/:m/:d/:name/' do
|
47
|
+
@page = Post.from_url params[:y], params[:m], params[:d], params[:name]
|
48
|
+
erb :post
|
49
|
+
end
|
50
|
+
|
51
|
+
get '/:y/:m/:d/:name' do #wrong link, but WP supports it
|
52
|
+
redirect "/#{params[:y]}/#{params[:m]}/#{params[:d]}/#{params[:name]}/"
|
53
|
+
end
|
54
|
+
|
55
|
+
get '/pages/:name' do
|
56
|
+
@page = Page.new params[:name]
|
57
|
+
erb :page
|
58
|
+
end
|
59
|
+
|
60
|
+
error do
|
61
|
+
erb :not_found
|
62
|
+
end
|
63
|
+
|
64
|
+
not_found do
|
65
|
+
erb :not_found
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def load_posts
|
70
|
+
posts = Dir.entries('./contents/posts').sort.reverse.reject do |it|
|
71
|
+
not it.end_with? '.txt'
|
72
|
+
end
|
73
|
+
|
74
|
+
posts.map do |it|
|
75
|
+
Post.new it
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
data/persona.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "persona/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "persona"
|
7
|
+
s.version = Persona::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Filippo Diotalevi"]
|
10
|
+
s.email = ["filippo.diotalevi@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/fdiotalevi/persona-cms"
|
12
|
+
s.summary = %q{Minimal personal content manager}
|
13
|
+
s.description = %q{A minimal personal content manager}
|
14
|
+
|
15
|
+
s.add_dependency('sinatra', '>= 1.1.0')
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
data/template/Gemfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'persona'
|
data/template/config.ru
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
html { margin: 20px }
|
2
|
+
body {
|
3
|
+
margin: 0 auto;
|
4
|
+
font-family: Georgia, 'Baskerville', Times, serif;
|
5
|
+
font-size: 18px;
|
6
|
+
line-height: 27px;
|
7
|
+
padding: 15px;
|
8
|
+
width: 780px;
|
9
|
+
|
10
|
+
}
|
11
|
+
header, footer, section, article {
|
12
|
+
display: block;
|
13
|
+
}
|
14
|
+
|
15
|
+
body > header {
|
16
|
+
height: 30px;
|
17
|
+
font-size: 16px;
|
18
|
+
vertical-align: top;
|
19
|
+
margin-bottom: 60px;
|
20
|
+
}
|
21
|
+
|
22
|
+
#content {
|
23
|
+
}
|
24
|
+
#by {
|
25
|
+
font-style: italic;
|
26
|
+
margin-right: 5px;
|
27
|
+
font-size: 28px;
|
28
|
+
}
|
29
|
+
#caption {
|
30
|
+
position: absolute;
|
31
|
+
font-size: 24px;
|
32
|
+
margin: -135px 0 0 70px;
|
33
|
+
}
|
34
|
+
#path {
|
35
|
+
color: #b53131;
|
36
|
+
}
|
37
|
+
.date {
|
38
|
+
font-style: italic;
|
39
|
+
line-height: 43px;
|
40
|
+
}
|
41
|
+
a {
|
42
|
+
color: #b83000;
|
43
|
+
}
|
44
|
+
h1 a {
|
45
|
+
color: black;
|
46
|
+
text-decoration: none;
|
47
|
+
}
|
48
|
+
a:hover {
|
49
|
+
text-decoration: underline;
|
50
|
+
}
|
51
|
+
|
52
|
+
.post header {
|
53
|
+
margin-bottom: 10px;
|
54
|
+
}
|
55
|
+
.post .body p:first-child {
|
56
|
+
margin-top: 0;
|
57
|
+
}
|
58
|
+
.post .body p:last-child {
|
59
|
+
margin-bottom: 0;
|
60
|
+
}
|
61
|
+
.post {
|
62
|
+
margin-bottom: 30px;
|
63
|
+
}
|
64
|
+
.post:last-child {
|
65
|
+
margin-bottom: 10px;
|
66
|
+
}
|
67
|
+
.post p {
|
68
|
+
margin: 10px 0;
|
69
|
+
}
|
70
|
+
.post .more {
|
71
|
+
margin-top: -10px;
|
72
|
+
margin-right: 30px;
|
73
|
+
font-style: italic;
|
74
|
+
text-align: right;
|
75
|
+
}
|
76
|
+
.more a {
|
77
|
+
text-decoration: none;
|
78
|
+
}
|
79
|
+
.more a:hover { text-decoration: underline }
|
80
|
+
|
81
|
+
.spaced {
|
82
|
+
margin-bottom: 50px;
|
83
|
+
}
|
84
|
+
|
85
|
+
h1, h2, h3, h4 {
|
86
|
+
margin: 0;
|
87
|
+
font-weight: normal;
|
88
|
+
}
|
89
|
+
ul, li {
|
90
|
+
list-style-type: none;
|
91
|
+
}
|
92
|
+
code {
|
93
|
+
font-family: 'Anonymous Pro', 'Bitstream Vera Sans', 'Monaco', Courier, mono;
|
94
|
+
}
|
95
|
+
pre {
|
96
|
+
padding: 20px;
|
97
|
+
}
|
98
|
+
blockquote {
|
99
|
+
font-style: italic;
|
100
|
+
}
|
101
|
+
|
102
|
+
body > footer {
|
103
|
+
text-align: left;
|
104
|
+
margin-left: 10px;
|
105
|
+
font-style: italic;
|
106
|
+
font-size: 18px;
|
107
|
+
color: #888;
|
108
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
<% @posts.first(3).each do |page| %>
|
3
|
+
|
4
|
+
<div class="spaced">
|
5
|
+
<h1><a href="<%= page.url %>"><%= page.title %></a></h1>
|
6
|
+
<div class="date">published on <%= page.date.strftime('%b %d, %Y') %> by <%= page.author %> </div>
|
7
|
+
|
8
|
+
<%= page.excerpt %>
|
9
|
+
|
10
|
+
<% if page.is_excerpt %>
|
11
|
+
<div class="date"><a href="<%= page.url %>">Read the complete post</a></div>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
14
|
+
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<h2>Older posts</h2>
|
18
|
+
<ul>
|
19
|
+
<% if @posts.size > 3%>
|
20
|
+
<% @posts[3..-1].each do |post| %>
|
21
|
+
<li>
|
22
|
+
<a href="<%= post.url %>"><%= post.title %></a>, published on <%= post.date.strftime('%b %d, %Y') %>
|
23
|
+
</li>
|
24
|
+
<%end%>
|
25
|
+
<%end%>
|
26
|
+
</ul>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<link rel="stylesheet" type="text/css" href="/css/main.css">
|
5
|
+
<link rel="alternate" type="application/atom+xml" title="feed" href="/feed/" />
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
7
|
+
<title>Filippo Diotalevi</title>
|
8
|
+
<meta name="keywords" content="startup,technology,java,ruby,rails,osgi">
|
9
|
+
<meta name="author" content="Filippo Diotalevi">
|
10
|
+
|
11
|
+
<script type="text/javascript">
|
12
|
+
|
13
|
+
var _gaq = _gaq || [];
|
14
|
+
_gaq.push(['_setAccount', 'UA-398358-5']);
|
15
|
+
_gaq.push(['_trackPageview']);
|
16
|
+
|
17
|
+
(function() {
|
18
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
19
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
20
|
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
21
|
+
})();
|
22
|
+
|
23
|
+
</script>
|
24
|
+
|
25
|
+
|
26
|
+
</head>
|
27
|
+
<body>
|
28
|
+
<header>
|
29
|
+
<a href='/'>Home</a> | <a href='/pages/about'>About</a>
|
30
|
+
</header>
|
31
|
+
|
32
|
+
<section>
|
33
|
+
<%= yield %>
|
34
|
+
</section>
|
35
|
+
<footer>
|
36
|
+
powered by Persona (unreleased yet), the minimal personal content manager
|
37
|
+
</footer>
|
38
|
+
</body>
|
39
|
+
</html>
|
40
|
+
|
41
|
+
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: persona
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Filippo Diotalevi
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-26 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: sinatra
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 1
|
31
|
+
- 0
|
32
|
+
version: 1.1.0
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description: A minimal personal content manager
|
36
|
+
email:
|
37
|
+
- filippo.diotalevi@gmail.com
|
38
|
+
executables:
|
39
|
+
- persona
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
44
|
+
files:
|
45
|
+
- .gitignore
|
46
|
+
- Gemfile
|
47
|
+
- README.rdoc
|
48
|
+
- Rakefile
|
49
|
+
- bin/persona
|
50
|
+
- lib/persona.rb
|
51
|
+
- lib/persona/file.rb
|
52
|
+
- lib/persona/page.rb
|
53
|
+
- lib/persona/post.rb
|
54
|
+
- lib/persona/version.rb
|
55
|
+
- lib/tasks/persona_tasks.rb
|
56
|
+
- persona.gemspec
|
57
|
+
- template/Gemfile
|
58
|
+
- template/config.ru
|
59
|
+
- template/config/persona.yaml
|
60
|
+
- template/contents/pages/about.txt
|
61
|
+
- template/contents/posts/1900-01-01-hello-world.txt
|
62
|
+
- template/public/css/main.css
|
63
|
+
- template/views/index.erb
|
64
|
+
- template/views/layout.erb
|
65
|
+
- template/views/not_found.erb
|
66
|
+
- template/views/page.erb
|
67
|
+
- template/views/post.erb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: https://github.com/fdiotalevi/persona-cms
|
70
|
+
licenses: []
|
71
|
+
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
version: "0"
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
requirements: []
|
94
|
+
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 1.3.7
|
97
|
+
signing_key:
|
98
|
+
specification_version: 3
|
99
|
+
summary: Minimal personal content manager
|
100
|
+
test_files: []
|
101
|
+
|