bloggit 1.0.3 → 1.0.7

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/History CHANGED
@@ -1,3 +1,32 @@
1
+ == 1.0.7 / 2003-04-02
2
+
3
+ * Experimental JSON Mongrel handler...
4
+ * Tagged as version 1.0.7
5
+ [2008-04-02 20:24:55 -0500]
6
+ * Absolute paths are availables for every link_to (uses the base_path from config)
7
+ * RSS feeds generate absolute paths now
8
+ * Post#to_yaml fixes
9
+ * Sub-folders are globbed when looking for pages and/or posts
10
+ * Added support for fetching latest posts that include, or exclude, a specified tag
11
+ * Experimental embedded server
12
+ * Fixed verbosity to actually honor the commandline
13
+ * Exposed 'path_to_root' in Page rendering context
14
+ [2007-10-27 12:53:04 -0500]
15
+ * Added 'content' to variable to context for pages and posts
16
+ * Updated version number
17
+ [2007-10-27 11:39:14 -0500]
18
+ * Updated gem manifest and the create_manifest task
19
+ * Added a .gitignore file for this project
20
+ [2007-10-23 21:38:52 -0500]
21
+ * Added JS Search plugin to test.blog fixture and boilerplate code.
22
+ * FIX: No longer dies when the $/media folder is missing
23
+ * Updated version number to 1.0.4
24
+ [2007-10-23 21:36:42 -0500]
25
+ * Added JS Search plugin to test.blog fixture and boilerplate code.
26
+ * FIX: No longer dies when the $/media folder is missing
27
+ * Updated version number to 1.0.4
28
+
29
+
1
30
  == 1.0.0 / 2007-03-15
2
31
 
3
32
  * Initial release!
data/Manifest CHANGED
@@ -13,6 +13,8 @@ lib/bloggit.rb
13
13
  lib/bloggit/boilerplate/Rakefile
14
14
  lib/bloggit/boilerplate/pages/about.page
15
15
  lib/bloggit/boilerplate/plugins/haloscan/init.rb
16
+ lib/bloggit/boilerplate/plugins/js_search/init.rb
17
+ lib/bloggit/boilerplate/plugins/js_search/scripts/search-engine.js
16
18
  lib/bloggit/boilerplate/settings.yml
17
19
  lib/bloggit/boilerplate/themes/default/styles/main.css
18
20
  lib/bloggit/boilerplate/themes/default/templates/archive.rhtml
@@ -396,6 +398,7 @@ test/fixtures/test.blog/pages/todo.page
396
398
  test/fixtures/test.blog/plugins/example/init.rb
397
399
  test/fixtures/test.blog/plugins/haloscan/init.rb
398
400
  test/fixtures/test.blog/plugins/js_search/init.rb
401
+ test/fixtures/test.blog/plugins/js_search/scripts/search-engine.js
399
402
  test/fixtures/test.blog/plugins/rdoc_formatter/init.rb
400
403
  test/fixtures/test.blog/posts/2004.03.07_to-boldly-go.post
401
404
  test/fixtures/test.blog/posts/2007.03.25_sure-whatever.post
data/ReadMe CHANGED
@@ -7,8 +7,10 @@
7
7
 
8
8
  Bloggit is a desktop blog generator.
9
9
 
10
+ You can find the source at: http://repo.or.cz/w/bloggit.git
10
11
 
11
- == FEATURES/PROBLEMS:
12
+
13
+ == FEATURES:
12
14
 
13
15
  * Static generation of blog
14
16
  * Tags
@@ -47,7 +49,7 @@ If you have a publish target defined, you can publish using Rake as well:
47
49
 
48
50
  (The MIT License)
49
51
 
50
- Copyright (c) 2007 Matthew McCray
52
+ Copyright (c) 2007-2008 Matthew McCray
51
53
 
52
54
  Permission is hereby granted, free of charge, to any person obtaining
53
55
  a copy of this software and associated documentation files (the
data/Todo CHANGED
@@ -10,7 +10,9 @@ format: Markdown
10
10
  * Base page folder setting ( defaults to `'.'` )
11
11
  * Abstract content types (page, post, media)
12
12
  * Cleanup error messages, application-wide
13
- * Convert to MERB-style template names `filename.type.processor`. For example: `home.html.erb`
13
+ * Glob files so sub-directories are scanned
14
+ * Convert to MERB-style template names `filename.processor.type`. For example: `home.erb.page`. If a processor type is given, then it's processed via that utility.
15
+ * (Page|Post).find_by_tag(s)
14
16
 
15
17
  ## Completed
16
18
 
@@ -8,7 +8,7 @@ require 'active_support'
8
8
  require 'builder'
9
9
 
10
10
  module Bloggit
11
- RELEASE_INFO = [1, 0, 3]
11
+ RELEASE_INFO = [1, 0, 7]
12
12
  VERSION = RELEASE_INFO.join('.')
13
13
  end
14
14
 
@@ -1,5 +1,23 @@
1
1
  # This is required automatically..
2
2
 
3
- Bloggit::Plugin.define :haloscan do |conf|
4
-
3
+ Bloggit::Plugin.register :haloscan do |settings|
4
+ $username = settings.fetch('username', '')
5
5
  end
6
+
7
+ Bloggit::Template.register_tag :haloscan do |*args|
8
+ type, slug = args
9
+ case type
10
+
11
+ when :comments
12
+ %Q|<a href="javascript:HaloScan('#{slug}');" target="_self"><script type="text/javascript">postCount('#{slug}');</script></a>|
13
+
14
+ when :trackbacks
15
+ %Q|<a href="javascript:HaloScanTB('#{slug}');" target="_self"><script type="text/javascript">postCountTB('#{slug}'); </script></a>|
16
+
17
+ when :script
18
+ %Q|<script type="text/javascript" src="http://www.haloscan.com/load/#{$username}"> </script>|
19
+
20
+ else
21
+ 'WHAT ELSE?'
22
+ end
23
+ end
@@ -0,0 +1,69 @@
1
+ # This is required automatically..
2
+
3
+ Bloggit::Plugin.register :js_search do |settings|
4
+
5
+ end
6
+
7
+ Bloggit::Template.register_tag :js_search do |*args|
8
+ type, label = args
9
+ label ||= 'Search'
10
+ path = Bloggit::Template.current_template
11
+ case type
12
+
13
+ when :form
14
+ %Q|<form id="search-form" action="#" method="GET" onsubmit="Search.query(document.getElementById('q').value);return false;"><input class="search-query" type="search" name="q" id="q" placeholder=""/><input class="search-button" type="submit" value="#{label}"/></form>|
15
+
16
+ when :script
17
+ %Q|<script src="#{path.url_for :script=>'search-engine'}"></script><script>Search.index_uri='#{path.url_for :script=>'keyword-index'}';</script>|
18
+ else
19
+ '?'
20
+ end
21
+ end
22
+
23
+ NOISE_WORDS = %w(about after all also an and another any are as at be because been before
24
+ being between both but by came can come could did do each for from get
25
+ got has had he have her here him himself his how if in into is it like
26
+ make many me might more most much must my never now of on only or other
27
+ our out over said same see should since some still such take than that
28
+ the their them then there these they this those through to too under up
29
+ very was way we well were what where which while who with would you your a
30
+ b c d e f g h i j k l m n o p q r s t u v w x y z $ 1 2 3 4 5 6 7 8 9 0 _)
31
+
32
+ Bloggit::on_event(:after_generate) do |site, cache_dir|
33
+ puts "Generating search index..."
34
+
35
+ index_data = {
36
+ :count=>0,
37
+ :pages=>[]
38
+ }
39
+
40
+ site.pages.each do |page|
41
+ msg = page.source.downcase
42
+ total_words = msg.split(' ').length
43
+ words = msg.gsub!( /[\W|_]/, ' ' ).split(' ')
44
+ words.uniq!
45
+ words.delete_if {|word| NOISE_WORDS.include?( word ) }
46
+ # TODO: Add path key that's the path from ROOT...
47
+ index_data[:pages] << { :title=>page.title, 'url'=>site.absolute_path_to(page), 'keywords'=>words.join(' '), :type=>'page' }
48
+ puts " #{words.length.to_s.rjust(3,' ')}/#{total_words.to_s.ljust(3,' ')} - #{page.title} (page)"
49
+ end
50
+
51
+ site.posts.each do |post|
52
+ msg = post.source.downcase
53
+ msg += " #{post.tags.join(' ')} #{post.title}"
54
+ total_words = msg.split(' ').length
55
+ words = msg.gsub!( /[\W|_]/, ' ' ).split(' ')
56
+ words.uniq!
57
+ words.delete_if {|word| NOISE_WORDS.include?( word ) }
58
+ # TODO: Add path key that's the path from ROOT...
59
+ index_data[:pages] << { :title=>post.title, 'url'=>site.absolute_path_to(post), 'keywords'=>words.join(' '), :type=>'post' }
60
+ puts " #{words.length.to_s.rjust(3,' ')}/#{total_words.to_s.ljust(3,' ')} - #{post.title} (post)"
61
+ end
62
+
63
+ index_data[:count] = index_data[:pages].length
64
+ File.open( File.join(cache_dir, 'theme', 'scripts', 'keyword-index.js'), 'w') do |f|
65
+ f.write index_data.to_json
66
+ end
67
+
68
+ FileUtils.cp File.join(site.base_path, 'plugins', 'js_search', 'scripts', 'search-engine.js'), File.join(cache_dir, 'theme', 'scripts', 'search-engine.js')
69
+ end
@@ -0,0 +1,71 @@
1
+ // Simple Keyword Search Engine
2
+ //
3
+ // Usage:
4
+ // Search.query(keyword) - returns array of matched pages
5
+
6
+ window.Search = {
7
+ index_uri :'keyword-index.js', // Path to the keyword-index
8
+ _idx :null,
9
+
10
+ query :function(q) {
11
+ try {
12
+ this.fetch_index();
13
+
14
+ var re = new RegExp(q, 'gi');
15
+ var results = [];
16
+
17
+ for(var i=0; i<this._idx.pages.length; i++) {
18
+ var page = this._idx.pages[i];
19
+ if( re.test(page.keywords) ) {
20
+ results.push( page );
21
+ }
22
+ }
23
+
24
+ this._onSearchComplete(results, q);
25
+ return results;
26
+ } catch (err) {
27
+ // If something went wrong... punt!
28
+ this._onError(err);
29
+ }
30
+ },
31
+
32
+ onFetchIndex :function(callback) {
33
+ this._onFetchIndex = callback;
34
+ },
35
+ _onFetchIndex :function(complete){},
36
+
37
+ onSearchComplete :function(callback) {
38
+ this._onSearchComplete = callback;
39
+ },
40
+ _onSearchComplete: function(results, q){ },
41
+
42
+ onError :function(callback) {
43
+ this._onError = callback;
44
+ },
45
+ _onError: function(err){ alert(err.message || err.description || err); },
46
+
47
+ fetch_index :function() {
48
+ if(this._idx == null) {
49
+ this._onFetchIndex(false);
50
+ var xhr = this.get_xhr();
51
+ xhr.open("GET", this.index_uri, false); // Synchronous loading...
52
+ xhr.send("");
53
+ eval("window.Search._idx = "+ xhr.responseText);
54
+ this._onFetchIndex(true);
55
+ }
56
+ },
57
+ get_xhr :function() {
58
+ return this.one_of_these(
59
+ function() {return new XMLHttpRequest()},
60
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
61
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
62
+ );
63
+ },
64
+ one_of_these :function() {
65
+ var returnValue;
66
+ for (var i=0; i<arguments.length; i++) {
67
+ try { returnValue = arguments[i](); break; } catch (ignore) {};
68
+ }
69
+ return returnValue;
70
+ }
71
+ }
@@ -1,2 +1,111 @@
1
- <p>One moment...</p>
2
- <script>setTimeout("location.href='/main'", 2000);</script>
1
+ <html>
2
+ <head>
3
+ <title><%= site.title %> :: Bloggit</title>
4
+ <style>
5
+ HTML, BODY {
6
+ font: normal 12px Verdana;
7
+ margin: 0; padding: 0;
8
+ border: 0 none;
9
+ overflow: hidden;
10
+ height: 100%;
11
+ }
12
+ </style>
13
+ <link rel="stylesheet" type="text/css" href="/scripts/resources/css/ext-all.css" />
14
+ <script type="text/javascript" src="/scripts/adapter/jquery/jquery.js"></script>
15
+ <script type="text/javascript" src="/scripts/adapter/jquery/jquery-plugins.js"></script>
16
+ <script type="text/javascript" src="/scripts/adapter/jquery/ext-jquery-adapter.js"></script>
17
+ <script type="text/javascript" src="/scripts/ext-all.js"></script>
18
+ <script type="text/javascript" src="/scripts/app.js"></script>
19
+ <style>
20
+ .x-layout-panel-south, x-layout-panel-north {
21
+ background-color: #c9defa !important;
22
+ }
23
+ </style>
24
+ </head>
25
+ <body>
26
+ <div id="container">
27
+ <div id="tab-pages">
28
+ <div id="pages-tb">
29
+ + New Page,
30
+ - Delete (selected)
31
+ </div>
32
+ <div id="pages-grid">
33
+ Pages Grid
34
+ </div>
35
+ <div>Splitter?</div>
36
+ <div>Content Editor</div>
37
+ <div>Extra Info? (tags, title, slug, etc)</div>
38
+ </div>
39
+ <div id="tab-posts">
40
+ <div id="posts-tb"></div>
41
+ <div id="posts-grid" style="height:500">
42
+ Posts Grid
43
+ </div>
44
+ <div>
45
+ Splitter?
46
+ </div>
47
+ <div>
48
+ Content Editor (title, slug, publish data, status, etc)
49
+ </div>
50
+ </div>
51
+ <div id="tab-themes">
52
+ <div id="themes-tb">
53
+ + New Theme
54
+ </div>
55
+ <div>
56
+ Theme Tree
57
+ </div>
58
+ <div>
59
+ Theme Editor
60
+ </div>
61
+ </div>
62
+ <div id="tab-plugins">
63
+ <div id="plugins-tb">
64
+ + New Plugin,
65
+ - Disable (selected)
66
+ </div>
67
+ <div>
68
+ Plugin Tree
69
+ </div>
70
+ <div>
71
+ Plugin Editor
72
+ </div>
73
+ </div>
74
+ <div id="tab-media">
75
+ <div id="media-tb">
76
+ + New Media,
77
+ - Delete (selected)
78
+ </div>
79
+ <div>
80
+ Media Tree View
81
+ </div>
82
+ <div>
83
+ Media Preview (?)
84
+ </div>
85
+ </div>
86
+ <div id="tab-settings">
87
+ Settings
88
+ </div>
89
+ <div id="tab-preview">
90
+ <div id="preview-tb">
91
+ @ Refresh,
92
+ # Regenerate
93
+ </div>
94
+ <div>
95
+ Preview IFRAME
96
+ </div>
97
+ </div>
98
+ <div id="site-header">
99
+ Bloggit <%= Bloggit::VERSION %>
100
+ </div>
101
+ <div id="home-page">
102
+ At your service, my dear.
103
+ </div>
104
+ <div id="status-bar">
105
+ Ready.
106
+ </div>
107
+ </div>
108
+ </body>
109
+ </html>
110
+ <!-- <p>One moment...</p>
111
+ <script>setTimeout("location.href='/main'", 2000);</script> -->
@@ -97,12 +97,12 @@ Bloggit = (function(){
97
97
  }
98
98
 
99
99
  var cm = new Ext.grid.ColumnModel([
100
- {header: "Title", width: 180, dataIndex: 'title', id:'title', renderer:titleRenderer},
100
+ {header: "Title", width: 300, dataIndex: 'title', id:'title', renderer:titleRenderer},
101
101
  {header: "Status", width: 115, dataIndex: 'status'},
102
102
  {header: "Format", width: 100, dataIndex: 'format'},
103
103
  {header: "Publish Date", width: 100, dataIndex: 'publish_date'},
104
104
  ]);
105
- cm.defaultSortable = true;
105
+ cm.defaultSortable = true;
106
106
 
107
107
  dsPosts.load();
108
108
  // create the grid
@@ -33,7 +33,7 @@ module Bloggit
33
33
  opt.on("--verbose", "Be verbose when outputting info") {|t| Bloggit::Cmdline.verbose = true }
34
34
  end
35
35
 
36
- #puts "Loading commands from #{File.join( File.dirname(__FILE__), 'commands', '*.rb')} (#{Bloggit::Cmdline.verbose})"
36
+ puts "Loading commands from #{File.join( File.dirname(__FILE__), 'commands', '*.rb')} (#{Bloggit::Cmdline.verbose})"
37
37
  Dir[ File.join( File.dirname(__FILE__), 'commands', '*.rb') ].each do |command|
38
38
  require command
39
39
  end
@@ -74,7 +74,7 @@ module Bloggit
74
74
 
75
75
  puts_if_verbose "Copying media files..."
76
76
  media_root = File.join(site.base_path, 'media')
77
- FileUtils.cp_r media_root, cache_dir, :verbose=>false
77
+ FileUtils.cp_r media_root, cache_dir, :verbose=>false if File.exists?(media_root)
78
78
 
79
79
  puts_if_verbose "Copying '#{site.theme}' theme files..."
80
80
  create_folder 'theme'
@@ -123,6 +123,7 @@ module Bloggit
123
123
 
124
124
  def gen_post(post)
125
125
  ctx = {
126
+ 'content' => post,
126
127
  'post' => post,
127
128
  'site' => @site
128
129
  }
@@ -134,6 +135,7 @@ module Bloggit
134
135
 
135
136
  def gen_page(page)
136
137
  ctx = {
138
+ 'content' => page,
137
139
  'page' => page,
138
140
  'site' => @site
139
141
  }
@@ -238,6 +240,7 @@ module Bloggit
238
240
  def gen_atom_feed(posts, io_obj)
239
241
  tmpl = Template.from_text('')
240
242
  Template.folder_depth = 0
243
+ Template.force_absolute_path = true
241
244
 
242
245
  xml = Builder::XmlMarkup.new( :target=>io_obj, :indent=>2 )
243
246
  #xml.instruct! 'xml-stylesheet', :href=>'/stylesheets/atom.css', :type=>'text/css'
@@ -269,12 +272,14 @@ module Bloggit
269
272
  end
270
273
  end
271
274
  end
275
+
276
+ Template.force_absolute_path = false
272
277
  end
273
278
 
274
279
  def gen_rss_feed(posts, io_obj)
275
280
  tmpl = Template.from_text('')
276
281
  Template.folder_depth = 0
277
-
282
+ Template.force_absolute_path = true
278
283
  xml = Builder::XmlMarkup.new( :target=>io_obj, :indent=>2 )
279
284
  xml.instruct! :xml, :version=>"1.0"
280
285
  xml.rss(:version=>"2.0"){
@@ -295,6 +300,8 @@ module Bloggit
295
300
  end
296
301
  }
297
302
  }
303
+ Template.force_absolute_path = false
304
+
298
305
  end
299
306
 
300
307
  private
@@ -27,7 +27,7 @@ module Bloggit
27
27
  end
28
28
 
29
29
  class << self
30
- private :new
30
+ #private :new
31
31
 
32
32
  # Creates a Media object from an image on the filesystem
33
33
  def from_file(path, site)
@@ -73,6 +73,14 @@ module Bloggit
73
73
  class << self
74
74
  private :new
75
75
 
76
+ def find_by_tag(tag)
77
+ find_by_tags( [tag] )
78
+ end
79
+
80
+ def find_by_tags(tags=[])
81
+
82
+ end
83
+
76
84
  def from_file(path, site=nil)
77
85
  path = File.expand_path(path)
78
86
  raise "File must exist" unless File.exists?( path )
@@ -12,11 +12,10 @@ module Bloggit
12
12
  include Test::Unit::Assertions
13
13
 
14
14
  class << self
15
- attr_reader :site
15
+ attr_reader :site, :plugins
16
16
 
17
17
  def init(site) #:nodoc:
18
18
  @site = site
19
-
20
19
  @plugins = {}
21
20
  # Load/require plugins from plugins/ dir...
22
21
  @plugin_path = File.join(site.base_path, 'plugins')
@@ -35,8 +34,7 @@ module Bloggit
35
34
 
36
35
  def register(plugin_name, opts={}, &block)
37
36
  # Yeah...
38
- @plugins[plugin_name]
39
- block.call( settings_for(plugin_name) )
37
+ @plugins[plugin_name] = block.call( settings_for(plugin_name) )
40
38
  end
41
39
 
42
40
  def settings_for(plugin_name)
@@ -46,6 +44,11 @@ module Bloggit
46
44
  def active_site
47
45
  @site
48
46
  end
47
+
48
+ def [](key)
49
+ @plugins[key]
50
+ end
51
+
49
52
  end
50
53
  end
51
54
 
@@ -108,8 +108,7 @@ module Bloggit
108
108
  end
109
109
 
110
110
  def to_yaml
111
- data_hash = prepare_data
112
- yml_s = data_hsh.to_yaml
111
+ yml_s = prepare_data.to_yaml
113
112
  yml_s << @source.to_yaml
114
113
  end
115
114
 
@@ -31,7 +31,7 @@ module Bloggit
31
31
  @pages = []
32
32
  @page_hsh = {}
33
33
  @inactive_pages = []
34
- Dir[ File.join(base_path, 'pages', '*.page') ].each do |page_path|
34
+ Dir.glob( File.join(base_path, 'pages', '**', '*.page') ).each do |page_path|
35
35
  page = Page.from_file(page_path, self)
36
36
  if page.is_publishable?
37
37
  @pages << page
@@ -49,7 +49,7 @@ module Bloggit
49
49
  @posts = []
50
50
  @inactive_posts = []
51
51
  @post_hsh = {}
52
- Dir[ File.join(base_path, 'posts', '*.post') ].each do |post_path|
52
+ Dir.glob( File.join(base_path, 'posts', '**', '*.post') ).each do |post_path|
53
53
  post = Post.from_file(post_path, self)
54
54
  if post.is_publishable?
55
55
  @posts << post
@@ -65,7 +65,7 @@ module Bloggit
65
65
 
66
66
  # Load Media... (?)
67
67
  @media = {}
68
- Dir[ File.join(base_path, 'media', '**', '*') ].each do |media_path|
68
+ Dir.glob( File.join(base_path, 'media', '**', '*') ).each do |media_path|
69
69
  unless FileTest.directory?(media_path)
70
70
  media_item = Media.from_file(media_path, self)
71
71
  @media[ media_item.relative_path ] = media_item
@@ -107,6 +107,30 @@ module Bloggit
107
107
  limit = @settings.syndication.fetch('number_of_entries', 10) if limit.nil?
108
108
  @posts[0..limit]
109
109
  end
110
+
111
+ def latest_posts_excluding_tag(limit=nil, tag=nil)
112
+ limit = @settings.syndication.fetch('number_of_entries', 10) if limit.nil?
113
+ latest = @posts.select do |post|
114
+ if post.has_tags? && !post.tags.include?(tag)
115
+ true
116
+ else
117
+ false
118
+ end
119
+ end
120
+ latest[0..limit]
121
+ end
122
+
123
+ def latest_posts_with_tag(limit=nil, tag=nil)
124
+ limit = @settings.syndication.fetch('number_of_entries', 10) if limit.nil?
125
+ latest = @posts.select do |post|
126
+ if post.has_tags? && post.tags.include?(tag)
127
+ true
128
+ else
129
+ false
130
+ end
131
+ end
132
+ latest[0..limit]
133
+ end
110
134
 
111
135
  def absolute_path_to(obj)
112
136
  case obj.class.to_s
@@ -4,6 +4,18 @@ require 'bloggit'
4
4
  desc "Runs the (Browser) client"
5
5
  task :client do
6
6
  # This is ugly -- find a better way!
7
- `open http://127.0.0.1:3322`
8
- Bloggit::Server.run()
7
+ fork do
8
+ Bloggit::Server.run()
9
+ end
10
+
11
+ # A pathetic hack to delay for a fraction of second the starting of the browser...
12
+ 1000000.times {|i| i.to_s }
13
+
14
+ begin
15
+ `open http://127.0.0.1:3322`
16
+ rescue
17
+ # This may fail ???
18
+ end
19
+
20
+ Process.wait
9
21
  end
@@ -2,13 +2,15 @@
2
2
  require 'rake'
3
3
  require 'bloggit'
4
4
 
5
+ VERBOSE = true unless defined?(VERBOSE)
6
+
5
7
  task :default=>:generate
6
8
 
7
9
  desc "Generate static HTML in cache"
8
10
  task :generate=>[:cleanup] do
9
11
  # Generate the HTML site and structure under cache/
10
12
  site = Bloggit::Site.from_file('.') #File.dirname( __FILE__ )
11
- gen = Bloggit::Generator.new(site, true)
13
+ gen = Bloggit::Generator.new(site, VERBOSE)
12
14
  gen.generate_cache
13
15
  end
14
16
 
@@ -16,7 +18,7 @@ desc "Upload cache to target location"
16
18
  task :upload do
17
19
  # Copy/SFTP/FTP site from cache/ to target location defined in settings.yml (?)
18
20
  site = Bloggit::Site.from_file('.') #File.dirname( __FILE__ )
19
- pub = Bloggit::Publisher.new(site, true)
21
+ pub = Bloggit::Publisher.new(site, VERBOSE)
20
22
  pub.upload
21
23
  end
22
24
 
@@ -29,7 +31,7 @@ desc "Removes site cache"
29
31
  task :cleanup do
30
32
  # Kill the files/folders under cache/
31
33
  site = Bloggit::Site.from_file('.', true) #File.dirname( __FILE__ )
32
- pub = Bloggit::Generator.new(site, true)
34
+ pub = Bloggit::Generator.new(site, VERBOSE)
33
35
  pub.cleanup_cache
34
36
  end
35
37
 
@@ -63,47 +63,49 @@ module Bloggit
63
63
  end
64
64
 
65
65
  def url_for(params={})
66
+ absolute = params.fetch(:absolute, false)
67
+
66
68
  if post = params.delete(:post)
67
69
  if post.is_a? String
68
- Template.path_to_root + site.get_post_by_slug(post).permalink
70
+ Template.path_to_root(absolute) + site.get_post_by_slug(post).permalink
69
71
  elsif post.is_a? Post
70
- Template.path_to_root + post.permalink
72
+ Template.path_to_root(absolute) + post.permalink
71
73
  end
72
74
 
73
75
  elsif page = params.delete(:page)
74
76
  if page.is_a? String
75
- Template.path_to_root + site.get_page_by_slug(page).permalink
77
+ Template.path_to_root(absolute) + site.get_page_by_slug(page).permalink
76
78
  elsif page.is_a? Page
77
- Template.path_to_root + page.permalink
79
+ Template.path_to_root(absolute) + page.permalink
78
80
  end
79
81
 
80
82
  elsif tag = params.delete(:tag)
81
83
  if tag.is_a? String
82
- Template.path_to_root + Tag.tag_list[tag].permalink
84
+ Template.path_to_root(absolute) + Tag.tag_list[tag].permalink
83
85
  elsif tag.is_a? Tag
84
- Template.path_to_root + tag.permalink
86
+ Template.path_to_root(absolute) + tag.permalink
85
87
  end
86
88
 
87
89
  elsif media = params.delete(:media)
88
90
  if media.is_a? String
89
- Template.path_to_root + site.media[media].permalink
91
+ Template.path_to_root(absolute) + site.media[media].permalink
90
92
  elsif media.is_a? Media
91
- Template.path_to_root + media.permalink
93
+ Template.path_to_root(absolute) + media.permalink
92
94
  end
93
95
 
94
96
  elsif script = params.delete(:script)
95
97
  script += '.js' unless script.ends_with? '.js'
96
- "#{ Template.path_to_root }theme/scripts/#{ script }"
98
+ "#{ Template.path_to_root(absolute) }theme/scripts/#{ script }"
97
99
 
98
100
  elsif style = params.delete(:style)
99
101
  style += '.css' unless style.ends_with? '.css'
100
- "#{ Template.path_to_root }theme/styles/#{ style }"
102
+ "#{ Template.path_to_root(absolute) }theme/styles/#{ style }"
101
103
 
102
104
  elsif image = params.delete(:image)
103
- "#{ Template.path_to_root }theme/images/#{ image }"
105
+ "#{ Template.path_to_root(absolute) }theme/images/#{ image }"
104
106
 
105
107
  elsif path = params.delete(:from_root)
106
- Template.path_to_root + path
108
+ Template.path_to_root(absolute) + path
107
109
 
108
110
  elsif url = params.delete(:url)
109
111
  url
@@ -111,24 +113,24 @@ module Bloggit
111
113
  end
112
114
  end
113
115
 
114
- def tag_links(obj)
116
+ def tag_links(obj, absolute=false)
115
117
  links = []
116
118
  obj.tags.each do |tag|
117
- links << link_to(tag, :tag=>tag)
119
+ links << link_to(tag, :tag=>tag, :absolute=>absolute)
118
120
  end
119
121
  links
120
122
  end
121
123
 
122
- def url_for_blog
123
- "#{ Template.path_to_root }#{site.build_post_path('index.html')}"
124
+ def url_for_blog(params={})
125
+ "#{ Template.path_to_root(params.fetch(:absolute, false)) }#{site.build_post_path('index.html')}"
124
126
  end
125
127
 
126
- def url_for_home
127
- "#{ Template.path_to_root }index.html"
128
+ def url_for_home(params={})
129
+ "#{ Template.path_to_root(params.fetch(:absolute, false)) }index.html"
128
130
  end
129
131
 
130
- def url_for_feed
131
- "#{ Template.path_to_root }#{site.settings.syndication.filename}"
132
+ def url_for_feed(params={})
133
+ "#{ Template.path_to_root(params.fetch(:absolute, false)) }#{site.settings.syndication.filename}"
132
134
  end
133
135
 
134
136
  def link_to(title, params={})
@@ -166,6 +168,9 @@ module Bloggit
166
168
  link_to image_tag, params
167
169
  end
168
170
 
171
+ def path_to_root(absolute=false)
172
+ Template.path_to_root(absolute)
173
+ end
169
174
 
170
175
  # def link_to_archive(title, params={})
171
176
  # atts = ""
@@ -255,7 +260,7 @@ module Bloggit
255
260
  class << self
256
261
  private :new
257
262
 
258
- attr_accessor :site, :template_dir, :content_parts, :src_path, :current_template, :folder_depth
263
+ attr_accessor :site, :template_dir, :content_parts, :src_path, :current_template, :folder_depth, :force_absolute_path
259
264
 
260
265
  include Test::Unit::Assertions
261
266
 
@@ -266,6 +271,7 @@ module Bloggit
266
271
  @is_ready = true
267
272
  @template_cache = {}
268
273
  @content_parts = {}
274
+ @force_absolute_path = false
269
275
  end
270
276
 
271
277
  # Do not call directly!
@@ -298,8 +304,14 @@ module Bloggit
298
304
  set_content_for(key, value)
299
305
  end
300
306
 
301
- def path_to_root
302
- '../' * @folder_depth
307
+ def path_to_root(absolute_path = false)
308
+ path_to_root = '../' * @folder_depth
309
+ if @force_absolute_path || absolute_path
310
+ root_url = @site.settings.syndication.fetch('base_url', '')
311
+ [root_url, path_to_root].join('/')
312
+ else
313
+ path_to_root
314
+ end
303
315
  end
304
316
 
305
317
  def from_file(path)
@@ -499,7 +499,7 @@ class FixedHoe #:nodoc:
499
499
  files = []
500
500
  Find.find '.' do |path|
501
501
  next unless File.file? path
502
- next if path =~ /\.svn|tmp$|CVS/
502
+ next if path =~ /\.svn|tmp$|CVS|\.git/
503
503
  files << path[2..-1]
504
504
  end
505
505
  files = files.sort.join "\n"
@@ -1,11 +1,10 @@
1
1
  # This is required automatically..
2
- include Bloggit
3
2
 
4
- Plugin.register :haloscan do |settings|
3
+ Bloggit::Plugin.register :haloscan do |settings|
5
4
  $username = settings.fetch('username', '')
6
5
  end
7
6
 
8
- Template.register_tag :haloscan do |*args|
7
+ Bloggit::Template.register_tag :haloscan do |*args|
9
8
  type, slug = args
10
9
  case type
11
10
 
@@ -20,6 +19,5 @@ Template.register_tag :haloscan do |*args|
20
19
 
21
20
  else
22
21
  'WHAT ELSE?'
23
- end
24
-
22
+ end
25
23
  end
@@ -1,51 +1,69 @@
1
- # include Bloggit
2
- #
3
- # # Registering plugin to retrieve settings from settings.yml
4
- # Plugin.register :js_search do |settings|
5
- # $username = settings.fetch('username', '')
6
- # end
7
- #
8
- #
9
- # # Registering custom tags in the template engine
10
- # Template.register_tag :js_search do |*args|
11
- # type, opts = args
12
- # opts ||= {}
13
- #
14
- # case type
15
- # when :form
16
- # %Q|<a href="javascript:HaloScanTB('#{slug}');" target="_self"><script type="text/javascript">postCountTB('#{slug}'); </script></a>|
17
- #
18
- # when :template
19
- # puts opts[:block].call()
20
- #
21
- # when :script
22
- # %Q|<script type="text/javascript" src="http://www.haloscan.com/load/#{settings.fetch('username', '')}"> </script>|
23
- #
24
- # else
25
- # 'WHAT ELSE?'
26
- # end
27
- #
28
- # end
29
- #
30
- # # Responding to application events...
31
- # Bloggit::on_event(:after_generate) do |site, cache_dir|
32
- # puts "Generating search index..."
33
- # # TODO: Copy/create JS Search lib in cache/ ...
34
- # # TODO: Generate index JS file ...
35
- # end
36
- #
37
- #
38
- # # Adding a command line tool...
39
- # Cmdline.register do |cmd, site|
40
- # search_cmd = CmdParse::Command.new( 'search', true, true )
41
- # search_cmd.short_desc = "JS Search Tools (plugin)"
42
- # cmd.add_command( search_cmd )
43
- #
44
- # idx = CmdParse::Command.new( 'index', false )
45
- # idx.short_desc = "Create search index"
46
- # idx.set_execution_block do |args|
47
- # puts "Generating index file(s)..."
48
- # end
49
- #
50
- # search_cmd.add_command( idx )
51
- # end
1
+ # This is required automatically..
2
+
3
+ Bloggit::Plugin.register :js_search do |settings|
4
+
5
+ end
6
+
7
+ Bloggit::Template.register_tag :js_search do |*args|
8
+ type, label = args
9
+ label ||= 'Search'
10
+ path = Bloggit::Template.current_template
11
+ case type
12
+
13
+ when :form
14
+ %Q|<form id="search-form" action="#" method="GET" onsubmit="Search.query(document.getElementById('q').value);return false;"><input class="search-query" type="search" name="q" id="q" placeholder=""/><input class="search-button" type="submit" value="#{label}"/></form>|
15
+
16
+ when :script
17
+ %Q|<script src="#{path.url_for :script=>'search-engine'}"></script><script>Search.index_uri='#{path.url_for :script=>'keyword-index'}';</script>|
18
+ else
19
+ '?'
20
+ end
21
+ end
22
+
23
+ NOISE_WORDS = %w(about after all also an and another any are as at be because been before
24
+ being between both but by came can come could did do each for from get
25
+ got has had he have her here him himself his how if in into is it like
26
+ make many me might more most much must my never now of on only or other
27
+ our out over said same see should since some still such take than that
28
+ the their them then there these they this those through to too under up
29
+ very was way we well were what where which while who with would you your a
30
+ b c d e f g h i j k l m n o p q r s t u v w x y z $ 1 2 3 4 5 6 7 8 9 0 _)
31
+
32
+ Bloggit::on_event(:after_generate) do |site, cache_dir|
33
+ puts "Generating search index..."
34
+
35
+ index_data = {
36
+ :count=>0,
37
+ :pages=>[]
38
+ }
39
+
40
+ site.pages.each do |page|
41
+ msg = page.source.downcase
42
+ total_words = msg.split(' ').length
43
+ words = msg.gsub!( /[\W|_]/, ' ' ).split(' ')
44
+ words.uniq!
45
+ words.delete_if {|word| NOISE_WORDS.include?( word ) }
46
+ # TODO: Add path key that's the path from ROOT...
47
+ index_data[:pages] << { :title=>page.title, 'url'=>site.absolute_path_to(page), 'keywords'=>words.join(' '), :type=>'page' }
48
+ puts " #{words.length.to_s.rjust(3,' ')}/#{total_words.to_s.ljust(3,' ')} - #{page.title} (page)"
49
+ end
50
+
51
+ site.posts.each do |post|
52
+ msg = post.source.downcase
53
+ msg += " #{post.tags.join(' ')} #{post.title}"
54
+ total_words = msg.split(' ').length
55
+ words = msg.gsub!( /[\W|_]/, ' ' ).split(' ')
56
+ words.uniq!
57
+ words.delete_if {|word| NOISE_WORDS.include?( word ) }
58
+ # TODO: Add path key that's the path from ROOT...
59
+ index_data[:pages] << { :title=>post.title, 'url'=>site.absolute_path_to(post), 'keywords'=>words.join(' '), :type=>'post' }
60
+ puts " #{words.length.to_s.rjust(3,' ')}/#{total_words.to_s.ljust(3,' ')} - #{post.title} (post)"
61
+ end
62
+
63
+ index_data[:count] = index_data[:pages].length
64
+ File.open( File.join(cache_dir, 'theme', 'scripts', 'keyword-index.js'), 'w') do |f|
65
+ f.write index_data.to_json
66
+ end
67
+
68
+ FileUtils.cp File.join(site.base_path, 'plugins', 'js_search', 'scripts', 'search-engine.js'), File.join(cache_dir, 'theme', 'scripts', 'search-engine.js')
69
+ end
@@ -0,0 +1,71 @@
1
+ // Simple Keyword Search Engine
2
+ //
3
+ // Usage:
4
+ // Search.query(keyword) - returns array of matched pages
5
+
6
+ window.Search = {
7
+ index_uri :'keyword-index.js', // Path to the keyword-index
8
+ _idx :null,
9
+
10
+ query :function(q) {
11
+ try {
12
+ this.fetch_index();
13
+
14
+ var re = new RegExp(q, 'gi');
15
+ var results = [];
16
+
17
+ for(var i=0; i<this._idx.pages.length; i++) {
18
+ var page = this._idx.pages[i];
19
+ if( re.test(page.keywords) ) {
20
+ results.push( page );
21
+ }
22
+ }
23
+
24
+ this._onSearchComplete(results, q);
25
+ return results;
26
+ } catch (err) {
27
+ // If something went wrong... punt!
28
+ this._onError(err);
29
+ }
30
+ },
31
+
32
+ onFetchIndex :function(callback) {
33
+ this._onFetchIndex = callback;
34
+ },
35
+ _onFetchIndex :function(complete){},
36
+
37
+ onSearchComplete :function(callback) {
38
+ this._onSearchComplete = callback;
39
+ },
40
+ _onSearchComplete: function(results, q){ },
41
+
42
+ onError :function(callback) {
43
+ this._onError = callback;
44
+ },
45
+ _onError: function(err){ alert(err.message || err.description || err); },
46
+
47
+ fetch_index :function() {
48
+ if(this._idx == null) {
49
+ this._onFetchIndex(false);
50
+ var xhr = this.get_xhr();
51
+ xhr.open("GET", this.index_uri, false); // Synchronous loading...
52
+ xhr.send("");
53
+ eval("window.Search._idx = "+ xhr.responseText);
54
+ this._onFetchIndex(true);
55
+ }
56
+ },
57
+ get_xhr :function() {
58
+ return this.one_of_these(
59
+ function() {return new XMLHttpRequest()},
60
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
61
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
62
+ );
63
+ },
64
+ one_of_these :function() {
65
+ var returnValue;
66
+ for (var i=0; i<arguments.length; i++) {
67
+ try { returnValue = arguments[i](); break; } catch (ignore) {};
68
+ }
69
+ return returnValue;
70
+ }
71
+ }
metadata CHANGED
@@ -1,33 +1,79 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: bloggit
5
3
  version: !ruby/object:Gem::Version
6
- version: 1.0.3
7
- date: 2007-10-23 00:00:00 -05:00
8
- summary: A static site generator for a blog with static pages
9
- require_paths:
10
- - lib
11
- email: darthapo@gmail.com
12
- homepage: http://www.mattmccray.com
13
- rubyforge_project: bloggit
14
- description: "== FEATURES/PROBLEMS: * Static generation of blog * Tags * Archives * ERb based layout support * ERb processing in pages/posts * Simple static pages * Comments (via Haloscan) * Searching (using JavaScript) == SYNOPSIS: You can generate the site from the commandline using Rake:"
15
- autorequire:
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 1.0.7
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - M@ McCray
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-04-02 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: RedCloth
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: "0"
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: cmdparse
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
42
+ - !ruby/object:Gem::Dependency
43
+ name: BlueCloth
44
+ version_requirement:
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ - !ruby/object:Gem::Dependency
52
+ name: builder
53
+ version_requirement:
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ - !ruby/object:Gem::Dependency
61
+ name: markaby
62
+ version_requirement:
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ description: "You can find the source at: http://repo.or.cz/w/bloggit.git == FEATURES: * Static generation of blog * Tags * Archives * ERb based layout support * ERb processing in pages/posts * Simple static pages * Comments (via Haloscan) * Searching (using JavaScript) == SYNOPSIS:"
70
+ email: darthapo@gmail.com
71
+ executables:
72
+ - bloggit
73
+ extensions: []
74
+
75
+ extra_rdoc_files: []
76
+
31
77
  files:
32
78
  - History
33
79
  - Manifest
@@ -44,6 +90,8 @@ files:
44
90
  - lib/bloggit/boilerplate/Rakefile
45
91
  - lib/bloggit/boilerplate/pages/about.page
46
92
  - lib/bloggit/boilerplate/plugins/haloscan/init.rb
93
+ - lib/bloggit/boilerplate/plugins/js_search/init.rb
94
+ - lib/bloggit/boilerplate/plugins/js_search/scripts/search-engine.js
47
95
  - lib/bloggit/boilerplate/settings.yml
48
96
  - lib/bloggit/boilerplate/themes/default/styles/main.css
49
97
  - lib/bloggit/boilerplate/themes/default/templates/archive.rhtml
@@ -427,6 +475,7 @@ files:
427
475
  - test/fixtures/test.blog/plugins/example/init.rb
428
476
  - test/fixtures/test.blog/plugins/haloscan/init.rb
429
477
  - test/fixtures/test.blog/plugins/js_search/init.rb
478
+ - test/fixtures/test.blog/plugins/js_search/scripts/search-engine.js
430
479
  - test/fixtures/test.blog/plugins/rdoc_formatter/init.rb
431
480
  - test/fixtures/test.blog/posts/2004.03.07_to-boldly-go.post
432
481
  - test/fixtures/test.blog/posts/2007.03.25_sure-whatever.post
@@ -451,70 +500,31 @@ files:
451
500
  - test/unit/site_test.rb
452
501
  - test/unit/template_test.rb
453
502
  - test/unit/text_formatter_test.rb
454
- test_files: []
455
-
503
+ has_rdoc: true
504
+ homepage: http://www.mattmccray.com
505
+ post_install_message:
456
506
  rdoc_options: []
457
507
 
458
- extra_rdoc_files: []
459
-
460
- executables:
461
- - bloggit
462
- extensions: []
463
-
508
+ require_paths:
509
+ - lib
510
+ required_ruby_version: !ruby/object:Gem::Requirement
511
+ requirements:
512
+ - - ">="
513
+ - !ruby/object:Gem::Version
514
+ version: "0"
515
+ version:
516
+ required_rubygems_version: !ruby/object:Gem::Requirement
517
+ requirements:
518
+ - - ">="
519
+ - !ruby/object:Gem::Version
520
+ version: "0"
521
+ version:
464
522
  requirements: []
465
523
 
466
- dependencies:
467
- - !ruby/object:Gem::Dependency
468
- name: activesupport
469
- version_requirement:
470
- version_requirements: !ruby/object:Gem::Version::Requirement
471
- requirements:
472
- - - ">"
473
- - !ruby/object:Gem::Version
474
- version: 0.0.0
475
- version:
476
- - !ruby/object:Gem::Dependency
477
- name: RedCloth
478
- version_requirement:
479
- version_requirements: !ruby/object:Gem::Version::Requirement
480
- requirements:
481
- - - ">"
482
- - !ruby/object:Gem::Version
483
- version: 0.0.0
484
- version:
485
- - !ruby/object:Gem::Dependency
486
- name: cmdparse
487
- version_requirement:
488
- version_requirements: !ruby/object:Gem::Version::Requirement
489
- requirements:
490
- - - ">"
491
- - !ruby/object:Gem::Version
492
- version: 0.0.0
493
- version:
494
- - !ruby/object:Gem::Dependency
495
- name: BlueCloth
496
- version_requirement:
497
- version_requirements: !ruby/object:Gem::Version::Requirement
498
- requirements:
499
- - - ">"
500
- - !ruby/object:Gem::Version
501
- version: 0.0.0
502
- version:
503
- - !ruby/object:Gem::Dependency
504
- name: builder
505
- version_requirement:
506
- version_requirements: !ruby/object:Gem::Version::Requirement
507
- requirements:
508
- - - ">"
509
- - !ruby/object:Gem::Version
510
- version: 0.0.0
511
- version:
512
- - !ruby/object:Gem::Dependency
513
- name: markaby
514
- version_requirement:
515
- version_requirements: !ruby/object:Gem::Version::Requirement
516
- requirements:
517
- - - ">"
518
- - !ruby/object:Gem::Version
519
- version: 0.0.0
520
- version:
524
+ rubyforge_project: bloggit
525
+ rubygems_version: 1.0.1
526
+ signing_key:
527
+ specification_version: 2
528
+ summary: A static site generator for a blog with static pages
529
+ test_files: []
530
+