schreihals 0.0.2 → 0.0.3

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.
@@ -0,0 +1,38 @@
1
+ module Schreihals
2
+ module Helpers
3
+ def find_template(views, name, engine, &block)
4
+ Array(views).each { |v| super(v, name, engine, &block) }
5
+ end
6
+
7
+ def partial(thing, locals = {})
8
+ name = case thing
9
+ when String then thing
10
+ else thing.class.to_s.demodulize.underscore
11
+ end
12
+
13
+ haml :"partials/_#{name}", :locals => { name.to_sym => thing }.merge(locals)
14
+ end
15
+
16
+ def set_page_title(title)
17
+ @page_title = title
18
+ end
19
+
20
+ def link_to(title, thing)
21
+ haml "%a{href: '#{url_for thing}'} #{title}"
22
+ end
23
+
24
+ def url_for(thing, options = {})
25
+ url = thing.respond_to?(:to_url) ? thing.to_url : thing.to_s
26
+ url = "#{settings.blog_url}#{url}" if options[:absolute]
27
+ url
28
+ end
29
+
30
+ def show_disqus?
31
+ settings.disqus_name.present?
32
+ end
33
+
34
+ def production?
35
+ settings.environment.to_sym == :production
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,74 @@
1
+ require 'tilt'
2
+
3
+ module Schreihals
4
+ class Post < Document
5
+ def initialize(*args)
6
+ super
7
+ self.attributes = {
8
+ 'disqus' => true,
9
+ 'status' => 'published',
10
+ 'summary' => nil,
11
+ 'link' => nil,
12
+ 'read_more' => nil,
13
+ 'date' => nil,
14
+ 'title' => nil,
15
+ 'slug' => nil,
16
+ 'disqus_identifier' => file_name
17
+ }.merge(attributes)
18
+
19
+ # extract date and slug from file name, if possible
20
+ if file_name_without_extension =~ /^(\d{4}-\d{1,2}-\d{1,2})-?(.+)$/
21
+ attributes['date'] ||= Date.parse($1)
22
+ attributes['slug'] ||= $2
23
+ else
24
+ attributes['slug'] ||= file_name_without_extension
25
+ end
26
+ end
27
+
28
+ def year
29
+ date.year
30
+ end
31
+
32
+ def month
33
+ date.month
34
+ end
35
+
36
+ def day
37
+ date.day
38
+ end
39
+
40
+ def to_url
41
+ date.present? ? "/#{year}/#{month}/#{day}/#{slug}/" : "/#{slug}/"
42
+ end
43
+
44
+ def disqus?
45
+ disqus && published?
46
+ end
47
+
48
+ def published?
49
+ status == 'published'
50
+ end
51
+
52
+ def post?
53
+ date.present?
54
+ end
55
+
56
+ def page?
57
+ !post?
58
+ end
59
+
60
+ class << self
61
+ def latest(options = {})
62
+ options = {published_only: false}.merge(options)
63
+
64
+ posts = documents.select(&:date)
65
+ posts = posts.select(&:published?) if options[:published_only]
66
+ posts.sort_by(&:date).reverse.first(10)
67
+ end
68
+
69
+ def with_slug(slug)
70
+ documents.detect { |p| p.slug == slug }
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,17 @@
1
+ module Schreihals
2
+ class Static
3
+ def initialize(app, public_dir = './public')
4
+ @file = Rack::File.new(public_dir)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ status, headers, body = @file.call(env)
10
+ if status > 400
11
+ @app.call(env)
12
+ else
13
+ [status, headers, body]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Schreihals
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -0,0 +1 @@
1
+ first_post
@@ -0,0 +1,13 @@
1
+ ---
2
+ title: <%= @title %>
3
+ summary:
4
+ link:
5
+
6
+ # More options:
7
+ #
8
+ # status: draft
9
+ # read_more:
10
+ # disqus: false
11
+ ---
12
+
13
+ <%= @text %>
@@ -0,0 +1,5 @@
1
+ .bundle
2
+ .rbfu-version
3
+ .powenv
4
+ .sass-cache
5
+ tmp
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'schreihals', '~> 0.0.2'
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'schreihals'
4
+
5
+ class MyBlog < Schreihals::App
6
+ set :blog_title, "<%= @name %>"
7
+ set :blog_url, "http://<%= @name %>.info"
8
+ set :blog_description, ""
9
+ set :author_name, "Your Name"
10
+ # set :disqus_name, ""
11
+ # set :google_analytics_id, ""
12
+ end
13
+
14
+ run MyBlog
File without changes
@@ -1,5 +1,4 @@
1
1
  %section
2
- .container
3
- %h2 400 + 4
4
- %p
5
- The document you requested could not be found.
2
+ %h2 400 + 4
3
+ %p
4
+ The document you requested could not be found.
@@ -0,0 +1 @@
1
+ @import 'schreihals';
@@ -1,4 +1,3 @@
1
1
  %section.posts
2
- .container
3
- - @posts.each do |post|
4
- = partial post
2
+ - @posts.each do |post|
3
+ = partial post
@@ -2,19 +2,23 @@
2
2
  %html
3
3
  %head
4
4
  %title= [@page_title, settings.blog_title].compact.join(" | ")
5
- %link{href: '/schreihals.css', media: "screen", rel: "stylesheet", type: "text/css"}
5
+ %meta{ name: "viewport", content: "width=device-width, initial-scale=1.0" }
6
+ %link{ href: '/blog.css', media: "screen", rel: "stylesheet", type: "text/css" }
6
7
  %link{ href: '/atom.xml', title: "Subscribe via Atom Feed", rel: 'alternate', type: 'application/atom+xml' }
7
8
  %body
8
- %header
9
- .container
9
+ .container
10
+ %header
10
11
  %h1
11
12
  = link_to settings.blog_title, '/'
13
+ - if @show_description
14
+ ~ markdown settings.blog_description
12
15
 
13
- = yield
16
+ = yield
14
17
 
15
- %footer
16
- .container
17
- ~ markdown settings.blog_description
18
+ %footer
19
+ ~ markdown settings.footer
18
20
 
19
- - if production? && settings.google_analytics_id.present?
20
- = partial 'google_analytics'
21
+ - if production? && settings.google_analytics_id.present?
22
+ = partial 'google_analytics'
23
+ - if production? && settings.gauges_id.present?
24
+ = partial 'gauges'
@@ -0,0 +1,12 @@
1
+ :javascript
2
+ var _gauges = _gauges || [];
3
+ (function() {
4
+ var t = document.createElement('script');
5
+ t.type = 'text/javascript';
6
+ t.async = true;
7
+ t.id = 'gauges-tracker';
8
+ t.setAttribute('data-site-id', '#{settings.gauges_id}');
9
+ t.src = '//secure.gaug.es/track.js';
10
+ var s = document.getElementsByTagName('script')[0];
11
+ s.parentNode.insertBefore(t, s);
12
+ })();
@@ -4,6 +4,7 @@
4
4
  - show_body ||= complete || !show_summary
5
5
  - show_read_more ||= !complete && post.summary.present?
6
6
  - show_permalink ||= post.post? && !show_read_more
7
+ - show_twitter ||= complete && post.post? && settings.twitter_id.present?
7
8
 
8
9
  %article.post{class: post.status}
9
10
  %header
@@ -27,5 +28,12 @@
27
28
  - if show_body
28
29
  ~ post.to_html
29
30
 
30
- - if show_permalink
31
- %p.permalink= link_to '∞', post
31
+ %footer
32
+ - if show_permalink
33
+ %p.permalink= link_to '∞', post
34
+ - if show_twitter
35
+ .social_media_buttons
36
+ - if show_twitter
37
+ %a{ href: "https://twitter.com/share", class: "twitter-share-button", data: { via: settings.twitter_id } }
38
+ :javascript
39
+ !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
@@ -1,10 +1,7 @@
1
1
  - set_page_title @post.title.presence
2
2
 
3
- %section.post
4
- .container
5
- = partial @post, complete: true
3
+ = partial @post, complete: true
6
4
 
7
5
  - if show_disqus? && @post.disqus?
8
6
  %section.disqus
9
- .container
10
- = partial 'disqus', :disqus_identifier => @post.disqus_identifier
7
+ = partial 'disqus', :disqus_identifier => @post.disqus_identifier
@@ -1,30 +1,41 @@
1
- @import url(http://fonts.googleapis.com/css?family=Inder|PT+Serif);
1
+ // load stuff!
2
2
  @import 'schnitzelstyle';
3
3
  @import 'schnitzelstyle/coderay';
4
-
5
- $font-default: 16px "PT Serif";
6
- $font-headlines: 15px "Inder";
7
- $font-footer: 11px "Inder";
4
+ @import 'schnitzelstyle/export';
8
5
 
9
6
  @include schnitzel-complete;
7
+ @include schnitzel-export;
10
8
 
11
- section.disqus {
12
- background-color: #eee !important;
9
+ /* misc crap */
10
+ .social_media_buttons {
11
+ margin: 1em 0;
13
12
  }
14
13
 
14
+ /* posts */
15
15
  article.post {
16
- margin: 5em 0;
17
16
  header {
18
- margin-bottom: 1em;
19
- .info { display: inline; margin-left: 1em; color: #999 }
17
+ .info {
18
+ display: inline;
19
+ margin-left: 1em;
20
+ color: #999;
21
+ }
20
22
  }
21
23
 
22
24
  &.draft header h2 { background-color: #ccc; }
23
25
 
24
26
  div.summary p {
25
- font: 18px "Inder";
27
+ font: $font-header;
28
+ font-size: 115%;
26
29
  line-height: 150%;
27
30
  color: #000;
31
+
32
+ @media only screen and (max-width: 640px) {
33
+ line-height: 130%;
34
+
35
+ section.posts & {
36
+ font-size: 100%;
37
+ }
38
+ }
28
39
  }
29
40
 
30
41
  p.permalink {
@@ -35,6 +46,7 @@ article.post {
35
46
  }
36
47
  }
37
48
 
49
+ /* disqus */
38
50
  #dsq-content {
39
51
  a {
40
52
  border: 0;
@@ -43,7 +55,7 @@ article.post {
43
55
  margin-bottom: 2em;
44
56
  }
45
57
  h3 {
46
- margin-top: 1em;
58
+ margin-top: 1em !important;
47
59
  @include clearfix;
48
60
  }
49
61
  }
@@ -15,17 +15,26 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Schreihals::VERSION
17
17
 
18
- gem.add_dependency 'sinatra'
19
- gem.add_dependency 'activesupport'
18
+ gem.add_dependency 'rack', '~> 1.4.0'
19
+ gem.add_dependency 'sinatra', '~> 1.3.2'
20
+ gem.add_dependency 'activesupport', '~> 3.1.0'
20
21
  gem.add_dependency 'shotgun'
21
22
  gem.add_dependency 'haml'
22
23
  gem.add_dependency 'sass'
23
- gem.add_dependency 'document_mapper'
24
24
  gem.add_dependency 'coderay'
25
25
  gem.add_dependency 'redcarpet'
26
26
  gem.add_dependency 'rack-cache'
27
27
  gem.add_dependency 'rack-codehighlighter'
28
- gem.add_dependency 'schnitzelstyle', '>= 0.0.1'
28
+ gem.add_dependency 'schnitzelstyle', '~> 0.0.2'
29
+ gem.add_dependency 'nokogiri'
30
+ gem.add_dependency 'thor'
31
+ gem.add_dependency 'psych'
32
+ gem.add_dependency 'i18n'
33
+ gem.add_dependency 'tilt', '~> 1.3.0'
29
34
 
30
- gem.add_development_dependency 'rspec', '>= 2.0.0'
35
+ gem.add_development_dependency 'rake'
36
+ gem.add_development_dependency 'riot'
37
+ gem.add_development_dependency 'rack-test'
38
+ gem.add_development_dependency 'watchr'
39
+ gem.add_development_dependency 'awesome_print'
31
40
  end
@@ -0,0 +1,68 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MyTestApp < Schreihals::App
4
+ set :documents_source, './test/posts'
5
+ set :blog_title, "A Little Test Blog"
6
+ set :footer, "This is just a test blog. Have fun."
7
+ end
8
+
9
+ context Schreihals::App do
10
+ setup { Rack::MockRequest.new(MyTestApp.new) }
11
+
12
+ context "when loading the home page" do
13
+ setup { topic.get '/' }
14
+
15
+ asserts(:status).equals 200
16
+ asserts(:body).present
17
+ asserts(:content_type).equals 'text/html;charset=utf-8'
18
+ asserts(:body).includes_elements("section.posts article.post", 2)
19
+
20
+ asserts(:body).includes_html('title' => MyTestApp.settings.blog_title)
21
+ asserts(:body).includes_html('.container>footer' => MyTestApp.settings.footer)
22
+ end
23
+
24
+ context "when loading a specific post's page" do
25
+ setup { topic.get '/2011/12/23/first-post/' }
26
+
27
+ asserts(:status).equals 200
28
+ asserts(:body).present
29
+ asserts(:content_type).equals 'text/html;charset=utf-8'
30
+ asserts(:body).includes_elements("article.post", 1)
31
+ asserts(:body).includes_html('article.post header h2 a' => "First Post\.")
32
+ end
33
+
34
+ context "when loading a static page" do
35
+ setup { topic.get '/static-page/' }
36
+
37
+ asserts(:status).equals 200
38
+ asserts(:body).present
39
+ asserts(:content_type).equals 'text/html;charset=utf-8'
40
+ asserts(:body).includes_elements("article.post", 1)
41
+ asserts(:body).includes_html('article.post header h2 a' => "A Static Page\.")
42
+ end
43
+
44
+ context "when loading the ATOM feed" do
45
+ setup { topic.get '/atom.xml' }
46
+
47
+ asserts(:status).equals 200
48
+ asserts(:body).present
49
+ asserts(:content_type).equals 'application/xml+atom'
50
+ asserts(:body).includes_elements("entry", 2)
51
+ end
52
+
53
+ context "when loading a static asset provided by schreihals" do
54
+ setup { topic.get '/favicon.ico' }
55
+
56
+ asserts(:status).equals 200
57
+ asserts(:body).present
58
+ asserts(:content_type).equals 'image/vnd.microsoft.icon'
59
+ end
60
+
61
+ context "when loading an invalid URL" do
62
+ setup { topic.get '/ooga/booga/foo/to/the/bar' }
63
+
64
+ asserts(:status).equals 404
65
+ asserts(:body).present
66
+ asserts(:content_type).equals 'text/html;charset=utf-8'
67
+ end
68
+ end