who-needs-wp 0.6.0 → 0.6.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/bin/who-needs-wp +1 -1
- data/lib/who-needs-wp.rb +51 -56
- data/lib/who-needs-wp/Content.rb +89 -0
- data/lib/who-needs-wp/content/Page.rb +33 -0
- data/lib/who-needs-wp/content/Post.rb +76 -0
- data/lib/who-needs-wp/sidebar/pageindex.rb +1 -1
- data/lib/who-needs-wp/sidebar/recentposts.rb +1 -1
- data/lib/who-needs-wp/templates/all_posts.haml +3 -2
- data/lib/who-needs-wp/templates/atom.haml +7 -7
- data/lib/who-needs-wp/templates/layout.haml +1 -1
- data/lib/who-needs-wp/templates/page.haml +3 -3
- data/lib/who-needs-wp/templates/pageindex.haml +1 -1
- data/lib/who-needs-wp/templates/post.haml +6 -6
- data/lib/who-needs-wp/templates/recentposts.haml +3 -3
- data/lib/who-needs-wp/templates/rss.haml +5 -5
- metadata +34 -7
- data/README.html +0 -132
- data/lib/who-needs-wp/pages.rb +0 -47
- data/lib/who-needs-wp/posts.rb +0 -89
data/bin/who-needs-wp
CHANGED
data/lib/who-needs-wp.rb
CHANGED
@@ -2,8 +2,6 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'rdiscount'
|
4
4
|
require 'haml'
|
5
|
-
|
6
|
-
|
7
5
|
require 'open-uri'
|
8
6
|
require 'sass'
|
9
7
|
require 'makers-mark'
|
@@ -12,25 +10,23 @@ require 'rss/maker'
|
|
12
10
|
require 'net/ssh'
|
13
11
|
require 'net/sftp'
|
14
12
|
require 'who-needs-wp/css.rb'
|
13
|
+
require 'who-needs-wp/Content.rb'
|
14
|
+
require 'who-needs-wp/content/Page.rb'
|
15
|
+
require 'who-needs-wp/content/Post.rb'
|
15
16
|
require 'who-needs-wp/Sidebar.rb'
|
16
17
|
require 'who-needs-wp/sidebar/twitter.rb'
|
17
18
|
require 'who-needs-wp/sidebar/delicious.rb'
|
18
19
|
require 'who-needs-wp/sidebar/recentposts.rb'
|
19
20
|
require 'who-needs-wp/sidebar/pageindex.rb'
|
20
21
|
require 'who-needs-wp/templates.rb'
|
21
|
-
require 'who-needs-wp/posts.rb'
|
22
|
-
require 'who-needs-wp/pages.rb'
|
23
22
|
|
24
23
|
module WhoNeedsWP
|
25
|
-
# A list of HTML strings which will be the sidebar
|
26
|
-
@sidebar = []
|
27
24
|
|
28
25
|
# Map of templates which are used to render content
|
29
26
|
@template = []
|
30
27
|
|
31
28
|
# Logger
|
32
29
|
@logger = Logger.new(STDOUT)
|
33
|
-
|
34
30
|
# Generate the site with the specified options
|
35
31
|
def self.generate(options)
|
36
32
|
@options = options
|
@@ -38,58 +34,57 @@ module WhoNeedsWP
|
|
38
34
|
@options[:url] = ''
|
39
35
|
end
|
40
36
|
self.load_templates
|
41
|
-
self.load_posts
|
42
|
-
|
43
|
-
if @posts.length > 0
|
44
|
-
RecentPosts.new
|
45
|
-
end
|
46
|
-
if @pages.length > 0
|
47
|
-
PageIndex.new
|
48
|
-
end
|
37
|
+
#self.load_posts
|
38
|
+
|
49
39
|
if @options[:twitter]
|
50
40
|
if @options[:twitter][:username]
|
51
41
|
TwitterFeed.new(@options[:twitter][:username])
|
52
|
-
end
|
42
|
+
end
|
53
43
|
if @options[:twitter][:search]
|
54
44
|
TwitterSearch.new(@options[:twitter][:search])
|
55
45
|
end
|
56
46
|
end
|
57
47
|
if @options[:delicious]
|
58
48
|
delicious = Delicious.new(@options[:delicious][:user])
|
59
|
-
end
|
60
|
-
|
61
|
-
|
49
|
+
end
|
50
|
+
Page.load
|
51
|
+
Post.load
|
52
|
+
if Post.all.length > 0
|
53
|
+
RecentPosts.new
|
54
|
+
end
|
55
|
+
if Page.all.length > 0
|
56
|
+
PageIndex.new
|
57
|
+
end
|
58
|
+
Page.render_all
|
59
|
+
Post.render_all
|
60
|
+
Post.atom
|
61
|
+
Post.rss
|
62
|
+
Post.index
|
62
63
|
self.index
|
63
|
-
self.all_posts
|
64
64
|
self.css
|
65
|
-
|
66
|
-
|
67
|
-
if @options[:upload]
|
65
|
+
|
66
|
+
if @options[:upload]
|
68
67
|
self.upload
|
69
68
|
end
|
70
69
|
end
|
71
70
|
|
71
|
+
def self.options
|
72
|
+
@options
|
73
|
+
end
|
74
|
+
|
72
75
|
# Generate the index page for the blog
|
73
76
|
def self.index
|
74
77
|
contents = ""
|
75
|
-
if
|
76
|
-
|
77
|
-
contents << post
|
78
|
+
if Post.all.length > 0
|
79
|
+
Post.all[0..3].each do |post|
|
80
|
+
contents << post.html
|
78
81
|
end
|
79
82
|
else
|
80
|
-
contents <<
|
83
|
+
contents << Page.all.first.html
|
81
84
|
end
|
82
85
|
self.render_html("index.html", "index", contents)
|
83
86
|
end
|
84
87
|
|
85
|
-
# Generate a page containing a list of all posts
|
86
|
-
def self.all_posts
|
87
|
-
self.render_html("posts/all.html", "post_index", @template['all_posts'].render(Object.new, {
|
88
|
-
:posts => @posts,
|
89
|
-
:options => @options
|
90
|
-
}), "All Posts")
|
91
|
-
end
|
92
|
-
|
93
88
|
def self.upload
|
94
89
|
match = @options[:remote_addr].match(/(.*)@(.*):(.*)/)
|
95
90
|
username = match[1]
|
@@ -105,15 +100,15 @@ module WhoNeedsWP
|
|
105
100
|
Net::SFTP.start(host, username) do |sftp|
|
106
101
|
Dir.glob("**/*") do |filename|
|
107
102
|
basename = File.basename(filename)
|
108
|
-
if basename =~ /^\..*$/ or
|
109
|
-
|
110
|
-
|
111
|
-
|
103
|
+
if basename =~ /^\..*$/ or
|
104
|
+
basename =~ /.*\.markdown$/ or
|
105
|
+
basename =~ /^.*~$/ or
|
106
|
+
basename =~ /^\#.*\#$/
|
112
107
|
@logger.debug "Skipping #{filename}"
|
113
108
|
else
|
114
109
|
remote_filename = remote_path + filename.sub(local_path, '')
|
115
110
|
@logger.debug "Remote filename = #{remote_filename}"
|
116
|
-
|
111
|
+
|
117
112
|
# If the directory does not exist then create it
|
118
113
|
begin
|
119
114
|
if File.directory? filename
|
@@ -128,23 +123,23 @@ module WhoNeedsWP
|
|
128
123
|
end
|
129
124
|
|
130
125
|
if not File.directory? filename
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
126
|
+
# If the file does not exist then create it
|
127
|
+
begin
|
128
|
+
status = sftp.stat!(remote_filename)
|
129
|
+
rescue Net::SFTP::StatusException
|
130
|
+
@logger.debug "#{remote_filename} does not exist"
|
131
|
+
sftp.upload!(filename, remote_filename)
|
132
|
+
sftp.setstat(remote_filename, :permissions => permissions[:file])
|
133
|
+
next
|
134
|
+
end
|
140
135
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
136
|
+
# If the local file has changed then upload it
|
137
|
+
if File.stat(filename).mtime > Time.at(status.mtime)
|
138
|
+
@logger.debug "Copying #{filename} to #{remote_filename}"
|
139
|
+
sftp.upload!(filename, remote_filename)
|
140
|
+
else
|
141
|
+
@logger.debug "Skipping #{filename}"
|
142
|
+
end
|
148
143
|
end
|
149
144
|
end
|
150
145
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module WhoNeedsWP
|
2
|
+
# Class for storing content which is rendered on the site
|
3
|
+
class Content
|
4
|
+
# Unique identifier of the content, can be used in RSS & Atom feeds
|
5
|
+
attr_accessor :id
|
6
|
+
# HTML content of the content
|
7
|
+
attr_accessor :html
|
8
|
+
# Original Markdown content
|
9
|
+
attr_accessor :markdown
|
10
|
+
# Title of the content derived from the filename
|
11
|
+
attr_accessor :title
|
12
|
+
# Author of the content
|
13
|
+
attr_accessor :author
|
14
|
+
# The full URL of this peice of content
|
15
|
+
attr_accessor :url
|
16
|
+
# A tiny URL which can be used when referring to this content
|
17
|
+
attr_accessor :tiny_url
|
18
|
+
# A short summary of this content, normally first paragraph
|
19
|
+
attr_accessor :summary
|
20
|
+
# A Hash which contains the original and generated filename
|
21
|
+
attr_accessor :filename
|
22
|
+
|
23
|
+
|
24
|
+
def initialize(filename)
|
25
|
+
@filename = {
|
26
|
+
:original => filename,
|
27
|
+
:generated => generate_filename(filename)
|
28
|
+
}
|
29
|
+
@title = generate_title(filename)
|
30
|
+
@url = WhoNeedsWP::options[:url] + '/' + @filename[:generated]
|
31
|
+
# Set the default author of the content to be the site author
|
32
|
+
@author = WhoNeedsWP::options[:author]
|
33
|
+
|
34
|
+
read_file
|
35
|
+
end
|
36
|
+
|
37
|
+
# Render this peice of content
|
38
|
+
def render
|
39
|
+
# Set the summary to be the first paragraph
|
40
|
+
@summary = $1 if @html =~ (/(?:<p>)(.*?)(?:<\/p>)/)
|
41
|
+
# Render the content HTML within a page
|
42
|
+
WhoNeedsWP::render_html(@filename[:generated], "page", @html, @title)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Read the content from the filename
|
48
|
+
def read_file
|
49
|
+
content = File.read(@filename[:original])
|
50
|
+
# Remove the author, if there is one from the Markdown
|
51
|
+
content = extract_author(content)
|
52
|
+
@markdown = MakersMark.generate(content)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Return the title of the content, based on the filename
|
56
|
+
def generate_title(filename)
|
57
|
+
match = filename.match(/.*\/([^\.]*)/)
|
58
|
+
return match[1].gsub(/_/, ' ')
|
59
|
+
end
|
60
|
+
|
61
|
+
# Return the filename which will be use to save rendered content
|
62
|
+
def generate_filename(filename)
|
63
|
+
File.dirname(filename) + "/" + File.basename(filename, ".markdown") + ".html"
|
64
|
+
end
|
65
|
+
|
66
|
+
# Generate a unique ID for this content
|
67
|
+
def generate_id
|
68
|
+
if self.created_at == nil
|
69
|
+
raise "Content must have a timestamp before a unique ID can be generated"
|
70
|
+
end
|
71
|
+
# Replace the HTTP from the URL with tag:
|
72
|
+
@id = (WhoNeedsWP::options[:url] + @filename[:generated]).gsub(/http:\/\//, 'tag:')
|
73
|
+
match = @id.match(/([^\/]*)\/(.*)/)
|
74
|
+
@id = "#{match[1]},#{self.created_at.strftime('%Y-%m-%d')}:#{match[2]}" if match
|
75
|
+
end
|
76
|
+
|
77
|
+
# Read the author from the Markdown content. If none exists
|
78
|
+
# then set the default author.
|
79
|
+
def extract_author(content)
|
80
|
+
match = content.match(/^[aA]uthor: (.*)$/o)
|
81
|
+
if match
|
82
|
+
@author = match[1]
|
83
|
+
# Remove the author from the post text
|
84
|
+
content.gsub! /^[aA]uthor: .*$/, ''
|
85
|
+
end
|
86
|
+
return content
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module WhoNeedsWP
|
2
|
+
class Page < Content
|
3
|
+
# A list of all the pages on the site
|
4
|
+
@@pages = []
|
5
|
+
# Load all pages
|
6
|
+
def self.load
|
7
|
+
Dir.glob('pages/*.markdown').each do |filename|
|
8
|
+
@@pages << Page.new(filename)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# See Content.render_content
|
13
|
+
def render
|
14
|
+
@html = WhoNeedsWP::render_template("page", {
|
15
|
+
:page => self,
|
16
|
+
:title => @title
|
17
|
+
})
|
18
|
+
super()
|
19
|
+
end
|
20
|
+
|
21
|
+
# Render all the pages loaded
|
22
|
+
def self.render_all
|
23
|
+
@@pages.each do |page|
|
24
|
+
page.render
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return all the pages created
|
29
|
+
def self.all
|
30
|
+
return @@pages
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module WhoNeedsWP
|
2
|
+
class Post < Content
|
3
|
+
# Date at which content was created, or specified in filing structure
|
4
|
+
attr_accessor :created_at
|
5
|
+
# Create a new Post object
|
6
|
+
def initialize(filename, created_at)
|
7
|
+
super(filename)
|
8
|
+
@created_at = created_at
|
9
|
+
end
|
10
|
+
|
11
|
+
# A list of all the pages on the site
|
12
|
+
@@posts = []
|
13
|
+
|
14
|
+
# Load all pages
|
15
|
+
def self.load
|
16
|
+
Dir.glob('posts/**/*.markdown').each do |filename|
|
17
|
+
match = filename.match(/([0-9]{4})\/([0-9]{2})\/([0-9]{2})\/([^\.]*)/)
|
18
|
+
date = DateTime.new(match[1].to_i, match[2].to_i, match[3].to_i)
|
19
|
+
@@posts << Post.new(filename, date)
|
20
|
+
end
|
21
|
+
# Sort the posts
|
22
|
+
@@posts.sort! { |a, b| a.created_at <=> b.created_at }
|
23
|
+
@@posts.reverse!
|
24
|
+
end
|
25
|
+
|
26
|
+
# See Content.render_content
|
27
|
+
def render(previous_post, next_post)
|
28
|
+
@html = WhoNeedsWP::render_template("post", {
|
29
|
+
:post => self,
|
30
|
+
:title => @title,
|
31
|
+
:previous_post => previous_post,
|
32
|
+
:next_post => next_post
|
33
|
+
})
|
34
|
+
super()
|
35
|
+
end
|
36
|
+
|
37
|
+
# Render all the posts loaded
|
38
|
+
def self.render_all
|
39
|
+
@@posts.each_index do |index|
|
40
|
+
post = @@posts[index]
|
41
|
+
previous_post = @@posts[index + 1] if index + 1 < @@posts.length
|
42
|
+
next_post = @@posts[index - 1] if index > 1
|
43
|
+
post.render(previous_post, next_post)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return all the posts created
|
48
|
+
def self.all
|
49
|
+
return @@posts
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.index(filename = "posts/index.html")
|
53
|
+
WhoNeedsWP::render_html(filename, "post_index", WhoNeedsWP::render_template("all_posts", {
|
54
|
+
:posts => @@posts
|
55
|
+
}), "All Posts")
|
56
|
+
end
|
57
|
+
|
58
|
+
# Generate an RSS feed of all the posts
|
59
|
+
def self.rss(filename = "posts.rss")
|
60
|
+
File.open(filename, "w") do |file|
|
61
|
+
file.write WhoNeedsWP::render_template("rss", {
|
62
|
+
:posts => @@posts
|
63
|
+
})
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Generate an ATOM feed of all the posts
|
68
|
+
def self.atom(filename = "posts.atom")
|
69
|
+
File.open(filename, "w") do |file|
|
70
|
+
file.write WhoNeedsWP::render_template("atom", {
|
71
|
+
:posts => @@posts
|
72
|
+
})
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -3,7 +3,7 @@ module WhoNeedsWP
|
|
3
3
|
class RecentPosts < Sidebar
|
4
4
|
# See Sidebar.render
|
5
5
|
def render
|
6
|
-
WhoNeedsWP::render_template("recentposts", { :posts => WhoNeedsWP::
|
6
|
+
WhoNeedsWP::render_template("recentposts", { :posts => WhoNeedsWP::Post.all[0..5] })
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
@@ -2,5 +2,6 @@
|
|
2
2
|
%ul
|
3
3
|
- posts.each do |post|
|
4
4
|
%li
|
5
|
-
%span.date= post
|
6
|
-
%a.title{:href => "#{
|
5
|
+
%span.date= post.created_at.strftime('%Y-%m-%d')
|
6
|
+
%a.title{:href => "#{post.url}", :title => post.title}= post.title
|
7
|
+
%p= post.summary
|
@@ -1,19 +1,19 @@
|
|
1
1
|
!!! XML utf-8
|
2
2
|
%feed{:xmlns => "http://www.w3.org/2005/Atom"}
|
3
3
|
%title= options[:title]
|
4
|
-
%id= "#{options[:url]}posts.atom"
|
4
|
+
%id= "#{options[:url]}/posts.atom"
|
5
5
|
%updated= "#{Time.now.xmlschema}"
|
6
6
|
%author
|
7
7
|
%name= options[:author]
|
8
8
|
%link{:href => "#{options[:url]}"}/
|
9
9
|
- posts.each do |post|
|
10
10
|
%entry
|
11
|
-
%title= post
|
12
|
-
%id= post
|
13
|
-
%updated= Time.parse(post
|
14
|
-
%link{:href => "#{options[:url]}/#{post
|
15
|
-
%content{:type => "text/html", :src => "#{options[:url]}/#{post
|
11
|
+
%title= post.title
|
12
|
+
%id= post.id
|
13
|
+
%updated= Time.parse(post.created_at.to_s).xmlschema
|
14
|
+
%link{:href => "#{options[:url]}/#{post.filename[:generated]}"}/
|
15
|
+
%content{:type => "text/html", :src => "#{options[:url]}/#{post.filename[:generated]}"}/
|
16
16
|
%summary{:type => "html"}
|
17
17
|
:cdata
|
18
|
-
#{post
|
18
|
+
#{post.summary}
|
19
19
|
|
@@ -20,7 +20,7 @@
|
|
20
20
|
%script{:src => 'http://www.google-analytics.com/ga.js', :type => 'text/javascript'}/
|
21
21
|
:javascript
|
22
22
|
try {
|
23
|
-
var pageTracker = _gat._getTracker("#{options[:google_analytics]}
|
23
|
+
var pageTracker = _gat._getTracker("#{options[:google_analytics]}");
|
24
24
|
pageTracker._trackPageview();
|
25
25
|
} catch(err) {}
|
26
26
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
|
2
2
|
.page
|
3
3
|
%h2.title
|
4
|
-
%a{:href => "#{options[:url]}/#{page
|
4
|
+
%a{:href => "#{options[:url]}/#{page.filename[:generated]}"}= page.title
|
5
5
|
.author
|
6
6
|
by
|
7
|
-
= page
|
7
|
+
= page.author
|
8
8
|
.content
|
9
|
-
~ page
|
9
|
+
~ page.markdown
|
@@ -1,14 +1,14 @@
|
|
1
1
|
|
2
2
|
.post
|
3
3
|
%h2.title
|
4
|
-
%a{:href => "#{
|
4
|
+
%a{:href => "#{post.url}"}= post.title
|
5
5
|
.date
|
6
|
-
= post
|
6
|
+
= post.created_at.strftime("%B %d, %Y")
|
7
7
|
.author
|
8
8
|
by
|
9
|
-
= post
|
9
|
+
= post.author
|
10
10
|
.content
|
11
|
-
~ post
|
11
|
+
~ post.markdown
|
12
12
|
|
13
13
|
- if previous_post or next_post
|
14
14
|
.navigation
|
@@ -17,9 +17,9 @@
|
|
17
17
|
- if previous_post
|
18
18
|
%li
|
19
19
|
Previous:
|
20
|
-
%a.next{:href => "#{
|
20
|
+
%a.next{:href => "#{previous_post.url}", :title => "#{previous_post.title}"}= "#{previous_post.title}"
|
21
21
|
|
22
22
|
- if next_post
|
23
23
|
%li
|
24
24
|
Next:
|
25
|
-
%a.next{:href => "#{
|
25
|
+
%a.next{:href => "#{next_post.url}", :title => "#{next_post.title}"}= "#{next_post.title}"
|
@@ -3,7 +3,7 @@
|
|
3
3
|
%ul
|
4
4
|
- posts.each do |post|
|
5
5
|
%li
|
6
|
-
%span.date= post
|
7
|
-
%a.title{:href => "#{options[:url]}/#{post
|
6
|
+
%span.date= post.created_at.strftime('%Y-%m-%d')
|
7
|
+
%a.title{:href => "#{options[:url]}/#{post.filename[:generated]}", :title => post.title}= post.title
|
8
8
|
%li
|
9
|
-
%a{:href => "#{options[:url]}/posts/
|
9
|
+
%a{:href => "#{options[:url]}/posts/index.html", :title => "All posts"} more
|
@@ -6,10 +6,10 @@
|
|
6
6
|
%link= options[:url]
|
7
7
|
- posts.each do |post|
|
8
8
|
%item
|
9
|
-
%title= post
|
10
|
-
%link= "#{options[:url]}/#{post
|
11
|
-
%guid= "#{options[:url]}/#{post
|
12
|
-
%pubDate= Time.parse(post
|
9
|
+
%title= post.title
|
10
|
+
%link= "#{options[:url]}/#{post.filename[:generated]}"
|
11
|
+
%guid= "#{options[:url]}/#{post.filename[:generated]}"
|
12
|
+
%pubDate= Time.parse(post.created_at.to_s).rfc822
|
13
13
|
%description
|
14
14
|
:cdata
|
15
|
-
#{post
|
15
|
+
#{post.summary}
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 6
|
8
|
-
-
|
9
|
-
version: 0.6.
|
8
|
+
- 1
|
9
|
+
version: 0.6.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Owen Griffin
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-29 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -115,6 +115,34 @@ dependencies:
|
|
115
115
|
version: 0.1.4
|
116
116
|
type: :runtime
|
117
117
|
version_requirements: *id007
|
118
|
+
- !ruby/object:Gem::Dependency
|
119
|
+
name: net-ssh
|
120
|
+
prerelease: false
|
121
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
segments:
|
126
|
+
- 2
|
127
|
+
- 0
|
128
|
+
- 21
|
129
|
+
version: 2.0.21
|
130
|
+
type: :runtime
|
131
|
+
version_requirements: *id008
|
132
|
+
- !ruby/object:Gem::Dependency
|
133
|
+
name: net-sftp
|
134
|
+
prerelease: false
|
135
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
segments:
|
140
|
+
- 2
|
141
|
+
- 0
|
142
|
+
- 4
|
143
|
+
version: 2.0.4
|
144
|
+
type: :runtime
|
145
|
+
version_requirements: *id009
|
118
146
|
description: A static web site generator.
|
119
147
|
email: owen.griffin@gmail.com
|
120
148
|
executables:
|
@@ -124,14 +152,14 @@ extensions: []
|
|
124
152
|
|
125
153
|
extra_rdoc_files:
|
126
154
|
- LICENSE
|
127
|
-
- README.html
|
128
155
|
- README.md
|
129
156
|
files:
|
130
157
|
- lib/who-needs-wp.rb
|
158
|
+
- lib/who-needs-wp/Content.rb
|
131
159
|
- lib/who-needs-wp/Sidebar.rb
|
160
|
+
- lib/who-needs-wp/content/Page.rb
|
161
|
+
- lib/who-needs-wp/content/Post.rb
|
132
162
|
- lib/who-needs-wp/css.rb
|
133
|
-
- lib/who-needs-wp/pages.rb
|
134
|
-
- lib/who-needs-wp/posts.rb
|
135
163
|
- lib/who-needs-wp/sidebar/delicious.rb
|
136
164
|
- lib/who-needs-wp/sidebar/pageindex.rb
|
137
165
|
- lib/who-needs-wp/sidebar/recentposts.rb
|
@@ -153,7 +181,6 @@ files:
|
|
153
181
|
- lib/who-needs-wp/templates/rss.haml
|
154
182
|
- lib/who-needs-wp/templates/twitter.haml
|
155
183
|
- LICENSE
|
156
|
-
- README.html
|
157
184
|
- README.md
|
158
185
|
has_rdoc: true
|
159
186
|
homepage: http://github.com/owengriffin/who-needs-wp
|
data/README.html
DELETED
@@ -1,132 +0,0 @@
|
|
1
|
-
<h1>who-needs-wp</h1>
|
2
|
-
|
3
|
-
<p><em>Who needs Wordpress?</em></p>
|
4
|
-
|
5
|
-
<p>The majority of web sites are consumed. Visitors will stumble upon the site, read a few pages (if you're lucky) and then disappear. Normally for every visitor to the site each webpage is generated dynamically. Each visitor has their own version of the web page for that particular moment of time. Is this really necessary? How often does the content on the web site you are visiting change?</p>
|
6
|
-
|
7
|
-
<p>Take blogs for example. I have a blog written using the excellent Wordpress software. I'm able to write posts within Wordpress and see them appear on the web site without leaving my web browser. My posts are held in a database, when a user requests to view my blog multiple requests are made to the database to build a dynamic page on which contents rarely changes. I create a new blog post every 3 weeks, it seems a bit unnecessary to generate a web page when the content hasn't changed.</p>
|
8
|
-
|
9
|
-
<p>There is another option. Instead of generating the web site dynamically when the page is requested I can generate the web page whenever the content changes. So whenever I create a new post - I regenerate the site. </p>
|
10
|
-
|
11
|
-
<p>This has the advantage of serving web pages faster; I use less hosting space; and I cut any unnecessary features which Wordpress provides.</p>
|
12
|
-
|
13
|
-
<p>The main disadvantage is that user's aren't able to comment on my posts - but this don't matter too much - nobody ever did! ;-)</p>
|
14
|
-
|
15
|
-
<h2>Getting Started</h2>
|
16
|
-
|
17
|
-
<p>who-needs-wp is a small Ruby program which helps generate static web sites. To start using who-needs-wp you need to install Ruby. On Ubuntu enter the following into a command prompt:</p>
|
18
|
-
|
19
|
-
<pre><code>sudo apt-get install ruby ruby-dev rubygems
|
20
|
-
</code></pre>
|
21
|
-
|
22
|
-
<p>You then need to install who-needs-wp by running the following:</p>
|
23
|
-
|
24
|
-
<pre><code>sudo gem install who-needs-wp
|
25
|
-
</code></pre>
|
26
|
-
|
27
|
-
<p>Ensure that Ruby gems is in your <code>PATH</code> variable by opening <code>~/.bashrc</code> and entering:</p>
|
28
|
-
|
29
|
-
<pre><code>export PATH=/var/lib/gems/1.8/bin:$PATH
|
30
|
-
</code></pre>
|
31
|
-
|
32
|
-
<p>You'll need to re-load the <code>.bashrc</code> file by using the following command:</p>
|
33
|
-
|
34
|
-
<pre><code>. ~/.bashrc
|
35
|
-
</code></pre>
|
36
|
-
|
37
|
-
<p>Now create a folder which will host your web site</p>
|
38
|
-
|
39
|
-
<pre><code>mkdir /var/www/website/
|
40
|
-
</code></pre>
|
41
|
-
|
42
|
-
<p>who-needs-wp stores posts in the <code>posts/</code> folder followed by a folder representing the date of the post. i.e. <code>posts/year/month/day</code>.</p>
|
43
|
-
|
44
|
-
<p>Create an example post by creating a folder and creating a Markdown file.</p>
|
45
|
-
|
46
|
-
<pre><code>mkdir /var/www/website/posts/2010/03/15/ --parents
|
47
|
-
gedit /var/www/website/posts/2010/03/15/An_example_post.markdown
|
48
|
-
</code></pre>
|
49
|
-
|
50
|
-
<p>The filename will be used as the title for the page - all the underscores will be replaced with spaces.</p>
|
51
|
-
|
52
|
-
<p>Along with <a href="http://daringfireball.net/projects/markdown/syntax">Markdown Syntax</a> you can also specify the author of the blog post within the file:</p>
|
53
|
-
|
54
|
-
<pre><code>Author: Your Name
|
55
|
-
</code></pre>
|
56
|
-
|
57
|
-
<p>Before it can generate the site who-needs-wp needs to be configured. Copy the following into <code>/var/www/website/.who-needs-wp.yaml</code></p>
|
58
|
-
|
59
|
-
<pre><code>---
|
60
|
-
:url: /website/test
|
61
|
-
:title: An example blog
|
62
|
-
:author: Your Name
|
63
|
-
</code></pre>
|
64
|
-
|
65
|
-
<p>These are the properties which are used to generate the website:</p>
|
66
|
-
|
67
|
-
<ul>
|
68
|
-
<li><code>url</code> - The base URL of the website</li>
|
69
|
-
<li><code>title</code> - A title for the index of your site</li>
|
70
|
-
<li><code>author</code> - When a author is not specified within the post this author is displayed</li>
|
71
|
-
</ul>
|
72
|
-
|
73
|
-
<p>Now you can generate your site:</p>
|
74
|
-
|
75
|
-
<pre><code>who-needs-wp .
|
76
|
-
</code></pre>
|
77
|
-
|
78
|
-
<p>And view the blog at the following URL:</p>
|
79
|
-
|
80
|
-
<pre><code>http://localhost/website/
|
81
|
-
</code></pre>
|
82
|
-
|
83
|
-
<h2>Overriding Templates</h2>
|
84
|
-
|
85
|
-
<p>You will probably find that the templates used by who-needs-wp don't quite match your requirements. You can override any of the templates by creating a <code>templates</code> folder. You can copy the existing templates from the gem as a starting point. The templates are stored within the <code>/var/lib/gems/1.8/gems/who-needs-wp-0.1.0/lib/who-needs-wp/templates/</code>. </p>
|
86
|
-
|
87
|
-
<h2>Applying alternative styles</h2>
|
88
|
-
|
89
|
-
<p>You can specify an additional stylesheet by using the <code>-s</code> or <code>--stylesheet</code> option to the who-needs-wp command.</p>
|
90
|
-
|
91
|
-
<h2>Twitter</h2>
|
92
|
-
|
93
|
-
<p>who-needs-wp can place a <a href="http://twitter.com/">Twitter</a> stream in the side bar. This can either be a search or an individual user's feed.</p>
|
94
|
-
|
95
|
-
<p>Modifying <code>.who-needs-wp.yaml</code> and add:</p>
|
96
|
-
|
97
|
-
<pre><code>:twitter:
|
98
|
-
:user: <your twitter user>
|
99
|
-
:search: <your twitter search>
|
100
|
-
</code></pre>
|
101
|
-
|
102
|
-
<h2>Delicious</h2>
|
103
|
-
|
104
|
-
<p>who-needs-wp can also display a list of bookmarks from <a href="http://del.icio.us/">Delicious</a>. Modify <code>.who-needs-wp.yaml</code> and add:</p>
|
105
|
-
|
106
|
-
<pre><code>:delicious:
|
107
|
-
:user: <your delicious username>
|
108
|
-
</code></pre>
|
109
|
-
|
110
|
-
<h2>Google Analytics</h2>
|
111
|
-
|
112
|
-
<p>To enable Google Analytics you need to specify your web property ID in <code>.who-needs-wp.yaml</code>. For example:</p>
|
113
|
-
|
114
|
-
<pre><code>:google_analytics: UA-XXXXXXXX
|
115
|
-
</code></pre>
|
116
|
-
|
117
|
-
<h2>Syntax Highlighting</h2>
|
118
|
-
|
119
|
-
<p>who-needs-wp will syntax highlight your code snippets using <a href="http://github.com/nakajima/makers-mark">Makers-Mark</a> and <a href="http://pygments.org/">Pygments</a></p>
|
120
|
-
|
121
|
-
<h2>Migration from Wordpress</h2>
|
122
|
-
|
123
|
-
<p>Packaged with who-needs-wp is a simple script called wordpress2wnwp which aids migrating from Wordpress. wordpress2wnwp exports posts from a MySQL database and outputs them in the who-needs-wp filing structure. It also generates Apache2 <code>RewriteRule</code>s which rewrite any Wordpress URLs to who-needs-wp.</p>
|
124
|
-
|
125
|
-
<p>To find more information on wordpress2wnwp enter the following command:</p>
|
126
|
-
|
127
|
-
<pre><code>wordpress2wnwp -h
|
128
|
-
</code></pre>
|
129
|
-
|
130
|
-
<h3>Copyright</h3>
|
131
|
-
|
132
|
-
<p>Copyright (c) 2010 Owen Griffin. See LICENSE for details.</p>
|
data/lib/who-needs-wp/pages.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
|
2
|
-
module WhoNeedsWP
|
3
|
-
def self.load_pages
|
4
|
-
@pages = []
|
5
|
-
Dir.glob('pages/*.markdown').each do |filename|
|
6
|
-
@logger.debug "Loading page #{filename}"
|
7
|
-
match = filename.match(/.*\/([^\.]*)/)
|
8
|
-
@pages << {
|
9
|
-
:filename => {
|
10
|
-
:original => filename,
|
11
|
-
:generated => File.dirname(filename) + "/" + File.basename(filename, ".markdown") + ".html"
|
12
|
-
},
|
13
|
-
:title => match[1].gsub(/_/, ' ')
|
14
|
-
}
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.get_pages
|
19
|
-
@pages
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.generate_pages
|
23
|
-
@pages.each do |page|
|
24
|
-
|
25
|
-
markdown = File.read(page[:filename][:original])
|
26
|
-
|
27
|
-
page[:author] = @options[:author]
|
28
|
-
|
29
|
-
match = markdown.match(/^[aA]uthor: (.*)$/o)
|
30
|
-
if match
|
31
|
-
page[:author] = match[1]
|
32
|
-
# Remove the author from the post text
|
33
|
-
markdown.gsub! /^[aA]uthor: .*$/, ''
|
34
|
-
end
|
35
|
-
|
36
|
-
# post[:markdown] = RDiscount.new(markdown, :smart, :generate_toc).to_html
|
37
|
-
page[:markdown] = MakersMark.generate(markdown)
|
38
|
-
page[:html] = @template['page'].render(Object.new, {
|
39
|
-
:page => page,
|
40
|
-
:title => page[:title],
|
41
|
-
:options => @options
|
42
|
-
})
|
43
|
-
# Render the page as HTML
|
44
|
-
self.render_html(page[:filename][:generated], "page", page[:html], page[:title])
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
data/lib/who-needs-wp/posts.rb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
|
2
|
-
module WhoNeedsWP
|
3
|
-
def self.load_posts
|
4
|
-
@posts = []
|
5
|
-
Dir.glob('posts/**/*.markdown').each do |filename|
|
6
|
-
@logger.debug "Loading post #{filename}"
|
7
|
-
match = filename.match(/([0-9]{4})\/([0-9]{2})\/([0-9]{2})\/([^\.]*)/)
|
8
|
-
date = DateTime.new(match[1].to_i, match[2].to_i, match[3].to_i)
|
9
|
-
generated_filename = File.dirname(filename) + "/" + File.basename(filename, ".markdown") + ".html"
|
10
|
-
post = {
|
11
|
-
:filename => {
|
12
|
-
:original => filename,
|
13
|
-
:generated => generated_filename,
|
14
|
-
},
|
15
|
-
:title => match[4].gsub(/_/, ' '),
|
16
|
-
:created_at => date
|
17
|
-
}
|
18
|
-
# Generate a unique post ID to be used in the Atom feed
|
19
|
-
post[:id] = "#{@options[:url]}#{generated_filename}".gsub(/http:\/\//, 'tag:')
|
20
|
-
match = post[:id].match(/([^\/]*)\/(.*)/)
|
21
|
-
post[:id] = "#{match[1]},#{date.strftime('%Y-%m-%d')}:#{match[2]}" if match
|
22
|
-
# Append the post to the global list of posts
|
23
|
-
@posts << post
|
24
|
-
end
|
25
|
-
# Sort the posts, newest first
|
26
|
-
@posts.sort! { |a, b| a[:created_at] <=> b[:created_at] }
|
27
|
-
@posts.reverse!
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.get_posts
|
31
|
-
return @posts
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.rss(filename, limit=10)
|
35
|
-
file = File.open(filename, "w")
|
36
|
-
file.write @template['rss'].render(Object.new, {
|
37
|
-
:posts => @posts[0..limit],
|
38
|
-
:options => @options
|
39
|
-
})
|
40
|
-
file.close
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.atom(filename, limit=10)
|
44
|
-
file = File.open(filename, "w")
|
45
|
-
file.write @template['atom'].render(Object.new, {
|
46
|
-
:posts => @posts[0..limit],
|
47
|
-
:options => @options
|
48
|
-
})
|
49
|
-
file.close
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.generate_posts
|
53
|
-
@posts.each_index do |index|
|
54
|
-
# Calculate the previous and next posts
|
55
|
-
post = @posts[index]
|
56
|
-
previous_post = @posts[index + 1] if index + 1 < @posts.length
|
57
|
-
next_post = @posts[index - 1] if index > 1
|
58
|
-
|
59
|
-
# Read the contents of the file
|
60
|
-
markdown = File.read(post[:filename][:original])
|
61
|
-
|
62
|
-
# Specify the default author
|
63
|
-
post[:author] = @options[:author]
|
64
|
-
|
65
|
-
# Check to see if the author of the document is specified with "Author:"
|
66
|
-
match = markdown.match(/^[aA]uthor: (.*)$/o)
|
67
|
-
if match
|
68
|
-
post[:author] = match[1]
|
69
|
-
# Remove the author from the post text
|
70
|
-
markdown.gsub! /^[aA]uthor: .*$/, ''
|
71
|
-
end
|
72
|
-
|
73
|
-
# post[:markdown] = RDiscount.new(markdown, :smart, :generate_toc).to_html
|
74
|
-
post[:markdown] = MakersMark.generate(markdown)
|
75
|
-
post[:html] = @template['post'].render(Object.new, {
|
76
|
-
:post => post,
|
77
|
-
:title => post[:title],
|
78
|
-
:options => @options,
|
79
|
-
:next_post => next_post,
|
80
|
-
:previous_post => previous_post
|
81
|
-
})
|
82
|
-
# Set the summary of the post to be the first paragraph
|
83
|
-
post[:summary] = $1 if post[:html] =~ (/(?:<p>)(.*?)(?:<\/p>)/)
|
84
|
-
|
85
|
-
# Render the post as HTML
|
86
|
-
self.render_html(post[:filename][:generated], "post", post[:html], post[:title])
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|