staticmatic2 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/Gemfile +12 -0
  2. data/Gemfile.lock +27 -0
  3. data/LICENSE +20 -0
  4. data/README.markdown +107 -0
  5. data/Rakefile +45 -0
  6. data/VERSION.yml +5 -0
  7. data/bin/staticmatic +140 -0
  8. data/lib/staticmatic.rb +25 -0
  9. data/lib/staticmatic/base.rb +123 -0
  10. data/lib/staticmatic/compass.rb +5 -0
  11. data/lib/staticmatic/compass/app_integration.rb +18 -0
  12. data/lib/staticmatic/compass/configuration_defaults.rb +44 -0
  13. data/lib/staticmatic/compass/installer.rb +15 -0
  14. data/lib/staticmatic/configuration.rb +20 -0
  15. data/lib/staticmatic/deployers/aws-s3.rb +71 -0
  16. data/lib/staticmatic/deployers/config/amazon.yml +7 -0
  17. data/lib/staticmatic/error.rb +17 -0
  18. data/lib/staticmatic/helpers.rb +12 -0
  19. data/lib/staticmatic/helpers/assets_helper.rb +116 -0
  20. data/lib/staticmatic/helpers/current_path_helper.rb +22 -0
  21. data/lib/staticmatic/helpers/form_helper.rb +23 -0
  22. data/lib/staticmatic/helpers/render_helper.rb +13 -0
  23. data/lib/staticmatic/helpers/tag_helper.rb +35 -0
  24. data/lib/staticmatic/helpers/url_helper.rb +59 -0
  25. data/lib/staticmatic/mixins/build.rb +77 -0
  26. data/lib/staticmatic/mixins/helpers.rb +15 -0
  27. data/lib/staticmatic/mixins/render.rb +153 -0
  28. data/lib/staticmatic/mixins/rescue.rb +12 -0
  29. data/lib/staticmatic/mixins/server.rb +7 -0
  30. data/lib/staticmatic/mixins/setup.rb +16 -0
  31. data/lib/staticmatic/server.rb +86 -0
  32. data/lib/staticmatic/template_error.rb +44 -0
  33. data/lib/staticmatic/templates/rescues/default.haml +7 -0
  34. data/lib/staticmatic/templates/rescues/template.haml +18 -0
  35. data/spec/base_spec.rb +13 -0
  36. data/spec/compass_integration_spec.rb +27 -0
  37. data/spec/helpers/asset_helper_spec.rb +43 -0
  38. data/spec/helpers/custom_helper_spec.rb +18 -0
  39. data/spec/render_spec.rb +44 -0
  40. data/spec/rescue_spec.rb +36 -0
  41. data/spec/sandbox/test_site/config/compass.rb +1 -0
  42. data/spec/sandbox/test_site/config/site.rb +0 -0
  43. data/spec/sandbox/test_site/src/helpers/application_helper.rb +5 -0
  44. data/spec/sandbox/test_site/src/layouts/alternate_layout.haml +3 -0
  45. data/spec/sandbox/test_site/src/layouts/default.haml +7 -0
  46. data/spec/sandbox/test_site/src/layouts/projects.haml +1 -0
  47. data/spec/sandbox/test_site/src/pages/hello_world.erb +1 -0
  48. data/spec/sandbox/test_site/src/pages/index.haml +5 -0
  49. data/spec/sandbox/test_site/src/pages/layout_test.haml +2 -0
  50. data/spec/sandbox/test_site/src/pages/page_one.haml +3 -0
  51. data/spec/sandbox/test_site/src/pages/page_two.haml +2 -0
  52. data/spec/sandbox/test_site/src/pages/page_with_error.haml +5 -0
  53. data/spec/sandbox/test_site/src/pages/page_with_partial_error.haml +3 -0
  54. data/spec/sandbox/test_site/src/partials/menu.haml +1 -0
  55. data/spec/sandbox/test_site/src/partials/partial_with_error.haml +1 -0
  56. data/spec/sandbox/test_site/src/stylesheets/application.sass +5 -0
  57. data/spec/sandbox/test_site/src/stylesheets/css_with_error.sass +5 -0
  58. data/spec/sandbox/test_site/src/stylesheets/nested/a_nested_stylesheet.sass +0 -0
  59. data/spec/sandbox/test_site/src/stylesheets/partials/_forms.sass +2 -0
  60. data/spec/sandbox/test_site/src/stylesheets/sassy.scss +12 -0
  61. data/spec/server_spec.rb +11 -0
  62. data/spec/setup_spec.rb +22 -0
  63. data/spec/spec_helper.rb +14 -0
  64. data/spec/template_error_spec.rb +23 -0
  65. data/staticmatic.gemspec +158 -0
  66. data/website/Gemfile +1 -0
  67. data/website/config/site.rb +17 -0
  68. data/website/site/docs/compass_integration.html +70 -0
  69. data/website/site/docs/getting_started.html +49 -0
  70. data/website/site/docs/helpers.html +22 -0
  71. data/website/site/images/bycurve21.gif +0 -0
  72. data/website/site/images/curve21.jpg +0 -0
  73. data/website/site/images/homepage-build.jpg +0 -0
  74. data/website/site/images/homepage-previewing.jpg +0 -0
  75. data/website/site/images/homepage-templating.jpg +0 -0
  76. data/website/site/stylesheets/ie.css +5 -0
  77. data/website/site/stylesheets/print.css +372 -0
  78. data/website/site/stylesheets/screen.css +488 -0
  79. data/website/src/helpers/content_helper.rb +10 -0
  80. data/website/src/layouts/default.haml +15 -0
  81. data/website/src/pages/development.haml +9 -0
  82. data/website/src/pages/docs/_menu.haml +4 -0
  83. data/website/src/pages/docs/_requires_prerelease.haml +4 -0
  84. data/website/src/pages/docs/compass_integration.haml +54 -0
  85. data/website/src/pages/docs/getting_started.haml +31 -0
  86. data/website/src/pages/docs/helpers.haml +1 -0
  87. data/website/src/pages/index.haml +27 -0
  88. data/website/src/stylesheets/_base.scss +43 -0
  89. data/website/src/stylesheets/_defaults.scss +260 -0
  90. data/website/src/stylesheets/ie.scss +10 -0
  91. data/website/src/stylesheets/print.scss +33 -0
  92. data/website/src/stylesheets/screen.scss +73 -0
  93. metadata +238 -0
@@ -0,0 +1,5 @@
1
+ ["installer", "configuration_defaults", "app_integration"].each do |file|
2
+ require File.join(File.dirname(__FILE__), "compass", file)
3
+ end
4
+
5
+ Compass.add_configuration(:staticmatic)
@@ -0,0 +1,18 @@
1
+
2
+ module Compass
3
+ module AppIntegration
4
+ module Staticmatic
5
+
6
+ extend self
7
+
8
+ def installer(*args)
9
+ Installer.new(*args)
10
+ end
11
+
12
+ def configuration
13
+ Compass::Configuration::Data.new('staticmatic').extend(ConfigurationDefaults)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,44 @@
1
+ module Compass
2
+ module AppIntegration
3
+ module Staticmatic
4
+ module ConfigurationDefaults
5
+ def project_type_without_default
6
+ :staticmatic
7
+ end
8
+
9
+ def http_path
10
+ "/"
11
+ end
12
+
13
+ def sass_dir_without_default
14
+ "src/stylesheets"
15
+ end
16
+
17
+ def javascripts_dir_without_default
18
+ "site/javascripts"
19
+ end
20
+
21
+ def css_dir_without_default
22
+ "site/stylesheets"
23
+ end
24
+
25
+ def images_dir_without_default
26
+ "site/images"
27
+ end
28
+
29
+ def default_http_images_path
30
+ "images"
31
+ end
32
+
33
+ def default_http_javascripts_path
34
+ "javascripts"
35
+ end
36
+
37
+ def default_cache_dir
38
+ ".sass-cache"
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,15 @@
1
+ module Compass
2
+ module AppIntegration
3
+ module Staticmatic
4
+ class Installer < Compass::Installers::ManifestInstaller
5
+ def completed_configuration
6
+ nil
7
+ end
8
+
9
+ def finalize(options = {})
10
+ puts manifest.welcome_message if manifest.welcome_message
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
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
+ attr_accessor :coffee_options
11
+
12
+ def initialize
13
+ self.preview_server_port = 3000
14
+ self.use_extensions_for_page_links = true
15
+ self.sass_options = {}
16
+ self.haml_options = {}
17
+ self.coffee_options = ''
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,71 @@
1
+ require 'aws/s3'
2
+ require 'yaml'
3
+
4
+ class StaticExe < Thor
5
+
6
+ desc "s3_deploy DIRECTORY", "Deploys your static website an Amazon's S3 bucket"
7
+ method_option :env, :type => :string, :aliases => "-e"
8
+ method_option :skip_build, :type => :boolean, :aliases => "-k"
9
+ def s3_deploy(directory = '.')
10
+ return if needs_setup? directory
11
+
12
+ invoke :build, directory unless options[:skip_build]
13
+
14
+ if Dir[site_path(directory,'*')].empty?
15
+ say 'Your build/ folder is empty', :red
16
+ say 'Nothing to do.'
17
+ return
18
+ end
19
+
20
+ say 'Uploading to Amazon S3...', :cyan
21
+ say 'Establishing connection to Amazon S3...'
22
+ amazon_config = YAML::load File.read(amazon_config_path directory)
23
+ AWS::S3::Base.establish_connection!(amazon_config['AccessKeys'])
24
+
25
+ env = options[:env] || 'development'
26
+ bucket_name = amazon_config['Buckets'][env]
27
+
28
+ say "Grabbing #{env} bucket '#{bucket_name}'"
29
+ buckets = AWS::S3::Service.buckets
30
+ unless buckets.map {|b| b.name}.include? bucket_name
31
+ say 'The bucket ', :red
32
+ say "'#{bucket_name}' "
33
+ say 'does not exist!', :red
34
+ say 'Nothing to do.'
35
+ return
36
+ end
37
+
38
+ Dir[site_path(directory,'*')].each do |file|
39
+ contents = File.read file
40
+ s3path = file.sub(%r{^\./build/},'')
41
+
42
+ say " upload ", :cyan; say s3path
43
+ AWS::S3::S3Object.store(s3path, contents, bucket_name, :access => :public_read)
44
+ end
45
+ say 'Done.'
46
+ end
47
+
48
+ private
49
+
50
+ def amazon_config_path(directory)
51
+ File.join(directory, 'config','amazon.yml')
52
+ end
53
+
54
+ def needs_setup?(directory)
55
+ config_file = amazon_config_path(directory)
56
+
57
+ unless File.exists? config_file
58
+ say 'You need an Amazon S3 config file.', :red
59
+ response = ask 'Would you like to generate one now? [Y/n]'
60
+
61
+ if response == '' || response.downcase == 'y'
62
+ copy_file lib_path('deployers/config/amazon.yml'), config_file
63
+ say 'Done.'
64
+ say 'Edit this config file to specify your Amazon S3 access keys, ' +
65
+ 'and then try again.'
66
+ say 'For more information, visit http://aws.amazon.com/s3/'
67
+ end
68
+ return true
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,7 @@
1
+ AccessKeys:
2
+ :access_key_id: Your-access-key-here
3
+ :secret_access_key: Your-secres-access-key-here
4
+
5
+ Buckets:
6
+ development: Your-development-bucket
7
+ production: Your-production-bucket
@@ -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,12 @@
1
+ ["assets", "form", "current_path", "render", "tag", "url"].each do |helper|
2
+ require File.join(File.dirname(__FILE__), "helpers", "#{helper}_helper")
3
+ end
4
+
5
+ module StaticMatic::Helpers
6
+ include TagHelper
7
+ include UrlHelper
8
+ include AssetsHelper
9
+ include FormHelper
10
+ include RenderHelper
11
+ include CurrentPathHelper
12
+ end
@@ -0,0 +1,116 @@
1
+ module StaticMatic
2
+ module Helpers
3
+ module AssetsHelper
4
+ self.extend self
5
+
6
+ # Generates links to all stylesheets in the source directory
7
+ # = stylesheets
8
+ # or specific stylesheets in a specific order
9
+ # = stylesheets :reset, :application
10
+ # Can also pass options hash in at the end so you can specify :media => :print
11
+ def stylesheets(*params)
12
+ options = if params.last.is_a? Hash; params.pop else {} end # clean up
13
+
14
+ options[:media] = 'all' unless options.has_key?(:media)
15
+ options[:rel] = 'stylesheet'; options[:type] = 'text/css'
16
+
17
+ src_files = @staticmatic.src_file_paths('sass','scss','css')
18
+ output = ""
19
+
20
+ if params.length == 0
21
+ # no specified files; include them all!
22
+ src_files.each {|path| output << format_output(:link,path,options) }
23
+ else
24
+ # specific files requested and in a specific order
25
+ params.each do |file|
26
+
27
+ if file.to_s.match %r{^https?://}
28
+ output << format_output(:link,file,options)
29
+ else
30
+ idx = src_files.index do |src|
31
+ %w{sass scss css}.map {|t| src.match /#{file}\.#{t}$/ }.any?
32
+ end
33
+ output << format_output(:link,src_files[idx],options) unless idx.nil?
34
+ end
35
+ end
36
+ end
37
+ output
38
+ end
39
+
40
+ # Generate javascript source tags for the specified files
41
+ #
42
+ # javascripts('test') -> <script language="javascript" src="javascripts/test.js"></script>
43
+ #
44
+ def javascripts(*files)
45
+ options = if files.last.is_a? Hash; files.pop else {} end # clean up
46
+
47
+ options[:language] = 'javascript'
48
+ options[:type] = 'text/javascript'
49
+
50
+ src_files = @staticmatic.src_file_paths('js','coffee')
51
+ output = ""
52
+
53
+ files.each do |path|
54
+ puts "path: #{path}"
55
+ if path.to_s.match %r{^https?://}
56
+ output << format_output(:script,path,options)
57
+ else
58
+ idx = src_files.index do |src|
59
+ %w{coffee js}.map {|t| src.match /#{path.to_s}\.#{t}$/ }.any?
60
+ end
61
+ output << format_output(:script,src_files[idx],options) unless idx.nil?
62
+ end
63
+ end
64
+ output
65
+ end
66
+
67
+ # Generates an image tag always relative to the current page unless absolute path or http url specified.
68
+ #
69
+ # img('test_image.gif') -> <img src="/images/test_image.gif" alt="Test image"/>
70
+ # img('contact/test_image.gif') -> <img src="/images/contact/test_image.gif" alt="Test image"/>
71
+ # img('http://localhost/test_image.gif') -> <img src="http://localhost/test_image.gif" alt="Test image"/>
72
+ def img(name, options = {})
73
+ options[:src] = name.match(%r{^((\.\.?)?/|https?://)}) ? name : "#{current_page_relative_path}images/#{name}"
74
+ options[:alt] ||= name.split('/').last.split('.').first.capitalize.gsub(/_|-/, ' ')
75
+ tag :img, options
76
+ end
77
+
78
+ def format_output(tag_type,path,options)
79
+ external_url = !!path.match(%r{^https?://})
80
+
81
+ if external_url
82
+ src = path
83
+ else
84
+ filename_without_extension = File.basename(path).chomp(File.extname(path))
85
+
86
+ path = path.gsub(/#{@staticmatic.src_dir}/, "").
87
+ gsub(/#{@staticmatic.site_dir}/, "").
88
+ gsub(/#{filename_without_extension}\.(sass|scss|css|js|coffee)/, "")
89
+
90
+ src = File.join(current_page_relative_path, path, "#{filename_without_extension}")
91
+ end
92
+
93
+ if tag_type == :link
94
+ src += '.css' if !external_url
95
+ options[:href] = qstring(src, options[:qstring]); options.delete :qstring
96
+ tag(tag_type,options)
97
+ elsif tag_type == :script
98
+ src += '.js' if !external_url
99
+ options[:src] = qstring(src, options[:qstring]); options.delete :qstring
100
+ tag(tag_type,options) { '' }
101
+ end
102
+
103
+ end
104
+
105
+ # Prepares a query string based on the given qstr.
106
+ # If qstr is true, it generates a query string based on the current time.
107
+ # If qstr is a string, it uses it as the query string itself.
108
+ #
109
+ def qstring(src,qstr)
110
+ src += '?_=' + Time.now.to_i.to_s if qstr == true
111
+ src += '?_=' + qstr if qstr.is_a? String
112
+ src
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,22 @@
1
+ module StaticMatic
2
+ module Helpers
3
+ module CurrentPathHelper
4
+ self.extend self
5
+
6
+ def current_page
7
+ @staticmatic.current_page
8
+ end
9
+
10
+ private
11
+
12
+ def current_page_relative_path(current_path = nil)
13
+ if current_path.nil? || current_path.match(/^((\.\.?)?\/|\#|.+?\:)/) == nil
14
+ current_page_depth = current_page.split('/').length - 2;
15
+ (current_page_depth > 0) ? ([ '..' ] * current_page_depth).join('/') + '/' : ''
16
+ else
17
+ ''
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+
2
+ module StaticMatic
3
+ module Helpers
4
+ module FormHelper
5
+ self.extend self
6
+
7
+ # Generates a form text field
8
+ #
9
+ def text_field(name, value, options = {})
10
+ options.merge!(:type => "text", :name => name, :value => value)
11
+ tag(:input, options)
12
+ end
13
+
14
+
15
+ # Generate a form textarea
16
+ #
17
+ def text_area(name, value, options = {})
18
+ options.merge!(:name => name)
19
+ tag(:textarea, options) { value }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+
2
+ module StaticMatic
3
+ module Helpers
4
+ module RenderHelper
5
+ self.extend self
6
+
7
+ # Include a partial template
8
+ def partial(name, options = {})
9
+ @staticmatic.generate_partial(name, options)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module StaticMatic
2
+ module Helpers
3
+ module TagHelper
4
+ self.extend self
5
+
6
+ # Generates HTML tags:
7
+ #
8
+ # tag(:br) -> <br/>
9
+ # tag(:a, :href => 'test.html') { "Test" } -> <a href="test.html">Test</a>
10
+ #
11
+ def tag(name, options = {}, &block)
12
+ options[:id] ||= options[:name] if options[:name]
13
+ output = "<#{name}"
14
+ options.keys.sort { |a, b| a.to_s <=> b.to_s }.each do |key|
15
+ output << " #{key}=\"#{options[key]}\"" if options[key]
16
+ end
17
+
18
+ if block_given?
19
+ output << ">"
20
+ output << yield
21
+ output << "</#{name}>"
22
+ else
23
+ format = @staticmatic.configuration.haml_options[:format]
24
+
25
+ if format.nil? || format == :xhtml
26
+ output << "/>"
27
+ else
28
+ output << ">"
29
+ end
30
+ end
31
+ output
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,59 @@
1
+ module StaticMatic
2
+ module Helpers
3
+ module UrlHelper
4
+ self.extend self
5
+
6
+ # Generate an HTML link
7
+ #
8
+ # If only the title is passed, it will automatically
9
+ # create a link from this value:
10
+ #
11
+ # link('Test') -> <a href="test.html">Test</a>
12
+ #
13
+ def link(title, href = "", options = {})
14
+ if href.is_a?(Hash)
15
+ options = href
16
+ href = ""
17
+ end
18
+
19
+ if href.nil? || href.strip.length < 1
20
+ path_prefix = ''
21
+ if title.match(/^(\.\.?)?\//)
22
+ # starts with relative path so strip it off and prepend it to the urlified title
23
+ path_prefix_match = title.match(/^[^\s]*\//)
24
+ path_prefix = path_prefix_match[0] if path_prefix_match
25
+ title = title[path_prefix.length, title.length]
26
+ end
27
+ href = path_prefix + urlify(title) + ".html"
28
+ end
29
+
30
+ options[:href] = "#{current_page_relative_path(href)}#{href}"
31
+
32
+ local_page = (options[:href].match(/^(\#|.+?\:)/) == nil)
33
+ unless @staticmatic.configuration.use_extensions_for_page_links || !local_page
34
+ options[:href].chomp!(".html")
35
+ options[:href].chomp!("index") if options[:href][-5, 5] == 'index'
36
+ end
37
+
38
+ tag(:a, options) { title }
39
+ end
40
+ alias link_to link
41
+
42
+ # Generates a URL friendly string from the value passed:
43
+ #
44
+ # "We love Haml" -> "we_love_haml"
45
+ # "Elf & Ham" -> "elf_and_ham"
46
+ # "Stephen's gem" -> "stephens_gem"
47
+ #
48
+ def urlify(string)
49
+ string.tr(" ", "_").
50
+ sub("&", "and").
51
+ sub("@", "at").
52
+ tr("^A-Za-z0-9_", "").
53
+ sub(/_{2,}/, "_").
54
+ downcase
55
+ end
56
+ end
57
+ end
58
+
59
+ end