restart blog by using zero and puma
This commit is contained in:
parent
d6ec7051d7
commit
5e0b87164d
23
Gemfile
23
Gemfile
|
@ -1,21 +1,8 @@
|
|||
source :rubygems
|
||||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rack', '1.3.6'
|
||||
gem 'sinatra'
|
||||
gem 'sinatra-support'
|
||||
gem 'rack-flash'
|
||||
gem 'haml'
|
||||
gem 'puma'
|
||||
gem 'zero', :git => 'https://github.com/libzero/zero.git'
|
||||
gem 'slim'
|
||||
gem 'sass'
|
||||
gem 'compass'
|
||||
gem 'data_mapper'
|
||||
gem 'dm-postgres-adapter'
|
||||
|
||||
# the different markups
|
||||
gem 'redclothcoderay'
|
||||
gem 'coderay'
|
||||
gem 'RedCloth'
|
||||
gem 'redcarpet'
|
||||
|
||||
group :install do
|
||||
gem 'highline'
|
||||
end
|
||||
gem 'kramdown'
|
||||
|
|
111
Gemfile.lock
111
Gemfile.lock
|
@ -1,96 +1,37 @@
|
|||
GEM
|
||||
remote: http://rubygems.org/
|
||||
GIT
|
||||
remote: https://github.com/libzero/zero.git
|
||||
revision: d92dea46954b388ec13bc53c6e4f9894f25863c4
|
||||
specs:
|
||||
RedCloth (4.2.8)
|
||||
addressable (2.2.6)
|
||||
bcrypt-ruby (2.1.4)
|
||||
chunky_png (1.2.5)
|
||||
coderay (1.0.0)
|
||||
compass (0.11.5)
|
||||
zero (0.2.0)
|
||||
tilt
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
chunky_png (1.2.8)
|
||||
compass (0.12.2)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.1)
|
||||
data_mapper (1.1.0)
|
||||
dm-aggregates (= 1.1.0)
|
||||
dm-constraints (= 1.1.0)
|
||||
dm-core (= 1.1.0)
|
||||
dm-migrations (= 1.1.0)
|
||||
dm-serializer (= 1.1.0)
|
||||
dm-timestamps (= 1.1.0)
|
||||
dm-transactions (= 1.1.0)
|
||||
dm-types (= 1.1.0)
|
||||
dm-validations (= 1.1.0)
|
||||
data_objects (0.10.6)
|
||||
addressable (~> 2.1)
|
||||
dm-aggregates (1.1.0)
|
||||
dm-core (~> 1.1.0)
|
||||
dm-constraints (1.1.0)
|
||||
dm-core (~> 1.1.0)
|
||||
dm-core (1.1.0)
|
||||
addressable (~> 2.2.4)
|
||||
dm-do-adapter (1.1.0)
|
||||
data_objects (~> 0.10.2)
|
||||
dm-core (~> 1.1.0)
|
||||
dm-migrations (1.1.0)
|
||||
dm-core (~> 1.1.0)
|
||||
dm-postgres-adapter (1.1.0)
|
||||
dm-do-adapter (~> 1.1.0)
|
||||
do_postgres (~> 0.10.2)
|
||||
dm-serializer (1.1.0)
|
||||
dm-core (~> 1.1.0)
|
||||
fastercsv (~> 1.5.4)
|
||||
json (~> 1.4.6)
|
||||
dm-timestamps (1.1.0)
|
||||
dm-core (~> 1.1.0)
|
||||
dm-transactions (1.1.0)
|
||||
dm-core (~> 1.1.0)
|
||||
dm-types (1.1.0)
|
||||
bcrypt-ruby (~> 2.1.4)
|
||||
dm-core (~> 1.1.0)
|
||||
fastercsv (~> 1.5.4)
|
||||
json (~> 1.4.6)
|
||||
stringex (~> 1.2.0)
|
||||
uuidtools (~> 2.1.2)
|
||||
dm-validations (1.1.0)
|
||||
dm-core (~> 1.1.0)
|
||||
do_postgres (0.10.6)
|
||||
data_objects (= 0.10.6)
|
||||
fastercsv (1.5.4)
|
||||
fssm (0.2.7)
|
||||
haml (3.1.3)
|
||||
highline (1.6.2)
|
||||
json (1.4.6)
|
||||
rack (1.3.3)
|
||||
rack-flash (0.1.2)
|
||||
rack
|
||||
redcarpet (1.17.2)
|
||||
redclothcoderay (0.3.6)
|
||||
RedCloth
|
||||
coderay
|
||||
sass (3.1.7)
|
||||
sinatra (1.2.6)
|
||||
rack (~> 1.1)
|
||||
tilt (>= 1.2.2, < 2.0)
|
||||
sinatra-support (1.2.2)
|
||||
sinatra (>= 1.0)
|
||||
stringex (1.2.2)
|
||||
tilt (1.3.3)
|
||||
uuidtools (2.1.2)
|
||||
fssm (0.2.10)
|
||||
kramdown (1.1.0)
|
||||
puma (2.4.0)
|
||||
rack (>= 1.1, < 2.0)
|
||||
rack (1.5.2)
|
||||
sass (3.2.10)
|
||||
slim (2.0.1)
|
||||
temple (~> 0.6.6)
|
||||
tilt (>= 1.3.3, < 2.1)
|
||||
temple (0.6.6)
|
||||
tilt (1.4.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
RedCloth
|
||||
coderay
|
||||
compass
|
||||
data_mapper
|
||||
dm-postgres-adapter
|
||||
haml
|
||||
highline
|
||||
rack-flash
|
||||
redcarpet
|
||||
redclothcoderay
|
||||
kramdown
|
||||
puma
|
||||
sass
|
||||
sinatra
|
||||
sinatra-support
|
||||
slim
|
||||
zero!
|
||||
|
|
15
README
15
README
|
@ -1,15 +0,0 @@
|
|||
zero-blog
|
||||
=========
|
||||
|
||||
After using jekyll for some time we decided, that it was not what we were looking
|
||||
for. The idea itself was good, but it made writing blogs without a larger screen
|
||||
impossible.
|
||||
|
||||
That's why we write our own blog system now. It stores the posts in a database
|
||||
and will have an admin panel. That way, it's possible to write an entry from the
|
||||
phone too.
|
||||
|
||||
Until now, it does not have many features apart from using datamapper and it
|
||||
will likely not be the blog system you are looking for, without making some
|
||||
changes for yourself, like the structure for the posts or the design. But maybe
|
||||
you can build another system out of it.
|
72
Rakefile
72
Rakefile
|
@ -1,72 +0,0 @@
|
|||
$LOAD_PATH << File.expand_path(File.dirname(__FILE__)) + '/'
|
||||
|
||||
def require_files
|
||||
require 'libs'
|
||||
require 'rake/functions'
|
||||
end
|
||||
|
||||
namespace :dm do
|
||||
desc 'migrate to the database model'
|
||||
task :migrate do
|
||||
require_files
|
||||
require 'dm-migrations'
|
||||
DataMapper.auto_migrate!
|
||||
end
|
||||
|
||||
desc 'upgrade the database to the latest model'
|
||||
task :upgrade do
|
||||
require_files
|
||||
require 'dm-migrations'
|
||||
DataMapper.auto_upgrade!
|
||||
end
|
||||
|
||||
desc 'fill the database with dummy data from seeds.rb'
|
||||
task :seed do
|
||||
require_files
|
||||
require 'seeds'
|
||||
end
|
||||
end
|
||||
|
||||
desc 'open a console with all libs loaded and a database connection opened'
|
||||
task :console do
|
||||
sh "irb -rubygems -I#{File.expand_path(File.dirname(__FILE__))} -r libs"
|
||||
end
|
||||
|
||||
namespace :account do
|
||||
desc 'create a new account'
|
||||
task :create do
|
||||
require_files
|
||||
require 'highline'
|
||||
h = HighLine.new
|
||||
acc = Account.new
|
||||
acc.username = h.ask('username: ')
|
||||
acc.password = h.ask('password: '){|q| q.echo = false }
|
||||
acc.password_confirmation = h.ask('password again: '){|q| q.echo = false }
|
||||
acc.email = h.ask('email: ')
|
||||
acc.role = :admin
|
||||
if acc.save
|
||||
puts "account saved with id #{acc.id}"
|
||||
else
|
||||
puts "failure at saving the account: #{acc.errors.first}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
namespace :import do
|
||||
desc 'import all posts from this directory'
|
||||
task :jekyll do
|
||||
require_files
|
||||
path = ask("Where are the jekyll posts?")
|
||||
template = ask("What is the default template? (textile, markdown, ...?)")
|
||||
if path.nil?
|
||||
puts "no path given! - aborting"
|
||||
else
|
||||
posts = Dir[path + '/*'].sort
|
||||
if posts.empty?
|
||||
puts "no posts in this directory"
|
||||
else
|
||||
import_jekyll posts, template
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
187
admin.rb
187
admin.rb
|
@ -1,187 +0,0 @@
|
|||
class Admin < Sinatra::Base
|
||||
set $settings
|
||||
use Rack::Session::Pool, :expire_after => 1800
|
||||
use Rack::Flash, :accessorize => [:error, :warning, :notice]
|
||||
set :haml, :layout => :admin_layout
|
||||
register Sinatra::CompassSupport
|
||||
|
||||
get '/' do
|
||||
haml :admin_index
|
||||
end
|
||||
|
||||
get '/post' do
|
||||
@posts = Post.all(:order => [:id.desc], :limit => 15)
|
||||
haml :admin_posts
|
||||
end
|
||||
|
||||
get '/post/new' do
|
||||
@post = Post.new
|
||||
haml :admin_post_create
|
||||
end
|
||||
|
||||
put '/post' do
|
||||
if params[:post].has_key? 'tags'
|
||||
tags = params[:post].delete('tags')
|
||||
else
|
||||
tags = []
|
||||
end
|
||||
@post = Post.new params[:post]
|
||||
@post.set_tags tags
|
||||
if @post.save
|
||||
flash.notice = 'Post saved'
|
||||
redirect "/admin/post/#{@post.id}", 303
|
||||
else
|
||||
flash.error = 'Error at saving the post'
|
||||
flash[:errors] = @post.errors
|
||||
redirect "/admin/post/new", 303
|
||||
end
|
||||
end
|
||||
|
||||
get '/post/:id' do
|
||||
@post = Post.get(params[:id])
|
||||
if @post
|
||||
haml :admin_post_change
|
||||
else
|
||||
flash.warning = "Post with id #{params[:id]} not found!"
|
||||
redirect './post', 303
|
||||
end
|
||||
end
|
||||
|
||||
post '/post/:id' do
|
||||
# read the checkbox value
|
||||
if params['post'].has_key?('released')
|
||||
params['post']['released'] = true
|
||||
else
|
||||
params['post']['released'] = false
|
||||
end
|
||||
# get the post and update it
|
||||
@post = Post.get(params[:id])
|
||||
if @post
|
||||
if params[:post].has_key? 'tags'
|
||||
tags = params[:post].delete('tags')
|
||||
end
|
||||
if @post.update(params[:post])
|
||||
@post.set_tags tags
|
||||
@post.save
|
||||
else
|
||||
flash.warning = 'Error at saving the post!'
|
||||
flash[:errors] = true
|
||||
end
|
||||
haml :admin_post_change
|
||||
else
|
||||
flash.warning = "Post with id #{params[:id]} not found!"
|
||||
redirect './post', 303
|
||||
end
|
||||
end
|
||||
|
||||
# tags
|
||||
get '/tag' do
|
||||
@tags = Tag.all(:order => [:name.asc])
|
||||
haml :admin_tag_index
|
||||
end
|
||||
|
||||
put '/tag/new' do
|
||||
@tag = Tag.new(:name => params['tag']['name'])
|
||||
if @tag.save
|
||||
flash[:notice] = "Tag '#{@tag.name}' created!"
|
||||
else
|
||||
flash[:warning] = "Tag '#{@tag.name} could not be created! Error was: '#{@tag.errors.first}'"
|
||||
end
|
||||
redirect '/admin/tag', 303
|
||||
end
|
||||
|
||||
get '/tag/:id' do
|
||||
@tag = Tag.first(:id => params[:id])
|
||||
haml :admin_tag_edit
|
||||
end
|
||||
|
||||
post '/tag/:id' do
|
||||
@tag = Tag.first(:id => params[:id])
|
||||
@tag.name = params['tag']['name']
|
||||
if @tag.save
|
||||
flash[:notice] = "Tag saved"
|
||||
redirect '/admin/tag', 303
|
||||
else
|
||||
flash[:notice] = "Tag could not be saved! Message: '#{@tag.errors.first}'"
|
||||
haml :admin_tag_edit
|
||||
end
|
||||
end
|
||||
|
||||
# login
|
||||
get '/login' do
|
||||
haml :admin_index_no_login
|
||||
end
|
||||
|
||||
post '/login' do
|
||||
account = Account.authenticate(params['username'], params['password'])
|
||||
if account.nil?
|
||||
flash.warning = 'wrong username or password'
|
||||
flash[:username] = params['username']
|
||||
redirect '/admin', 303
|
||||
else
|
||||
flash.notice = 'Login successful'
|
||||
session[:id] = account.id
|
||||
session[:last_updated] = Time.now
|
||||
# redirect to the url set from the #before block
|
||||
if session.has_key? :to_path
|
||||
redirect "/admin#{session.delete(:to_path)}", 303
|
||||
else
|
||||
redirect '/admin/', 303
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
get '/logout' do
|
||||
session[:id] = nil
|
||||
session[:last_updated] = nil
|
||||
flash.notice = 'Logout complete'
|
||||
redirect '/'
|
||||
end
|
||||
|
||||
get '/stylesheet.css' do
|
||||
scss :admin_stylesheet
|
||||
end
|
||||
|
||||
helpers do
|
||||
def session_read
|
||||
puts session.inspect
|
||||
if (session.has_key?(:id) && session.has_key?(:last_updated) &&
|
||||
Time.now - session[:last_updated] < 1800)
|
||||
Account.get(session[:id])
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def keys_to_sym hash
|
||||
new_hash = {}
|
||||
hash.each do |k, v|
|
||||
new_hash[k.to_sym] = v
|
||||
end
|
||||
hash = new_hash
|
||||
end
|
||||
|
||||
def markup content, markup
|
||||
markup = markup.to_sym
|
||||
if respond_to? markup
|
||||
send markup, content
|
||||
else
|
||||
content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
@account = session_read
|
||||
end
|
||||
|
||||
before %r{^(?!\/(login|stylesheet\.css)+$)} do
|
||||
if @account.nil?
|
||||
flash.warning = 'You are not logged in!'
|
||||
session[:to_path] = request.path_info
|
||||
redirect '/admin/login', 303
|
||||
else
|
||||
session[:last_updated] = Time.now
|
||||
end
|
||||
end
|
||||
end
|
10
config.ru
10
config.ru
|
@ -1,10 +0,0 @@
|
|||
$LOAD_PATH << File.expand_path(File.dirname(__FILE__)) + '/'
|
||||
require 'libs'
|
||||
|
||||
use Rack::CommonLogger
|
||||
use Rack::Deflater # compress with gzip
|
||||
use Rack::Static, :urls => ['/public', '/images']
|
||||
run Rack::URLMap.new({
|
||||
'/' => Blog,
|
||||
'/admin' => Admin
|
||||
})
|
32
libs.rb
32
libs.rb
|
@ -1,32 +0,0 @@
|
|||
# this file loads only the libs needed for using "something"
|
||||
require 'rubygems'
|
||||
require 'bundler/setup'
|
||||
require 'bcrypt'
|
||||
require 'data_mapper'
|
||||
require 'haml'
|
||||
require 'sass'
|
||||
require 'compass'
|
||||
require 'sinatra'
|
||||
require 'sinatra/support'
|
||||
require 'rack-flash'
|
||||
|
||||
# markups
|
||||
require 'redcloth'
|
||||
require 'redcarpet'
|
||||
require 'coderay'
|
||||
require 'redclothcoderay'
|
||||
RedclothCoderay.coderay_options :css => :class
|
||||
|
||||
require 'settings'
|
||||
|
||||
# load the models
|
||||
$LOAD_PATH << File.expand_path(File.dirname(__FILE__)) + '/models'
|
||||
require 'account'
|
||||
require 'post'
|
||||
require 'comment'
|
||||
require 'tag'
|
||||
|
||||
DataMapper.finalize
|
||||
|
||||
require 'page'
|
||||
require 'admin'
|
|
@ -1,57 +0,0 @@
|
|||
class Account
|
||||
include DataMapper::Resource
|
||||
include DataMapper::Validate
|
||||
attr_accessor :password, :password_confirmation
|
||||
|
||||
# Properties
|
||||
property :id, Serial
|
||||
property :username, String, :lazy => false
|
||||
property :email, String
|
||||
property :crypted_password, String, :length => 70
|
||||
property :role, String
|
||||
|
||||
has n, :posts
|
||||
|
||||
# Validations
|
||||
validates_presence_of :username, :email, :role
|
||||
validates_uniqueness_of :username, :case_sensitive => false
|
||||
validates_presence_of :password, :if => :password_required
|
||||
validates_presence_of :password_confirmation, :if => :password_required
|
||||
validates_length_of :password, :min => 4, :max => 40, :if => :password_required
|
||||
validates_confirmation_of :password, :if => :password_required
|
||||
validates_length_of :email, :min => 3, :max => 100
|
||||
validates_uniqueness_of :email, :case_sensitive => false
|
||||
validates_format_of :email, :with => :email_address
|
||||
validates_format_of :role, :with => /[A-Za-z]/
|
||||
|
||||
# Callbacks
|
||||
before :save, :encrypt_password
|
||||
|
||||
##
|
||||
# This method is for authentication purpose
|
||||
#
|
||||
def self.authenticate(username, password)
|
||||
account = first(:conditions => { :username => username }) unless username.nil?
|
||||
(account && account.has_password?(password)) ? account : nil
|
||||
end
|
||||
|
||||
##
|
||||
# This method is used by AuthenticationHelper
|
||||
#
|
||||
def self.find_by_id(id)
|
||||
get(id) rescue nil
|
||||
end
|
||||
|
||||
def has_password?(password)
|
||||
::BCrypt::Password.new(crypted_password) == password
|
||||
end
|
||||
|
||||
private
|
||||
def password_required
|
||||
crypted_password.nil? || password
|
||||
end
|
||||
|
||||
def encrypt_password
|
||||
self.crypted_password = ::BCrypt::Password.create(password) unless password.nil?
|
||||
end
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
class Comment
|
||||
include DataMapper::Resource
|
||||
include DataMapper::Validate
|
||||
|
||||
property :id, Serial
|
||||
property :author, String
|
||||
property :email, String
|
||||
property :acknowledged, Boolean, :default => false
|
||||
property :body, Text
|
||||
belongs_to :post
|
||||
|
||||
validates_presence_of :author, :email, :body
|
||||
validates_length_of :email, :min => 3, :max => 100
|
||||
validates_format_of :email, :with => :email_address
|
||||
|
||||
# overwrite the default to_json, because we don't need all fields
|
||||
def to_json ressource_options
|
||||
{
|
||||
:id => id,
|
||||
:post_id => post.id,
|
||||
:author => author,
|
||||
:body => body
|
||||
}
|
||||
end
|
||||
end
|
|
@ -1,51 +0,0 @@
|
|||
class Post
|
||||
include DataMapper::Resource
|
||||
include DataMapper::Validate
|
||||
|
||||
property :id, Serial
|
||||
property :title, Text, :required => true
|
||||
property :written, Time, :default => lambda {|r, p| Time.now }
|
||||
property :released, Boolean, :default => false
|
||||
property :markup, Text, :default => 'textile'
|
||||
property :content, Text
|
||||
|
||||
belongs_to :account
|
||||
has n, :comments
|
||||
has n, :tags, :through => Resource
|
||||
|
||||
def self.get_released id
|
||||
get_all_released.get(id)
|
||||
end
|
||||
|
||||
def self.get_all_released
|
||||
all(:released => true)
|
||||
end
|
||||
|
||||
def self.get_page page=0
|
||||
get_all_released.all(:limit => 10, :offset => (page * 10),
|
||||
:order => [:written.desc])
|
||||
end
|
||||
|
||||
def self.page_count
|
||||
(get_all_released.count / 10).ceil
|
||||
end
|
||||
|
||||
def self.find_of_day time
|
||||
get_all_released.all_written(time..(time+86400))
|
||||
end
|
||||
|
||||
def acknowledged_comments
|
||||
comments(:acknowledged => true)
|
||||
end
|
||||
|
||||
# checks if a post has this tag
|
||||
def has_tag tag
|
||||
tag_id = tag.id
|
||||
tags.any? { |t| t.id == tag_id }
|
||||
end
|
||||
|
||||
# sets all tags for this post
|
||||
def set_tags new_tags
|
||||
self.tags = Tag.all(:id => new_tags)
|
||||
end
|
||||
end
|
|
@ -1,11 +0,0 @@
|
|||
class Tag
|
||||
include DataMapper::Resource
|
||||
include DataMapper::Validate
|
||||
|
||||
property :id, Serial
|
||||
property :name, Text
|
||||
|
||||
has n, :posts, :through => Resource
|
||||
validates_uniqueness_of :name, :case_sensitive => false
|
||||
validates_presence_of :name
|
||||
end
|
95
page.rb
95
page.rb
|
@ -1,95 +0,0 @@
|
|||
class Blog < Sinatra::Base
|
||||
set $settings
|
||||
# never ever again load the Rack::Session::Pool here
|
||||
# or the admin pool get's broken and you get thrown out after every request!
|
||||
# do that in the config.ru, if you have to!
|
||||
register Sinatra::CompassSupport
|
||||
|
||||
get '/' do
|
||||
if params.has_key? 'page'
|
||||
@current_page = params['page'].to_i
|
||||
else
|
||||
@current_page = 1
|
||||
end
|
||||
@page_count = Post.page_count
|
||||
@posts = Post.get_page(@current_page - 1)
|
||||
haml :index
|
||||
end
|
||||
|
||||
get '/:year/:month/:day/:title.html' do
|
||||
@post = Post.find_of_day(
|
||||
Time.mktime(params[:year], params[:month], params[:day])
|
||||
).select do |post|
|
||||
params[:title] == post.title.gsub(/ /, '_').downcase
|
||||
end
|
||||
if @post.count > 0
|
||||
@post = @post[0]
|
||||
haml :post_single
|
||||
else
|
||||
404
|
||||
end
|
||||
end
|
||||
|
||||
get '/post/:id' do
|
||||
@post = Post.get_released(params[:id])
|
||||
if @post.nil?
|
||||
404
|
||||
else
|
||||
haml :post_single
|
||||
end
|
||||
end
|
||||
|
||||
get '/post/:id/comment.json' do
|
||||
Post.get_released(params[:id]).acknowledged_comments.to_json
|
||||
end
|
||||
|
||||
get '/atom.xml' do
|
||||
@posts = Post.get_page(0)
|
||||
haml :atom, :layout => false
|
||||
end
|
||||
|
||||
get '/stylesheet.css' do
|
||||
scss :stylesheet
|
||||
end
|
||||
|
||||
get '/404' do
|
||||
404
|
||||
end
|
||||
|
||||
error 404 do
|
||||
'where am i? is somebody here? hello?'
|
||||
end
|
||||
|
||||
get '/502' do
|
||||
502
|
||||
end
|
||||
|
||||
error 502 do
|
||||
'oh no, i think i wet myself'
|
||||
end
|
||||
|
||||
def link_to display, link
|
||||
"<a href=\"${link}\">#{display}</a>"
|
||||
end
|
||||
|
||||
def markup content, markup
|
||||
markup = markup.to_sym
|
||||
if respond_to? markup
|
||||
send markup, content
|
||||
else
|
||||
content
|
||||
end
|
||||
end
|
||||
|
||||
def domain path = ''
|
||||
$settings[:domain] + path
|
||||
end
|
||||
|
||||
def title
|
||||
$settings[:title]
|
||||
end
|
||||
|
||||
def subtitle
|
||||
$settings[:subtitle]
|
||||
end
|
||||
end
|
|
@ -1,4 +0,0 @@
|
|||
$('a').live('click', function(e){
|
||||
e.preventDefault();
|
||||
$('#content').load($(this).attr('href') + ' #content');
|
||||
})
|
File diff suppressed because one or more lines are too long
|
@ -1,66 +0,0 @@
|
|||
require 'yaml'
|
||||
|
||||
def ask message
|
||||
puts message
|
||||
STDIN.gets.chomp
|
||||
end
|
||||
|
||||
def import_jekyll files, template
|
||||
# all tags used in the posts
|
||||
template_tags = {}
|
||||
post_tags = {}
|
||||
puts "If asked about template tags, please give a replacement."
|
||||
# from jekyll - lib/jekyll/convertible.rb#26 (08.2011)
|
||||
files.each do |path|
|
||||
content = File.read(path)
|
||||
data = {}
|
||||
if content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
||||
content = $POSTMATCH
|
||||
|
||||
begin
|
||||
data = YAML.load($1)
|
||||
rescue => e
|
||||
puts "YAML exception reading #{path}: #{e.message}"
|
||||
raise e
|
||||
end
|
||||
|
||||
content = content.gsub /({{.*?}})/ do |m|
|
||||
if template_tags.has_key? $1
|
||||
template_tags[$1]
|
||||
else
|
||||
template_tags[$1] = ask("Found tag \"#{$1}\" in post #{data['title']}:")
|
||||
end
|
||||
end
|
||||
|
||||
post = Post.new(
|
||||
:written => data['date'],
|
||||
:released => true,
|
||||
:account => Account.first(:username => data['author']),
|
||||
:markup => template,
|
||||
:content => content,
|
||||
:title => data['title']
|
||||
)
|
||||
if post.save
|
||||
data['tags'].each do |t|
|
||||
if (post_tags.has_key? t)
|
||||
post_tags[t] << post
|
||||
else
|
||||
post_tags[t] = [post]
|
||||
end
|
||||
end
|
||||
else
|
||||
puts "post #{post.title} of file #{path} could not be saved!"
|
||||
end
|
||||
else
|
||||
puts "No valid jekyll file #{path}"
|
||||
raise ArgumentError, "#{path} is not a jekyll file"
|
||||
end
|
||||
end
|
||||
if post_tags.count > 0
|
||||
post_tags.each do |tag_name, posts|
|
||||
tag = Tag.new(:name => tag_name)
|
||||
tag.posts = posts
|
||||
tag.save
|
||||
end
|
||||
end
|
||||
end
|
38
seeds.rb
38
seeds.rb
|
@ -1,38 +0,0 @@
|
|||
gib = Account.new(
|
||||
:username => 'Gibheer',
|
||||
:password => 'food',
|
||||
:password_confirmation => 'food',
|
||||
:email => 'foo@bar.com',
|
||||
:role => 'admin'
|
||||
)
|
||||
gib.save
|
||||
storm = Account.new(
|
||||
:username => 'Stormwind',
|
||||
:password => 'bard',
|
||||
:password_confirmation => 'bard',
|
||||
:email => 'bar@foo.com',
|
||||
:role => 'admin'
|
||||
)
|
||||
storm.save
|
||||
|
||||
(1..50).each do |i|
|
||||
gib.posts.new(:title => "post #{i}", :content => "content of post #{i}",
|
||||
:released => true).save
|
||||
end
|
||||
(1..50).each do |i|
|
||||
storm.posts.new(:title => "post #{i}", :content => "content of post #{i}",
|
||||
:released => true).save
|
||||
end
|
||||
storm.posts.new(:title => 'bar', :content => 'this is my post!').save
|
||||
gib.posts.new(:title => 'foo', :content => 'this is mine!', :released => true).save
|
||||
gib.posts.new(:title => 'lala', :content => 'lorem ipsum in the round about').save
|
||||
storm.posts.new(:title => 'first!', :content => 'i\'m at the top!',
|
||||
:released => true).save
|
||||
Post.last.comments.new(:author => 'Gibheer', :email => 'foo@bar.com',
|
||||
:acknowledged => true, :body => 'ipsum ipsum ipsum').save
|
||||
gib.posts.new(:title => 'with markdown', :content => 'this is some `code`',
|
||||
:markup => 'markdown', :released => true).save
|
||||
Post.last.comments.new(:author => 'Gibheer', :email => 'foo@bar.com',
|
||||
:acknowledged => false, :body => 'lorem lorem ipsum').save
|
||||
Post.last.comments.new(:author => 'Stormwind', :email => 'bar@foo.com',
|
||||
:acknowledged => true, :body => 'lorem ipsum').save
|
|
@ -1,21 +0,0 @@
|
|||
$settings = {
|
||||
:domain => 'http://example.com',
|
||||
:title => 'zero-knowledge',
|
||||
:subtitle => 'scripte, programmieren und administrtieren',
|
||||
:environment => :development,
|
||||
:logging => true,
|
||||
:method_override => true,
|
||||
:sass => {
|
||||
:style => :expanded
|
||||
}
|
||||
}
|
||||
|
||||
DataMapper::Logger.new($stdout, :debug) if $settings[:logging]
|
||||
case $settings[:environment]
|
||||
when :development then
|
||||
DataMapper.setup(
|
||||
:default, 'postgres://<user>:<passphrase>@localhost/<database>'
|
||||
)
|
||||
end
|
||||
|
||||
RedclothCoderay.coderay_options :css => :class
|
176
views/_base.scss
176
views/_base.scss
|
@ -1,176 +0,0 @@
|
|||
header, article, section, aside, footer {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0; }
|
||||
|
||||
html {
|
||||
font-size: $font-size-base;
|
||||
background: $background2; }
|
||||
|
||||
body {
|
||||
font-size: $font-size;
|
||||
font-family: $font-family;
|
||||
color: $font-color1;
|
||||
line-height: $font-size * 1.3;
|
||||
min-width: $body-min-width;
|
||||
max-width: $body-max-width;
|
||||
margin: auto;
|
||||
margin-top: $top-gap;
|
||||
margin-bottom: $top-gap;
|
||||
padding: 2em;
|
||||
padding-top: 0;
|
||||
background-color: $background1;
|
||||
@include set-border-radius;
|
||||
a {
|
||||
color: $link-color1;
|
||||
padding: 0.25em;
|
||||
&:visited {
|
||||
color: $link-color1; }
|
||||
&:hover, &:active {
|
||||
background-color: $highlight-color1;
|
||||
@include set-border-radius;
|
||||
@include background-image(linear-gradient($highlight-gradient)); } }
|
||||
code {
|
||||
font-family: $font-family-code; }
|
||||
pre { margin: 1em; }
|
||||
ul {
|
||||
list-style-type: circle;
|
||||
padding-left: 2em;
|
||||
padding-bottom: 1em;
|
||||
ul {
|
||||
list-style-type: square;
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
}
|
||||
}
|
||||
#wrapper {
|
||||
margin-top: 5em; }
|
||||
#header {
|
||||
position: absolute;
|
||||
width: 800px;
|
||||
top: 0;
|
||||
h1 {
|
||||
> img {
|
||||
margin-top: 2em; }
|
||||
a {
|
||||
font: {
|
||||
size: $font-size * 4;
|
||||
weight: bold; };
|
||||
text-decoration: none;
|
||||
padding: 0;
|
||||
float: left;
|
||||
text-shadow: 2px 5px 8px darken($background1, 10);
|
||||
color: $link-color1;
|
||||
&:hover, &:active {
|
||||
background: none;
|
||||
text-shadow: 3px 5px 8px darken($link-color1, 20); } } } }
|
||||
#linklist {
|
||||
border: 1px solid black;
|
||||
float: right;
|
||||
width: 250px; }
|
||||
#content {
|
||||
em {
|
||||
font-style: oblique; }
|
||||
strong {
|
||||
font-weight: bold; }
|
||||
i {
|
||||
font-style: italic; }
|
||||
b {
|
||||
font-weight: bolder; }
|
||||
cite {
|
||||
font-style: italic; }
|
||||
del {
|
||||
text-decoration: line-through; }
|
||||
ins {
|
||||
text-decoration: underline; }
|
||||
.float_left {
|
||||
float: left;
|
||||
margin: 4px; }
|
||||
.float_right {
|
||||
float: right;
|
||||
margin: 4px; }
|
||||
padding-top: $top-gap;
|
||||
article {
|
||||
clear: both;
|
||||
margin-bottom: 1em;
|
||||
padding-bottom: 0.5em;
|
||||
@include set-border-with-radius;
|
||||
@include clearfix;
|
||||
section {
|
||||
padding: 1em;
|
||||
clear: left;
|
||||
p {
|
||||
margin-bottom: 1em; }
|
||||
h1 {
|
||||
font-size: $font-size * 1.3;
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
margin-bottom: 3px; }
|
||||
h2 {
|
||||
font-size: $font-size * 1.2;
|
||||
font-weight: bold;
|
||||
magrin-bottom: 2px; } }
|
||||
header {
|
||||
float: left;
|
||||
margin: 1em;
|
||||
margin-bottom: 0;
|
||||
h1 {
|
||||
font-size: $font-size * 1.5;
|
||||
font-weight: bold; } }
|
||||
footer {
|
||||
float: right;
|
||||
width: 6.85em;
|
||||
padding: 0.75em;
|
||||
margin-left: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
text-align: center;
|
||||
// set the border
|
||||
@include set-border-radius;
|
||||
border-bottom: $border-width solid $border-color;
|
||||
border-left: $border-width solid $border-color;
|
||||
@include background-image(linear-gradient($background-gradient));
|
||||
.author {
|
||||
padding-bottom: 5px;
|
||||
font-weight: bold; }
|
||||
.date {
|
||||
.day {
|
||||
font-weight: bold;
|
||||
font-size: $font-size * 1.2; }
|
||||
.month, .year {
|
||||
font-size: $font-size * 0.75;
|
||||
display: inline; } }
|
||||
.time {
|
||||
font-size: $font-size * 0.75;
|
||||
.hour {
|
||||
display: inline;
|
||||
margin-right: -4px;
|
||||
&:after {
|
||||
content: ":"; } }
|
||||
.minute {
|
||||
display: inline; } } } }
|
||||
.page {
|
||||
text-align: center;
|
||||
margin-bottom: 1em;
|
||||
span.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
a, span {
|
||||
display: inline-block;
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
margin: 0;
|
||||
width: 10%;
|
||||
min-width: 90px;
|
||||
@include set-border-radius;
|
||||
@include box-sizing(border-box);
|
||||
}
|
||||
}
|
||||
}
|
||||
#footer {
|
||||
padding: 1em;
|
||||
overflow: hidden;
|
||||
font-size: $font-size * 0.85;
|
||||
@include set-border-with-radius;
|
||||
p {
|
||||
text-align: center; } } }
|
|
@ -1,64 +0,0 @@
|
|||
.CodeRay {
|
||||
font-family: $font-family-code;
|
||||
//line-height: $font-size * 1.2;
|
||||
background-color: #232323;
|
||||
border: 1px solid black;
|
||||
color: #E6E0DB;
|
||||
padding: 3px 5px;
|
||||
overflow: auto;
|
||||
margin: 12px 0;
|
||||
pre {
|
||||
margin: 0px;
|
||||
padding: 0px; }
|
||||
.an {
|
||||
color: #E7BE69; }
|
||||
.c {
|
||||
color: #BC9358;
|
||||
font-style: italic; }
|
||||
.ch {
|
||||
color: #509E4F; }
|
||||
.cl, .co {
|
||||
color: #FFF; }
|
||||
.fl {
|
||||
color: #A4C260; }
|
||||
.fu {
|
||||
color: #FFC56D; }
|
||||
.gv {
|
||||
color: #D0CFFE; }
|
||||
.i {
|
||||
color: #A4C260; }
|
||||
.il {
|
||||
background: #151515; }
|
||||
.iv {
|
||||
color: #D0CFFE; }
|
||||
.pp {
|
||||
color: #E7BE69; }
|
||||
.r {
|
||||
color: #CB7832; }
|
||||
.rx, .s {
|
||||
color: #A4C260; }
|
||||
.sy {
|
||||
color: #6C9CBD; }
|
||||
.ta {
|
||||
color: #E7BE69; }
|
||||
.pc {
|
||||
color: #6C9CBD; } }
|
||||
|
||||
/* html attribute */
|
||||
/* comment */
|
||||
/* escaped character */
|
||||
/* class */
|
||||
/* constant */
|
||||
/* float */
|
||||
/* function */
|
||||
/* global variable */
|
||||
/* integer */
|
||||
/* inline code */
|
||||
/* instance variable */
|
||||
/* doctype */
|
||||
/* keyword */
|
||||
/* regex */
|
||||
/* string */
|
||||
/* symbol */
|
||||
/* html tag */
|
||||
/* boolean */
|
|
@ -1,10 +0,0 @@
|
|||
%a{:href => '/admin/logout'}="Logout"
|
||||
%h1="Index"
|
||||
#create
|
||||
-@post = Post.new
|
||||
=haml :admin_post_create, :layout => nil
|
||||
%hr
|
||||
#posts
|
||||
%a{:href => '/admin/post'}="Posts"
|
||||
-@posts=Post.all(:order => [:id.desc])
|
||||
=haml :admin_posts, :layout => nil
|
|
@ -1,11 +0,0 @@
|
|||
%form#login.fields{:action => '/admin/login', :method => 'post'}
|
||||
.login="Welcome in the admin area."
|
||||
.username
|
||||
%label.block{:for => 'username'}='Username'
|
||||
%input.block{:name => 'username', :placeholder => 'username', :value => flash[:username]}
|
||||
.password
|
||||
%label.block{:for => 'password'}='Password'
|
||||
%input.block{:name => 'password', :placeholder => 'password', :type => :password}
|
||||
.submit
|
||||
%button{:type => 'submit'}="Login"
|
||||
%button{:type => 'submit', :formmethod => :post, :formaction => '/'}="Back"
|
|
@ -1,31 +0,0 @@
|
|||
!!! 5
|
||||
%html
|
||||
%head
|
||||
%title="zero-knowledge - Adminpanel"
|
||||
%link{:rel => 'stylesheet', :href => '/admin/stylesheet.css', :type => 'text/css'}
|
||||
%script{:src => '/public/head.min.js'}
|
||||
%body
|
||||
#menu
|
||||
%ul
|
||||
%li
|
||||
%a{:href => '/'}="main"
|
||||
%li
|
||||
%a{:href => '/admin'}="admin"
|
||||
-if @account
|
||||
%li
|
||||
%a{:href => '/admin/post/new'}="create"
|
||||
%li
|
||||
%a{:href => '/admin/tag'}="tags"
|
||||
#messages
|
||||
-unless flash.error.nil?
|
||||
%p.error=flash.error
|
||||
-unless flash.warning.nil?
|
||||
%p.warning=flash.warning
|
||||
-unless flash.notice.nil?
|
||||
%p.notice=flash.notice
|
||||
#content=yield
|
||||
:javascript
|
||||
head.js(
|
||||
'http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js',
|
||||
'/public/admin.js'
|
||||
)
|
|
@ -1,12 +0,0 @@
|
|||
-unless @post.errors.nil?
|
||||
-@post.errors.each do |error|
|
||||
.error=error
|
||||
%form{:action => "/admin/post/#{@post.id}", :method => :post}
|
||||
.fields
|
||||
=haml :admin_post_edit, :layout => nil
|
||||
.buttons
|
||||
%button{:type => :submit}="Update"
|
||||
%button{:type => :submit, :formmethod => :get,
|
||||
:formaction => '/admin/post'}="Back"
|
||||
|
||||
~haml :post_single, :layout => nil
|
|
@ -1,11 +0,0 @@
|
|||
-if flash[:errors].nil?
|
||||
-@post.errors.each do |error|
|
||||
.error=error
|
||||
%form{:action => "/admin/post", :method => :post}
|
||||
.fields
|
||||
%input{:type => :hidden, :name => "_method", :value => :put}=""
|
||||
=(haml :admin_post_edit, :layout => nil)
|
||||
.buttons
|
||||
%button{:type => :submit}="Create"
|
||||
%button{:type => :submit, :formmethod => :get,
|
||||
:formaction => '/admin/post'}="Back"
|
|
@ -1,48 +0,0 @@
|
|||
.main
|
||||
.content
|
||||
%label{:for => :post_content}="Content"
|
||||
%textarea.content{:id => :post_content,
|
||||
:name => 'post[content]'}=@post.content
|
||||
.title
|
||||
%label{:for => :post_title}="Title"
|
||||
%input{:id => :post_title,
|
||||
:name => 'post[title]',
|
||||
:value => @post.title}
|
||||
.further
|
||||
.markup
|
||||
%label{:for => :post_markup}="markup"
|
||||
%select{:id => :post_markup, :name => 'post[markup]'}
|
||||
-[:markdown, :textile].each do |markup|
|
||||
-if @post.markup.to_sym == markup
|
||||
%option{:selected => :selected}=markup
|
||||
-else
|
||||
%option=markup
|
||||
.written
|
||||
%label{:for => :post_written}="written"
|
||||
%input{:id => :post_written,
|
||||
:name => 'post[written]', :value => @post.written}
|
||||
.released
|
||||
%label{:for => :post_released}="released"
|
||||
%input{:type => :checkbox, :name => 'post[released]',
|
||||
:class => "post-released-#{@post.released}", :value => 0,
|
||||
:checked => @post.released, :id => :post_released}
|
||||
.author
|
||||
%label{:for => :post_author}="Author"
|
||||
%select{:name => 'post[account_id]', :id => :post_author}
|
||||
-if @post.account.nil?
|
||||
-@post.account = @account
|
||||
-Account.all(:order => [:id]).each do |account|
|
||||
-if @post.account.id == account.id
|
||||
%option{:value => account.id, :selected => :selected}
|
||||
=account.username
|
||||
-else
|
||||
%option{:value => account.id}=account.username
|
||||
.tags
|
||||
%label{:for => :post_tags}="Tags (#{Tag.all.count})"
|
||||
%select{:name => 'post[tags][]', :id => :post_tags, :size => 10, :multiple => true}
|
||||
- post_tags = @post.tags
|
||||
- Tag.all(:order => [:name.asc]).each do |tag|
|
||||
-if @post.has_tag tag
|
||||
%option{:selected => :selected, :value => tag.id}=tag.name
|
||||
-else
|
||||
%option{:value => tag.id}=tag.name
|
|
@ -1,6 +0,0 @@
|
|||
-@posts.each do |post|
|
||||
.post
|
||||
.title
|
||||
%a{:href => "/admin/post/#{post.id}"}=post.title
|
||||
%span.released{:class => "post-released-#{post.released}"}
|
||||
.written=post.written
|
|
@ -1,151 +0,0 @@
|
|||
// imports
|
||||
@import "blueprint/colors";
|
||||
@import "compass/reset";
|
||||
@import "compass/css3";
|
||||
@import "compass/utilities";
|
||||
|
||||
// variables
|
||||
$font-color: hsl(0, 6%, 90%);
|
||||
$link-color: $font-color;
|
||||
$link-hover-color: hsl(32, 100%, 50%);
|
||||
$border-color: black;
|
||||
$background-normal: hsl(204, 25%, 35%);
|
||||
$background-menu-normal: hsl(0, 0%, 20%);
|
||||
$background-menu: color-stops(lighten($background-menu-normal, 15%),
|
||||
$background-menu-normal 25%, darken($background-menu-normal, 15%));
|
||||
$background-button: color-stops(lighten($background-normal, 15%),
|
||||
$background-normal 75%, darken($background-normal, 5%));
|
||||
$background-button-hover: color-stops(lighten($background-normal, 5%),
|
||||
$background-normal 75%, darken($background-normal, 15%));
|
||||
// some defaults for functions
|
||||
$default-text-shadow-color: hsl(0, 10%, 50%);
|
||||
$default-text-shadow-h-offset: 2px;
|
||||
$default-text-shadow-v-offset: 2px;
|
||||
$default-text-shadow-blur: 2px;
|
||||
$default-border-radius: 2px;
|
||||
|
||||
body {background: $background-normal; color: $font-color;}
|
||||
#menu, #messages, #content {
|
||||
padding-left: 3em;
|
||||
padding-right: 3em;
|
||||
}
|
||||
#messsages, #content {
|
||||
padding-top: 1em;
|
||||
}
|
||||
#menu {
|
||||
@include background-image(linear-gradient($background-menu));
|
||||
li {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
}
|
||||
:after {
|
||||
content: '';
|
||||
clear: both;
|
||||
display: block;
|
||||
}
|
||||
a {
|
||||
color: $link-color;
|
||||
padding: 1em;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
@include single-text-shadow;
|
||||
&:hover {
|
||||
color: $link-hover-color;
|
||||
};
|
||||
}
|
||||
}
|
||||
#messages {
|
||||
padding-top: 1em;
|
||||
.message {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
}
|
||||
.error {
|
||||
@extend .message;
|
||||
background-color: $error-bg-color;
|
||||
border-color: $error-border-color;
|
||||
color: $error-color;
|
||||
}
|
||||
.warning {
|
||||
@extend .message;
|
||||
background-color: $notice-bg-color;
|
||||
border-color: $notice-border-color;
|
||||
color: $notice-color;
|
||||
}
|
||||
.notice {
|
||||
@extend .message;
|
||||
background-color: $success-bg-color;
|
||||
border-color: $success-border-color;
|
||||
color: $success-color;
|
||||
}
|
||||
}
|
||||
#content {
|
||||
.buttons {
|
||||
clear: both;
|
||||
}
|
||||
.fields {
|
||||
clear: both;
|
||||
.main {
|
||||
width: 74%;
|
||||
float: left;
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 25em;
|
||||
@include box-sizing(border-box);
|
||||
}
|
||||
}
|
||||
.further {
|
||||
float: right;
|
||||
width: 24%;
|
||||
}
|
||||
.further:after {
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
label, input, select {
|
||||
display: block;
|
||||
}
|
||||
label {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
}
|
||||
input, select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
button {
|
||||
padding: 0.5em;
|
||||
margin: 0.1em;
|
||||
border: 1px solid $border-color;
|
||||
color: $link-color;
|
||||
font-weight: bold;
|
||||
@include background-image(linear-gradient($background-button));
|
||||
&:hover {
|
||||
@include background-image(linear-gradient($background-button-hover));
|
||||
}
|
||||
&:active {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
a {
|
||||
color: $link-color;
|
||||
font: {
|
||||
weight: bold;
|
||||
decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
#login {
|
||||
text-align: center;
|
||||
.login {
|
||||
padding: 1em;
|
||||
font-weight: bold;
|
||||
font-family: Sans;
|
||||
}
|
||||
> div {
|
||||
width: 18em;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
%form{:action => "/admin/tag/#{@tag.id}", :method => :post}
|
||||
.fields
|
||||
%input{:name => 'tag[name]', :placeholder => 'new tag name', :value => @tag.name}=""
|
||||
.buttons
|
||||
%button{:type => :submit}="update"
|
||||
%ul
|
||||
-@tag.posts.each do |post|
|
||||
%li
|
||||
%a{:href => "/admin/post/#{post.id}"}=post.title
|
|
@ -1,9 +0,0 @@
|
|||
%form{:action => "/admin/tag/new", :method => :post}
|
||||
%input{:type => :hidden, :name => '_method', :value => 'put'}=""
|
||||
.fields
|
||||
%input{:name => 'tag[name]', :placeholder => 'new tag name'}=""
|
||||
.buttons
|
||||
%button{:type => :submit}="create"
|
||||
- @tags.each do |tag|
|
||||
.tag
|
||||
%a{:href => "/admin/tag/#{tag.id}"}=tag.name
|
|
@ -1,18 +0,0 @@
|
|||
!!! XML
|
||||
%feed{:xmlns => 'http://www.w3.org/2005/Atom'}
|
||||
%title=title
|
||||
%subtitle=subtitle
|
||||
%link{:href => domain}
|
||||
%link{:type => 'application/atom+xml', :rel => "self", :href => domain('/atom.xml')}
|
||||
%updated=Post.get_all_released.last.written.xmlschema
|
||||
%id=domain
|
||||
-@posts.each do |post|
|
||||
%entry
|
||||
%id=domain("/post/#{post.id}")
|
||||
%link{:type => 'text/html', :rel => "alternate", :href => "/post/#{post.id}"}
|
||||
%title=post.title
|
||||
%updated=post.written.xmlschema
|
||||
%author
|
||||
%name=post.account.username
|
||||
%summary{:type => 'html'}=markup(post.content, post.markup).match(/.*?<\/p>/m)[0].gsub(/</, '<').gsub(/>/, '>')
|
||||
%content{:type => 'html'}=markup(post.content, post.markup).gsub(/</, '<').gsub(/>/, '>')
|
|
@ -1,13 +0,0 @@
|
|||
-@posts.each do |post|
|
||||
-@post = post
|
||||
=haml :post_single, :layout => nil
|
||||
.page
|
||||
-if @current_page > 2
|
||||
%a{:href => domain('/?page=1')}="<<"
|
||||
-if @current_page > 1
|
||||
%a{:href => domain("/?page=#{@current_page - 1}")}="<"
|
||||
%span.bold=@current_page
|
||||
-if @current_page < @page_count + 1
|
||||
%a{:href => domain("/?page=#{@current_page + 1}")}=">"
|
||||
-if @current_page < (@page_count)
|
||||
%a{:href => domain("/?page=#{@page_count + 1}")}=">>"
|
|
@ -1,24 +0,0 @@
|
|||
!!! 5
|
||||
%html
|
||||
%head
|
||||
%title="#{title} - #{subtitle}"
|
||||
%meta{:'http-equiv' => 'Content-Type', :content => 'text/html; charset=utf-8'}
|
||||
%link{:rel => 'stylesheet', :href => '/stylesheet.css', :type => 'text/css'}
|
||||
%script{:src => domain('/public/javascript/head.min.js')}
|
||||
%link{:rel => 'alternate', :type => 'application/atom+xml', :href => domain('/atom.xml'), :title => 'Atom 1.0'}
|
||||
%body
|
||||
#wrapper
|
||||
%header#header
|
||||
%h1
|
||||
%a{:href => domain}
|
||||
%img{:src => domain("/public/images/zero-knowledge.png"), :alt => title}
|
||||
%img{:style => "float:right", :src => domain("/public/images/blub.png"), :alt => "Logo"}
|
||||
#content
|
||||
=yield
|
||||
%footer#footer
|
||||
%p="Design and Content © 2011 by Gibheer and Stormwind"
|
||||
:javascript
|
||||
head.js(
|
||||
'http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js',
|
||||
'/public/app.js'
|
||||
)
|
|
@ -1,14 +0,0 @@
|
|||
%article
|
||||
%header
|
||||
%h1
|
||||
%a{:href => domain("/post/#{@post.id}")}=@post.title
|
||||
%footer
|
||||
.author=@post.account.username
|
||||
.date
|
||||
.day=@post.written.strftime('%d')
|
||||
.month=@post.written.strftime('%B')
|
||||
.year=@post.written.strftime('%Y')
|
||||
.time
|
||||
.hour=@post.written.strftime('%H')
|
||||
.minute=@post.written.strftime('%M')
|
||||
%section~markup(@post.content, @post.markup)
|
|
@ -1,46 +0,0 @@
|
|||
//colors
|
||||
$font-color1: hsl(0, 0%, 95%);
|
||||
$link-color1: hsl(32, 100%, 50%);
|
||||
$highlight-color1: hsl(204, 33%, 45%);
|
||||
$highlight-gradient: color-stops(lighten($highlight-color1, 5), $highlight-color1 30%, darken($highlight-color1, 15));
|
||||
$border-color: black;
|
||||
$background1: hsl(204, 25%, 35%);
|
||||
$background2: hsl(0, 0%, 20%);
|
||||
$background-gradient: color-stops(lighten($background1, 5), $background1 25%, darken($background1, 5));
|
||||
|
||||
// font
|
||||
$font-size: 100%;
|
||||
$font-size-base: 14px;
|
||||
$font-family: "DejaVu Sans", Verdana, Arial, sans-serif;
|
||||
$font-family-code: monospace;
|
||||
|
||||
//$font-family: 'Droid Serif', 'DejaVu Serif', 'Bitstream Vera Serif', Serif
|
||||
//$font-family-code: 'Droid Mono', 'Courier New', 'Terminal', monospace
|
||||
// sizes
|
||||
// -- body
|
||||
$body-min-width: 400px;
|
||||
$body-max-width: 900px;
|
||||
$top-gap: 95px;
|
||||
|
||||
// -- border stuff
|
||||
$border-width: 1px;
|
||||
$border-radius: 4px;
|
||||
|
||||
//imports
|
||||
@import "compass/reset";
|
||||
@import "compass/css3";
|
||||
@import "compass/utilities";
|
||||
|
||||
// build own mixins
|
||||
@mixin set-border {
|
||||
border: $border-width solid $border-color; }
|
||||
|
||||
@mixin set-border-radius {
|
||||
@include border-radius($border-radius, $border-radius); }
|
||||
|
||||
@mixin set-border-with-radius {
|
||||
@include set-border;
|
||||
@include set-border-radius; }
|
||||
|
||||
@import "base";
|
||||
@import "coderay";
|
Loading…
Reference in New Issue