who-needs-wp 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -48,7 +48,7 @@ Choice.options do
48
48
  end
49
49
 
50
50
  option :upload do
51
- short '-u'
51
+ short '-p'
52
52
  long '--upload'
53
53
  desc 'Upload the output to an FTP address.'
54
54
  end
@@ -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
- self.load_pages
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
- self.generate_posts
61
- self.generate_pages
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
- self.rss("posts.rss")
66
- self.atom("posts.atom")
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 @posts.length > 0
76
- @posts[0..3].each do |post|
77
- contents << post[:html]
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 << @pages.first[:html]
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
- basename =~ /.*\.markdown$/ or
110
- basename =~ /^.*~$/ or
111
- basename =~ /^\#.*\#$/
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
- # If the file does not exist then create it
132
- begin
133
- status = sftp.stat!(remote_filename)
134
- rescue Net::SFTP::StatusException
135
- @logger.debug "#{remote_filename} does not exist"
136
- sftp.upload!(filename, remote_filename)
137
- sftp.setstat(remote_filename, :permissions => permissions[:file])
138
- next
139
- end
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
- # If the local file has changed then upload it
142
- if File.stat(filename).mtime > Time.at(status.mtime)
143
- @logger.debug "Copying #{filename} to #{remote_filename}"
144
- sftp.upload!(filename, remote_filename)
145
- else
146
- @logger.debug "Skipping #{filename}"
147
- end
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 PageIndex < Sidebar
4
4
  # See Sidebar.render
5
5
  def render
6
- WhoNeedsWP::render_template("pageindex", { :pages => WhoNeedsWP::get_pages })
6
+ WhoNeedsWP::render_template("pageindex", { :pages => WhoNeedsWP::Page.all })
7
7
  end
8
8
  end
9
9
  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::get_posts[0..5] })
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[:created_at].strftime('%Y-%m-%d')
6
- %a.title{:href => "#{options[:url]}/#{post[:filename][:generated]}", :title => post[:title]}= post[:title]
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[: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]}"}/
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[:summary]}
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[:filename][:generated]}"}= page[:title]
4
+ %a{:href => "#{options[:url]}/#{page.filename[:generated]}"}= page.title
5
5
  .author
6
6
  by
7
- = page[:author]
7
+ = page.author
8
8
  .content
9
- ~ page[:markdown]
9
+ ~ page.markdown
@@ -3,4 +3,4 @@
3
3
  %ul
4
4
  - pages.each do |page|
5
5
  %li
6
- %a.title{:href => "#{options[:url]}/#{page[:filename][:generated]}", :title => page[:title]}= page[:title]
6
+ %a.title{:href => "#{options[:url]}/#{page.filename[:generated]}", :title => page.title}= page.title
@@ -1,14 +1,14 @@
1
1
 
2
2
  .post
3
3
  %h2.title
4
- %a{:href => "#{options[:url]}/#{post[:filename][:generated]}"}= post[:title]
4
+ %a{:href => "#{post.url}"}= post.title
5
5
  .date
6
- = post[:created_at].strftime("%B %d, %Y")
6
+ = post.created_at.strftime("%B %d, %Y")
7
7
  .author
8
8
  by
9
- = post[:author]
9
+ = post.author
10
10
  .content
11
- ~ post[:markdown]
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 => "#{options[:url]}/#{previous_post[:filename][:generated]}", :title => "#{previous_post[:title]}"}= "#{previous_post[:title]}"
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 => "#{options[:url]}/#{next_post[:filename][:generated]}", :title => "#{next_post[:title]}"}= "#{next_post[:title]}"
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[:created_at].strftime('%Y-%m-%d')
7
- %a.title{:href => "#{options[:url]}/#{post[:filename][:generated]}", :title => post[:title]}= post[:title]
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/all.html", :title => "All posts"} more
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[: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
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[:summary]}
15
+ #{post.summary}
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 6
8
- - 0
9
- version: 0.6.0
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-28 00:00:00 +00:00
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
@@ -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: &lt;your twitter user&gt;
99
- :search: &lt;your twitter search&gt;
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: &lt;your delicious username&gt;
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>
@@ -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
@@ -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