bdimcheff-staticmatic 0.10.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.
Files changed (48) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +50 -0
  3. data/Rakefile +31 -0
  4. data/VERSION.yml +4 -0
  5. data/bin/staticmatic +23 -0
  6. data/lib/staticmatic.rb +20 -0
  7. data/lib/staticmatic/base.rb +87 -0
  8. data/lib/staticmatic/configuration.rb +18 -0
  9. data/lib/staticmatic/error.rb +17 -0
  10. data/lib/staticmatic/helpers.rb +197 -0
  11. data/lib/staticmatic/mixins/build.rb +46 -0
  12. data/lib/staticmatic/mixins/helpers.rb +15 -0
  13. data/lib/staticmatic/mixins/render.rb +125 -0
  14. data/lib/staticmatic/mixins/rescue.rb +12 -0
  15. data/lib/staticmatic/mixins/server.rb +6 -0
  16. data/lib/staticmatic/mixins/setup.rb +20 -0
  17. data/lib/staticmatic/server.rb +94 -0
  18. data/lib/staticmatic/template_error.rb +40 -0
  19. data/lib/staticmatic/templates/default/application.haml +7 -0
  20. data/lib/staticmatic/templates/default/application.sass +4 -0
  21. data/lib/staticmatic/templates/default/index.haml +1 -0
  22. data/lib/staticmatic/templates/rescues/default.haml +7 -0
  23. data/lib/staticmatic/templates/rescues/template.haml +18 -0
  24. data/test/base_test.rb +13 -0
  25. data/test/helpers_test.rb +12 -0
  26. data/test/render_test.rb +30 -0
  27. data/test/rescue_test.rb +36 -0
  28. data/test/sandbox/test_site/configuration.rb +0 -0
  29. data/test/sandbox/test_site/site/index.html +10 -0
  30. data/test/sandbox/test_site/site/stylesheets/application.css +2 -0
  31. data/test/sandbox/test_site/src/helpers/application_helper.rb +5 -0
  32. data/test/sandbox/test_site/src/layouts/alternate_layout.haml +3 -0
  33. data/test/sandbox/test_site/src/layouts/application.haml +7 -0
  34. data/test/sandbox/test_site/src/layouts/projects.haml +1 -0
  35. data/test/sandbox/test_site/src/pages/hello_world.erb +1 -0
  36. data/test/sandbox/test_site/src/pages/index.haml +5 -0
  37. data/test/sandbox/test_site/src/pages/layout_test.haml +2 -0
  38. data/test/sandbox/test_site/src/pages/page_with_error.haml +5 -0
  39. data/test/sandbox/test_site/src/pages/page_with_partial_error.haml +3 -0
  40. data/test/sandbox/test_site/src/partials/menu.haml +1 -0
  41. data/test/sandbox/test_site/src/partials/partial_with_error.haml +1 -0
  42. data/test/sandbox/test_site/src/stylesheets/application.sass +2 -0
  43. data/test/sandbox/test_site/src/stylesheets/css_with_error.sass +5 -0
  44. data/test/server_test.rb +12 -0
  45. data/test/setup_test.rb +25 -0
  46. data/test/template_error_test.rb +23 -0
  47. data/test/test_helper.rb +20 -0
  48. metadata +128 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (C) 2009 Stephen Bartholomew
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,50 @@
1
+ # StaticMatic
2
+
3
+ *For information on Haml & Sass please see [haml.hamptoncatlin.com](http://haml.hamptoncatlin.com)*.
4
+
5
+ ## What's it all about?
6
+
7
+ CMS is overrated. A lot of the time, clients want us to do what we do
8
+ best - well designed pages with structured, accessible and maintainable markup & styling.
9
+
10
+ CMSs are often perfect for this, but sometimes they can be restrictive and more cumbersome
11
+ than just working with good ol' source code. At the same time we want our code to be
12
+ structured, DRY and flexible.
13
+
14
+ Enter **StaticMatic**.
15
+
16
+ ## Usage
17
+
18
+ StaticMatic will set up a basic site structure for you with this command:
19
+
20
+ staticmatic setup <directory>
21
+
22
+ After this command you'll have the following files:
23
+
24
+ <directory>/
25
+ site/
26
+ images/
27
+ stylesheets/
28
+ javascripts/
29
+ src/
30
+ helpers/
31
+ layouts/
32
+ application.haml
33
+ pages/
34
+ index.haml
35
+ stylesheets/
36
+ application.sass
37
+
38
+ StaticMatic sets you up with a sample layout, stylesheet and page file. Once you've
39
+ edited the pages and stylesheets, you can generate the static site:
40
+
41
+ staticmatic build <directory>
42
+
43
+ All of the pages are parsed and wrapped up in application.haml and put into the site directory.
44
+
45
+ ## Templates
46
+
47
+ StaticMatic adds a few helpers to the core Haml helpers:
48
+
49
+ = link 'Title', 'url'
50
+ = img 'my_image.jpg'
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require "rubygems"
2
+ require "rake"
3
+ require "rake/testtask"
4
+ require File.dirname(__FILE__) + '/lib/staticmatic'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = "staticmatic"
10
+ gem.executables = "staticmatic"
11
+ gem.summary = "Lightweight Static Site Framework"
12
+ gem.email = "steve@curve21.com"
13
+ gem.homepage = "http://staticmatic.net"
14
+ gem.description = "Lightweight Static Site Framework"
15
+ gem.authors = ["Stephen Bartholomew"]
16
+ gem.rubyforge_project = "staticmatic"
17
+
18
+ gem.files = FileList["[A-Z]*", "{bin,lib,test}/**/*"]
19
+
20
+ gem.add_dependency("haml", ">=2.0.0")
21
+ gem.add_dependency("mongrel", ">=1.1.5")
22
+ end
23
+ rescue LoadError
24
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gemgem.github.com"
25
+ end
26
+
27
+ desc "Run all unit tests"
28
+ Rake::TestTask.new(:test) do |t|
29
+ t.test_files = Dir.glob("test/*_test.rb")
30
+ t.verbose = true
31
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 10
4
+ :patch: 1
data/bin/staticmatic ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.dirname(__FILE__) + '/../lib/staticmatic'
4
+
5
+ command = ARGV[0]
6
+ directory = ARGV[1]
7
+
8
+ if !command || !directory
9
+ puts "Usage: #{$0} <build|setup|preview> <directory>"
10
+ exit
11
+ end
12
+
13
+ configuration = StaticMatic::Configuration.new
14
+
15
+ config_file = "#{directory}/src/configuration.rb"
16
+
17
+ if File.exists?(config_file)
18
+ config = File.read(config_file)
19
+ eval(config)
20
+ end
21
+
22
+ staticmatic = StaticMatic::Base.new(directory, configuration)
23
+ staticmatic.run(command)
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'haml'
3
+ require 'sass'
4
+ require 'mongrel'
5
+ require 'fileutils'
6
+
7
+ module StaticMatic
8
+ VERSION = '0.10.2'
9
+ end
10
+
11
+ ["render", "build", "setup", "server", "helpers", "rescue"].each do |mixin|
12
+ require File.join(File.dirname(__FILE__), "staticmatic", "mixins", mixin)
13
+ end
14
+
15
+ ["base", "configuration", "error", "server", "helpers", "template_error"].each do |lib|
16
+ require File.join(File.dirname(__FILE__), "staticmatic", lib)
17
+ end
18
+
19
+ Haml::Helpers.class_eval("include StaticMatic::Helpers")
20
+
@@ -0,0 +1,87 @@
1
+ module StaticMatic
2
+ # Directories generated for a new site setup
3
+ BASE_DIRS = %w{
4
+ site/
5
+ site/stylesheets
6
+ site/images
7
+ site/javascripts
8
+ src/
9
+ src/pages/
10
+ src/layouts
11
+ src/stylesheets
12
+ src/helpers
13
+ }
14
+
15
+ # Templates for setup and their location
16
+ TEMPLATES = {
17
+ 'application.haml' => 'layouts',
18
+ 'application.sass' => 'stylesheets',
19
+ 'index.haml' => 'pages'
20
+ }
21
+
22
+ class Base
23
+
24
+ include StaticMatic::RenderMixin
25
+ include StaticMatic::BuildMixin
26
+ include StaticMatic::SetupMixin
27
+ include StaticMatic::HelpersMixin
28
+ include StaticMatic::ServerMixin
29
+ include StaticMatic::RescueMixin
30
+
31
+ attr_accessor :configuration
32
+ attr_reader :current_page, :src_dir, :site_dir
33
+
34
+ def current_file
35
+ @current_file_stack[0] || ""
36
+ end
37
+
38
+ def initialize(base_dir, configuration = Configuration.new)
39
+ @configuration = configuration
40
+ @current_page = nil
41
+ @current_file_stack = []
42
+ @base_dir = base_dir
43
+ @src_dir = "#{@base_dir}/src"
44
+ @site_dir = "#{@base_dir}/site"
45
+ @templates_dir = File.dirname(__FILE__) + '/templates/default/'
46
+ @layout = "application"
47
+ @scope = Object.new
48
+ @scope.instance_variable_set("@staticmatic", self)
49
+ load_helpers
50
+ end
51
+
52
+ def base_dir
53
+ @base_dir
54
+ end
55
+
56
+ def run(command)
57
+ if %w(build setup preview).include?(command)
58
+ send(command)
59
+ else
60
+ puts "#{command} is not a valid StaticMatic command"
61
+ end
62
+ end
63
+
64
+ # TODO: DRY this _exists? section up
65
+ def template_exists?(name, dir = '')
66
+ File.exists?(File.join(@src_dir, 'pages', dir, "#{name}.haml")) || File.exists?(File.join(@src_dir, 'stylesheets', dir, "#{name}.sass"))
67
+ end
68
+
69
+ def layout_exists?(name)
70
+ File.exists? full_layout_path(name)
71
+ end
72
+
73
+ def template_directory?(path)
74
+ File.directory?(File.join(@src_dir, 'pages', path))
75
+ end
76
+
77
+ def full_layout_path(name)
78
+ "#{@src_dir}/layouts/#{name}.haml"
79
+ end
80
+
81
+ class << self
82
+ def base_dirs
83
+ StaticMatic::BASE_DIRS
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,18 @@
1
+ module StaticMatic
2
+ class Configuration
3
+ attr_accessor :preview_server_port
4
+
5
+ attr_accessor :preview_server_host
6
+
7
+ attr_accessor :use_extensions_for_page_links
8
+ attr_accessor :sass_options
9
+ attr_accessor :haml_options
10
+
11
+ def initialize
12
+ self.preview_server_port = 3000
13
+ self.use_extensions_for_page_links = true
14
+ self.sass_options = {}
15
+ self.haml_options = {}
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module StaticMatic
2
+ class Error < StandardError
3
+ attr_reader :line
4
+
5
+ attr_reader :filename
6
+
7
+ def initialize(lineno, filename, message)
8
+ @line = lineno
9
+ @filename = filename
10
+ @message = message
11
+ end
12
+
13
+ def message
14
+ "#{@filename}, line #{@line}: #{@message}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,197 @@
1
+ module StaticMatic
2
+ module Helpers
3
+ self.extend self
4
+
5
+ # Generates links to all stylesheets in the source directory
6
+ # = stylesheets
7
+ # or specific stylesheets in a specific order
8
+ # = stylesheets :reset, :application
9
+ # Can also pass options hash in at the end so you can specify :media => :print
10
+ def stylesheets(*params)
11
+ options = {}
12
+ if params.last.is_a?(Hash)
13
+ options = params.last
14
+ params.slice!(-1, 1)
15
+ end
16
+ options[:media] = 'all' unless options.has_key?(:media)
17
+ options[:rel] = 'stylesheet'; options[:type] = 'text/css'
18
+
19
+ relative_path = current_page_relative_path
20
+
21
+ output = ""
22
+ if params.length == 0
23
+ # no specific files requested so include all in no particular order
24
+ stylesheet_dir = File.join(@staticmatic.src_dir, 'stylesheets')
25
+ stylesheet_directories = Dir[File.join(stylesheet_dir, '**','*.sass')]
26
+
27
+ # Bit of a hack here - adds any stylesheets that exist in the site/ dir that haven't been generated from source sass
28
+ Dir[File.join(@staticmatic.site_dir, 'stylesheets', '*.css')].each do |filename|
29
+ search_filename = File.basename(filename).chomp(File.extname(filename))
30
+
31
+ already_included = false
32
+ stylesheet_directories.each do |path|
33
+ if File.basename(path).include?(search_filename)
34
+ already_included = true
35
+ break
36
+ end
37
+ end
38
+
39
+ stylesheet_directories << filename unless already_included
40
+ end
41
+
42
+ stylesheet_directories.each do |path|
43
+ filename_without_extension = File.basename(path).chomp(File.extname(path))
44
+
45
+ options[:href] = "#{relative_path}stylesheets/#{filename_without_extension}.css"
46
+ output << tag(:link, options)
47
+ end
48
+ else
49
+ #specific files requested and in a specific order
50
+ params.each do |file|
51
+ if File.exist?(File.join(@staticmatic.src_dir, 'stylesheets', "#{file}.sass")) ||
52
+ File.exist?(File.join(@staticmatic.site_dir, 'stylesheets', "#{file}.css"))
53
+ options[:href] = "#{relative_path}stylesheets/#{file}.css"
54
+ output << tag(:link, options)
55
+ end
56
+ end
57
+ end
58
+
59
+ output
60
+ end
61
+
62
+ # Generate javascript source tags for the specified files
63
+ #
64
+ # javascripts('test') -> <script language="javascript" src="javascripts/test.js"></script>
65
+ #
66
+ def javascripts(*files)
67
+ relative_path = current_page_relative_path
68
+
69
+ output = ""
70
+ files.each do |file|
71
+ file_str = file.to_s
72
+ src = file_str.match(%r{^((\.\.?)?/|https?://)}) ? file_str : "#{relative_path}javascripts/#{file_str}.js"
73
+ output << tag(:script, :language => 'javascript', :src => src, :type => "text/javascript") { "" }
74
+ end
75
+ output
76
+ end
77
+
78
+ # Generates a form text field
79
+ #
80
+ def text_field(name, value, options = {})
81
+ options.merge!(:type => "text", :name => name, :value => value)
82
+ tag(:input, options)
83
+ end
84
+
85
+ # Generate a form textarea
86
+ #
87
+ def text_area(name, value, options = {})
88
+ options.merge!(:name => name)
89
+ tag(:textarea, options) { value }
90
+ end
91
+
92
+ # Generate an HTML link
93
+ #
94
+ # If only the title is passed, it will automatically
95
+ # create a link from this value:
96
+ #
97
+ # link('Test') -> <a href="test.html">Test</a>
98
+ #
99
+ def link(title, href = "", options = {})
100
+ if href.is_a?(Hash)
101
+ options = href
102
+ href = ""
103
+ end
104
+
105
+ if href.nil? || href.strip.length < 1
106
+ path_prefix = ''
107
+ if title.match(/^(\.\.?)?\//)
108
+ # starts with relative path so strip it off and prepend it to the urlified title
109
+ path_prefix_match = title.match(/^[^\s]*\//)
110
+ path_prefix = path_prefix_match[0] if path_prefix_match
111
+ title = title[path_prefix.length, title.length]
112
+ end
113
+ href = path_prefix + urlify(title) + ".html"
114
+ end
115
+
116
+ options[:href] = "#{current_page_relative_path(href)}#{href}"
117
+
118
+ local_page = (options[:href].match(/^(\#|.+?\:)/) == nil)
119
+ unless @staticmatic.configuration.use_extensions_for_page_links || !local_page
120
+ options[:href].chomp!(".html")
121
+ options[:href].chomp!("index") if options[:href][-5, 5] == 'index'
122
+ end
123
+
124
+ tag(:a, options) { title }
125
+ end
126
+ alias link_to link
127
+
128
+ # Generates an image tag always relative to the current page unless absolute path or http url specified.
129
+ #
130
+ # img('test_image.gif') -> <img src="/images/test_image.gif" alt="Test image"/>
131
+ # img('contact/test_image.gif') -> <img src="/images/contact/test_image.gif" alt="Test image"/>
132
+ # img('http://localhost/test_image.gif') -> <img src="http://localhost/test_image.gif" alt="Test image"/>
133
+ def img(name, options = {})
134
+ options[:src] = name.match(%r{^((\.\.?)?/|https?://)}) ? name : "#{current_page_relative_path}images/#{name}"
135
+ options[:alt] ||= name.split('/').last.split('.').first.capitalize.gsub(/_|-/, ' ')
136
+ tag :img, options
137
+ end
138
+
139
+ # Generates HTML tags:
140
+ #
141
+ # tag(:br) -> <br/>
142
+ # tag(:a, :href => 'test.html') { "Test" } -> <a href="test.html">Test</a>
143
+ #
144
+ def tag(name, options = {}, &block)
145
+ options[:id] ||= options[:name] if options[:name]
146
+ output = "<#{name}"
147
+ options.keys.sort { |a, b| a.to_s <=> b.to_s }.each do |key|
148
+ output << " #{key}=\"#{options[key]}\"" if options[key]
149
+ end
150
+
151
+ if block_given?
152
+ output << ">"
153
+ output << yield
154
+ output << "</#{name}>"
155
+ else
156
+ output << "/>"
157
+ end
158
+ output
159
+ end
160
+
161
+ # Generates a URL friendly string from the value passed:
162
+ #
163
+ # "We love Haml" -> "we_love_haml"
164
+ # "Elf & Ham" -> "elf_and_ham"
165
+ # "Stephen's gem" -> "stephens_gem"
166
+ #
167
+ def urlify(string)
168
+ string.tr(" ", "_").
169
+ sub("&", "and").
170
+ sub("@", "at").
171
+ tr("^A-Za-z0-9_", "").
172
+ sub(/_{2,}/, "_").
173
+ downcase
174
+ end
175
+
176
+ # Include a partial template
177
+ def partial(name, options = {})
178
+ @staticmatic.generate_partial(name, options)
179
+ end
180
+
181
+ def current_page
182
+ @staticmatic.current_page
183
+ end
184
+
185
+ private
186
+
187
+ def current_page_relative_path(current_path = nil)
188
+ if current_path.nil? || current_path.match(/^((\.\.?)?\/|\#|.+?\:)/) == nil
189
+ current_page_depth = current_page.split('/').length - 2;
190
+ (current_page_depth > 0) ? ([ '..' ] * current_page_depth).join('/') + '/' : ''
191
+ else
192
+ ''
193
+ end
194
+ end
195
+
196
+ end
197
+ end