lokka 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +48 -0
- data/LICENSE +20 -0
- data/README.ja.rdoc +46 -0
- data/README.rdoc +46 -0
- data/Rakefile +116 -0
- data/VERSION +1 -0
- data/bin/autotest +16 -0
- data/bin/bluefeather +16 -0
- data/bin/convert_to_should_syntax +16 -0
- data/bin/css2sass +16 -0
- data/bin/edit_json.rb +16 -0
- data/bin/erubis +16 -0
- data/bin/exceptional +16 -0
- data/bin/haml +16 -0
- data/bin/html2haml +16 -0
- data/bin/jeweler +16 -0
- data/bin/lokka +4 -0
- data/bin/prettify_json.rb +16 -0
- data/bin/rackup +16 -0
- data/bin/rake +16 -0
- data/bin/rcov +16 -0
- data/bin/sass +16 -0
- data/bin/sass-convert +16 -0
- data/bin/tilt +16 -0
- data/bin/unit_diff +16 -0
- data/config.ru +3 -0
- data/config.yml +4 -0
- data/i18n/en.yml +149 -0
- data/i18n/ja.yml +149 -0
- data/init.rb +7 -0
- data/install.rb +16 -0
- data/lib/lokka.rb +138 -0
- data/lib/lokka/app.rb +562 -0
- data/lib/lokka/before.rb +29 -0
- data/lib/lokka/bread_crumb.rb +34 -0
- data/lib/lokka/category.rb +33 -0
- data/lib/lokka/comment.rb +26 -0
- data/lib/lokka/entry.rb +70 -0
- data/lib/lokka/helpers.rb +214 -0
- data/lib/lokka/option.rb +23 -0
- data/lib/lokka/site.rb +19 -0
- data/lib/lokka/tag.rb +5 -0
- data/lib/lokka/theme.rb +17 -0
- data/lib/lokka/user.rb +77 -0
- data/lib/sqlite3.dll +0 -0
- data/lokka.exe +0 -0
- data/lokka.exy +15 -0
- data/lokka.gemspec +373 -0
- data/lokka.ico +0 -0
- data/lokka.rb +11 -0
- data/public/admin/categories/edit.haml +6 -0
- data/public/admin/categories/form.haml +18 -0
- data/public/admin/categories/index.haml +15 -0
- data/public/admin/categories/new.haml +5 -0
- data/public/admin/comments/edit.haml +6 -0
- data/public/admin/comments/form.haml +29 -0
- data/public/admin/comments/index.haml +22 -0
- data/public/admin/comments/new.haml +5 -0
- data/public/admin/css/editor.css +10 -0
- data/public/admin/css/jquery.cleditor.css +24 -0
- data/public/admin/css/style.css +710 -0
- data/public/admin/edit.haml +42 -0
- data/public/admin/favicon.ico +0 -0
- data/public/admin/images/add.png +0 -0
- data/public/admin/images/aside_arrow.png +0 -0
- data/public/admin/images/buttons.gif +0 -0
- data/public/admin/images/category.png +0 -0
- data/public/admin/images/comment.png +0 -0
- data/public/admin/images/dashboard.png +0 -0
- data/public/admin/images/file.png +0 -0
- data/public/admin/images/files.png +0 -0
- data/public/admin/images/mail-attachment.png +0 -0
- data/public/admin/images/plugin.png +0 -0
- data/public/admin/images/post.png +0 -0
- data/public/admin/images/setting.png +0 -0
- data/public/admin/images/tag.png +0 -0
- data/public/admin/images/theme.png +0 -0
- data/public/admin/images/toolbar.gif +0 -0
- data/public/admin/images/user.png +0 -0
- data/public/admin/index.haml +1 -0
- data/public/admin/js/editor.js +7 -0
- data/public/admin/js/jquery.cleditor.js +1132 -0
- data/public/admin/js/jquery.cleditor.min.js +31 -0
- data/public/admin/layout.haml +91 -0
- data/public/admin/pages/edit.haml +6 -0
- data/public/admin/pages/form.haml +33 -0
- data/public/admin/pages/index.haml +23 -0
- data/public/admin/pages/new.haml +5 -0
- data/public/admin/plugins/index.haml +4 -0
- data/public/admin/posts/edit.haml +6 -0
- data/public/admin/posts/form.haml +33 -0
- data/public/admin/posts/index.haml +23 -0
- data/public/admin/posts/new.haml +5 -0
- data/public/admin/show.haml +7 -0
- data/public/admin/signup.haml +17 -0
- data/public/admin/site/edit.haml +13 -0
- data/public/admin/tags/edit.haml +6 -0
- data/public/admin/tags/form.haml +10 -0
- data/public/admin/tags/index.haml +19 -0
- data/public/admin/themes/index.haml +13 -0
- data/public/admin/users/edit.haml +6 -0
- data/public/admin/users/form.haml +22 -0
- data/public/admin/users/index.haml +24 -0
- data/public/admin/users/new.haml +5 -0
- data/public/plugin/lokka-google_analytics/lib/lokka/google_analytics.rb +29 -0
- data/public/plugin/lokka-google_analytics/views/index.haml +15 -0
- data/public/plugin/lokka-hello/lib/lokka/hello.rb +15 -0
- data/public/plugin/lokka-markdown/lib/lokka/markdown.rb +12 -0
- data/public/plugin/lokka-rbconfig/lib/lokka/rbconfig.rb +11 -0
- data/public/plugin/lokka-rbconfig/views/index.haml +7 -0
- data/public/plugin/lokka-rbconfig/views/style.css +12 -0
- data/public/system/404.haml +20 -0
- data/public/system/500.haml +19 -0
- data/public/system/comments/form.haml +22 -0
- data/public/system/favicon.ico +0 -0
- data/public/system/index.builder +25 -0
- data/public/system/style.css +8 -0
- data/public/theme/default/entries.erb +40 -0
- data/public/theme/default/entry.erb +23 -0
- data/public/theme/default/layout.erb +74 -0
- data/public/theme/default/quote.gif +0 -0
- data/public/theme/default/screenshot.png +0 -0
- data/public/theme/default/style.css +1147 -0
- data/public/theme/jarvi/entries.erb +26 -0
- data/public/theme/jarvi/entry.erb +14 -0
- data/public/theme/jarvi/favicon.ico +0 -0
- data/public/theme/jarvi/images/aside_dt.gif +0 -0
- data/public/theme/jarvi/images/aside_dt.png +0 -0
- data/public/theme/jarvi/images/footer.gif +0 -0
- data/public/theme/jarvi/images/footer.psd +0 -0
- data/public/theme/jarvi/images/header_deascription_ul.gif +0 -0
- data/public/theme/jarvi/images/header_language.gif +0 -0
- data/public/theme/jarvi/images/header_nav.gif +0 -0
- data/public/theme/jarvi/images/html.gif +0 -0
- data/public/theme/jarvi/images/index_content.gif +0 -0
- data/public/theme/jarvi/images/index_content_footer.gif +0 -0
- data/public/theme/jarvi/images/index_content_header.gif +0 -0
- data/public/theme/jarvi/images/index_header_nav.gif +0 -0
- data/public/theme/jarvi/images/section_header_title.gif +0 -0
- data/public/theme/jarvi/images/wide_content.gif +0 -0
- data/public/theme/jarvi/images/wide_content_body.gif +0 -0
- data/public/theme/jarvi/images/wide_content_h3.gif +0 -0
- data/public/theme/jarvi/layout.erb +55 -0
- data/public/theme/jarvi/screenshot.png +0 -0
- data/public/theme/jarvi/style.css +618 -0
- data/public/theme/lokka-org/article.haml +9 -0
- data/public/theme/lokka-org/entries.haml +9 -0
- data/public/theme/lokka-org/entry.haml +1 -0
- data/public/theme/lokka-org/favicon.ico +0 -0
- data/public/theme/lokka-org/images/aside_dt.gif +0 -0
- data/public/theme/lokka-org/images/aside_dt.png +0 -0
- data/public/theme/lokka-org/images/download_button.jpg +0 -0
- data/public/theme/lokka-org/images/footer.gif +0 -0
- data/public/theme/lokka-org/images/footer.psd +0 -0
- data/public/theme/lokka-org/images/header_capture.gif +0 -0
- data/public/theme/lokka-org/images/header_capture.jpg +0 -0
- data/public/theme/lokka-org/images/header_capture_a.gif +0 -0
- data/public/theme/lokka-org/images/header_deascription_ul.gif +0 -0
- data/public/theme/lokka-org/images/header_h1_a.gif +0 -0
- data/public/theme/lokka-org/images/header_language.gif +0 -0
- data/public/theme/lokka-org/images/header_nav.gif +0 -0
- data/public/theme/lokka-org/images/heder_nav_home.gif +0 -0
- data/public/theme/lokka-org/images/heder_nav_home.jpg +0 -0
- data/public/theme/lokka-org/images/html.gif +0 -0
- data/public/theme/lokka-org/images/index_content.gif +0 -0
- data/public/theme/lokka-org/images/index_content_footer.gif +0 -0
- data/public/theme/lokka-org/images/index_content_header.gif +0 -0
- data/public/theme/lokka-org/images/index_header_h1.gif +0 -0
- data/public/theme/lokka-org/images/index_header_nav.gif +0 -0
- data/public/theme/lokka-org/images/language_a.png +0 -0
- data/public/theme/lokka-org/images/section_header_title.gif +0 -0
- data/public/theme/lokka-org/images/wide_content.gif +0 -0
- data/public/theme/lokka-org/images/wide_content_body.gif +0 -0
- data/public/theme/lokka-org/images/wide_content_h3.gif +0 -0
- data/public/theme/lokka-org/index.haml +5 -0
- data/public/theme/lokka-org/layout.haml +72 -0
- data/public/theme/lokka-org/quote.gif +0 -0
- data/public/theme/lokka-org/screenshot.png +0 -0
- data/public/theme/lokka-org/style.css +806 -0
- data/public/theme/p0t/article.haml +10 -0
- data/public/theme/p0t/entries.haml +9 -0
- data/public/theme/p0t/entry.haml +7 -0
- data/public/theme/p0t/favicon.ico +0 -0
- data/public/theme/p0t/images/quote.gif +0 -0
- data/public/theme/p0t/layout.haml +68 -0
- data/public/theme/p0t/screenshot.png +0 -0
- data/public/theme/p0t/style.css +359 -0
- data/public/theme/vicuna-mono/entries.erb +40 -0
- data/public/theme/vicuna-mono/entry.erb +23 -0
- data/public/theme/vicuna-mono/layout.erb +76 -0
- data/public/theme/vicuna-mono/quote.gif +0 -0
- data/public/theme/vicuna-mono/screenshot.png +0 -0
- data/public/theme/vicuna-mono/style.css +1156 -0
- data/test/helper.rb +23 -0
- data/test/lokka/app_test.rb +15 -0
- data/test/lokka/post_test.rb +17 -0
- metadata +965 -0
data/lib/lokka/before.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Lokka
|
2
|
+
module Before
|
3
|
+
def self.registered(app)
|
4
|
+
app.before do
|
5
|
+
begin
|
6
|
+
Site.first
|
7
|
+
rescue DataObjects::SyntaxError
|
8
|
+
Lokka::Database.new.create.setup
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
app.before do
|
13
|
+
@site = Site.first
|
14
|
+
@title = @site.title
|
15
|
+
@theme = Theme.new(settings.theme)
|
16
|
+
@theme_types = []
|
17
|
+
session[:locale] = params[:locale] if params[:locale]
|
18
|
+
end
|
19
|
+
|
20
|
+
app.before %r{(?!^/admin/login$)^/admin/.*$} do
|
21
|
+
login_required
|
22
|
+
end
|
23
|
+
|
24
|
+
app.before %r{(?!^/admin/login$)^/admin/.*$} do
|
25
|
+
login_required
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Bread
|
2
|
+
attr_accessor :name, :link, :last
|
3
|
+
|
4
|
+
def initialize(name, link, last = false)
|
5
|
+
@name = name
|
6
|
+
@link = link
|
7
|
+
@last = last
|
8
|
+
end
|
9
|
+
|
10
|
+
def last?
|
11
|
+
@last
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class BreadCrumb
|
16
|
+
include Enumerable
|
17
|
+
attr_accessor :breads
|
18
|
+
|
19
|
+
def initialize(breads = [])
|
20
|
+
@breads = breads
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(name, link)
|
25
|
+
@breads << Bread.new(name, link)
|
26
|
+
end
|
27
|
+
|
28
|
+
def each
|
29
|
+
@breads.last.last = true
|
30
|
+
@breads.each do |bread|
|
31
|
+
yield bread
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Category
|
2
|
+
include DataMapper::Resource
|
3
|
+
|
4
|
+
property :id, Serial
|
5
|
+
property :slug, Slug, :length => 255, :unique => true
|
6
|
+
property :title, String, :length => 255, :unique => true
|
7
|
+
property :description, Text
|
8
|
+
property :type, Discriminator
|
9
|
+
property :created_at, DateTime
|
10
|
+
property :updated_at, DateTime
|
11
|
+
property :parent_id, Integer
|
12
|
+
|
13
|
+
is :tree, :order => :title
|
14
|
+
|
15
|
+
has n, :entries
|
16
|
+
|
17
|
+
def self.get_by_fuzzy_slug(str)
|
18
|
+
ret = first(:slug => str)
|
19
|
+
ret.blank? ? get(str) : ret
|
20
|
+
end
|
21
|
+
|
22
|
+
def fuzzy_slug
|
23
|
+
slug.blank? ? id : slug
|
24
|
+
end
|
25
|
+
|
26
|
+
def link
|
27
|
+
cats = [fuzzy_slug]
|
28
|
+
ancestors.each do |ancestor|
|
29
|
+
cats.unshift ancestor.fuzzy_slug
|
30
|
+
end
|
31
|
+
"/category/#{cats.join('/')}/"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Comment
|
2
|
+
include DataMapper::Resource
|
3
|
+
|
4
|
+
property :id, Serial
|
5
|
+
property :entry_id, Integer
|
6
|
+
property :name, String
|
7
|
+
property :homepage, String
|
8
|
+
property :body, Text
|
9
|
+
property :created_at, DateTime
|
10
|
+
property :updated_at, DateTime
|
11
|
+
|
12
|
+
belongs_to :entry
|
13
|
+
|
14
|
+
default_scope(:default).update(:order => :created_at.desc)
|
15
|
+
|
16
|
+
validates_presence_of :name
|
17
|
+
validates_presence_of :body
|
18
|
+
|
19
|
+
def self.recent(count = 5)
|
20
|
+
all(:limit => count, :order => [:created_at.desc])
|
21
|
+
end
|
22
|
+
|
23
|
+
def link
|
24
|
+
"#{self.entry.link}#comment-#{id}"
|
25
|
+
end
|
26
|
+
end
|
data/lib/lokka/entry.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
class Entry
|
3
|
+
include DataMapper::Resource
|
4
|
+
|
5
|
+
property :id, Serial
|
6
|
+
property :user_id, Integer
|
7
|
+
property :category_id, Integer
|
8
|
+
property :slug, Slug, :length => 255
|
9
|
+
property :title, String, :length => 255
|
10
|
+
property :body, Text
|
11
|
+
property :type, Discriminator
|
12
|
+
property :created_at, DateTime
|
13
|
+
property :updated_at, DateTime
|
14
|
+
|
15
|
+
belongs_to :user
|
16
|
+
belongs_to :category, :required => false
|
17
|
+
has n, :comments
|
18
|
+
|
19
|
+
has_tags
|
20
|
+
|
21
|
+
default_scope(:default).update(:order => [:created_at.desc])
|
22
|
+
|
23
|
+
validates_presence_of :title
|
24
|
+
validates_uniqueness_of :slug
|
25
|
+
validates_uniqueness_of :title
|
26
|
+
|
27
|
+
def tag_collection=(string)
|
28
|
+
reg = RUBY_VERSION >= "1.9.0" ? /[^\p{Word}_]/i : /[^\w\s_-]/i
|
29
|
+
@tag_list = string.to_s.split(',').map { |name|
|
30
|
+
name.force_encoding(Encoding.default_external).gsub(reg, '').strip
|
31
|
+
}.reject{|x|x.blank?}.uniq.sort
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get_by_fuzzy_slug(str)
|
35
|
+
ret = first(:slug => str)
|
36
|
+
ret.blank? ? get(str) : ret
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.search(str)
|
40
|
+
all(:title.like => "%#{str}%") |
|
41
|
+
all(:body.like => "%#{str}%")
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.recent(count = 5)
|
45
|
+
all(:limit => count, :order => [:created_at.desc])
|
46
|
+
end
|
47
|
+
|
48
|
+
def fuzzy_slug
|
49
|
+
slug.blank? ? id : slug
|
50
|
+
end
|
51
|
+
|
52
|
+
def link
|
53
|
+
"/#{fuzzy_slug}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def edit_link
|
57
|
+
"/admin/#{self.class.to_s.tableize}/#{id}/edit"
|
58
|
+
end
|
59
|
+
|
60
|
+
def tags_to_html
|
61
|
+
html = '<ul>'
|
62
|
+
tags.each do |tag|
|
63
|
+
html += %Q(<li><a href="#{tag.link}">#{tag.name}</a></li>)
|
64
|
+
end
|
65
|
+
html + '</ul>'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Post < Entry; end
|
70
|
+
class Page < Entry; end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
module Lokka
|
2
|
+
module Helpers
|
3
|
+
include Rack::Utils
|
4
|
+
|
5
|
+
alias :h :escape_html
|
6
|
+
|
7
|
+
def index?; @theme_types.include?(:index); end
|
8
|
+
def search?; @theme_types.include?(:search); end
|
9
|
+
def category?; @theme_types.include?(:category); end
|
10
|
+
def tag?; @theme_types.include?(:tag); end
|
11
|
+
def yearly?; @theme_types.include?(:yearly); end
|
12
|
+
def monthly?; @theme_types.include?(:monthly); end
|
13
|
+
def daily?; @theme_types.include?(:daily); end
|
14
|
+
def entry?; @theme_types.include?(:entry); end
|
15
|
+
def entries?; @theme_types.include?(:entries); end
|
16
|
+
|
17
|
+
# h + n2br
|
18
|
+
def hbr(str)
|
19
|
+
h(str).gsub(/\r\n|\r|\n/, "<br />\n")
|
20
|
+
end
|
21
|
+
|
22
|
+
def login_required
|
23
|
+
if current_user.class != GuestUser
|
24
|
+
return true
|
25
|
+
else
|
26
|
+
session[:return_to] = request.fullpath
|
27
|
+
redirect '/admin/login'
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def current_user
|
33
|
+
if session[:user]
|
34
|
+
User.get(session[:user])
|
35
|
+
else
|
36
|
+
GuestUser.new
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def logged_in?
|
41
|
+
!!session[:user]
|
42
|
+
end
|
43
|
+
|
44
|
+
def bread_crumb
|
45
|
+
html = '<ol>'
|
46
|
+
@bread_crumbs.each do |bread|
|
47
|
+
html += '<li>'
|
48
|
+
if bread.last?
|
49
|
+
html += bread.name
|
50
|
+
else
|
51
|
+
html += "<a href=\"#{bread.link}\">#{bread.name}</a>"
|
52
|
+
end
|
53
|
+
html += '</li>'
|
54
|
+
end
|
55
|
+
html += '</ol>'
|
56
|
+
html
|
57
|
+
end
|
58
|
+
|
59
|
+
def category_tree(categories = Category.roots)
|
60
|
+
html = '<ul>'
|
61
|
+
categories.each do |category|
|
62
|
+
html += '<li>'
|
63
|
+
html += "<a href=\"#{category.link}\">#{category.title}</a>"
|
64
|
+
if category.children.count > 0
|
65
|
+
html += category_tree(category.children)
|
66
|
+
end
|
67
|
+
html += '</li>'
|
68
|
+
end
|
69
|
+
html += '</ul>'
|
70
|
+
html
|
71
|
+
end
|
72
|
+
|
73
|
+
def render_detect(*names)
|
74
|
+
ret = ''
|
75
|
+
names.each do |name|
|
76
|
+
out = render_any(name)
|
77
|
+
unless out.blank?
|
78
|
+
ret = out
|
79
|
+
break
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if ret.blank?
|
84
|
+
raise Lokka::NoTemplateError, "Template not found. #{[names.join(', ')]}"
|
85
|
+
else
|
86
|
+
ret
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def partial(name, options = {})
|
91
|
+
options[:layout] = false
|
92
|
+
render_any(name, options)
|
93
|
+
end
|
94
|
+
|
95
|
+
def render_any(name, options = {})
|
96
|
+
ret = ''
|
97
|
+
settings.supported_templates.each do |ext|
|
98
|
+
out = rendering(ext, name, options)
|
99
|
+
out.force_encoding(Encoding.default_external) unless out.nil?
|
100
|
+
unless out.blank?
|
101
|
+
ret = out
|
102
|
+
break
|
103
|
+
end
|
104
|
+
end
|
105
|
+
ret
|
106
|
+
end
|
107
|
+
|
108
|
+
def rendering(ext, name, options = {})
|
109
|
+
locals = options[:locals] ? {:locals => options[:locals]} : {}
|
110
|
+
dir = request.path_info =~ %r{^/admin/.*} ? 'admin' : "theme/#{@theme.name}"
|
111
|
+
layout = "#{dir}/layout"
|
112
|
+
path = "#{dir}/#{name}"
|
113
|
+
|
114
|
+
puts "ext, name, theme, dir, file: #{ext}, #{name}, #{@theme.name}, #{dir}, #{settings.views}/#{path}.#{ext}"
|
115
|
+
|
116
|
+
if File.exist?("#{settings.views}/#{layout}.#{ext}")
|
117
|
+
options[:layout] = layout.to_sym if options[:layout].nil?
|
118
|
+
end
|
119
|
+
if File.exist?("#{settings.views}/#{path}.#{ext}")
|
120
|
+
send(ext.to_sym, path.to_sym, options, locals)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def comment_form
|
125
|
+
haml :'system/comments/form', :layout => false
|
126
|
+
end
|
127
|
+
|
128
|
+
def link_to_if(cond, name, url, options = {})
|
129
|
+
cond ? link_to(name, url, options) : name
|
130
|
+
end
|
131
|
+
|
132
|
+
def link_to_unless(cond, name, url, options = {})
|
133
|
+
link_to_if !cond, name, url, options
|
134
|
+
end
|
135
|
+
|
136
|
+
def link_to(name, url, options = {})
|
137
|
+
attrs = {:href => url}
|
138
|
+
if options[:confirm] and options[:method]
|
139
|
+
attrs[:onclick] = "if(confirm('#{options[:confirm]}')){var f = document.createElement('form');f.style.display = 'none';this.parentNode.appendChild(f);f.method = 'POST';f.action = this.href;var m = document.createElement('input');m.setAttribute('type', 'hidden');m.setAttribute('name', '_method');m.setAttribute('value', '#{options[:method]}');f.appendChild(m);f.submit();};return false"
|
140
|
+
end
|
141
|
+
|
142
|
+
options.delete :confirm
|
143
|
+
options.delete :method
|
144
|
+
|
145
|
+
attrs.update(options)
|
146
|
+
|
147
|
+
str = ''
|
148
|
+
attrs.each do |key, value|
|
149
|
+
str += %Q(#{key.to_s}="#{value}")
|
150
|
+
end
|
151
|
+
|
152
|
+
%Q(<a #{str}>#{name}</a>)
|
153
|
+
end
|
154
|
+
|
155
|
+
def select_field(object, method, values = [], options = {})
|
156
|
+
name = "#{object.class.name.downcase}[#{method}]"
|
157
|
+
v = object.send(method)
|
158
|
+
|
159
|
+
attrs = ''
|
160
|
+
options.each do |key, value|
|
161
|
+
attrs += %Q( #{key}="#{value}")
|
162
|
+
end
|
163
|
+
|
164
|
+
html = %Q(<select name="#{name}"#{attrs}>)
|
165
|
+
values.each do |value|
|
166
|
+
padding = value[0] == v ? ' selected="selected"' : ''
|
167
|
+
html += %Q(<option value="#{value[0]}"#{padding}>#{value[1]}</option>)
|
168
|
+
end
|
169
|
+
html + '</select>'
|
170
|
+
end
|
171
|
+
|
172
|
+
def truncate(text, options = {})
|
173
|
+
options = {:length => 30, :ommision => '...'}.merge(options)
|
174
|
+
if options[:length] < text.length
|
175
|
+
text[0..options[:length]] + options[:ommision]
|
176
|
+
else
|
177
|
+
text
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def strip_tags(text)
|
182
|
+
text.gsub(/<.+?>/, '')
|
183
|
+
end
|
184
|
+
|
185
|
+
def months
|
186
|
+
ms = {}
|
187
|
+
Post.all.each do |post|
|
188
|
+
m = post.created_at.strftime('%Y-%m')
|
189
|
+
if ms[m].nil?
|
190
|
+
ms[m] = 1
|
191
|
+
else
|
192
|
+
ms[m] += 1
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
months = []
|
197
|
+
ms.each do |m, count|
|
198
|
+
year, month = m.split('-')
|
199
|
+
months << OpenStruct.new({:year => year, :month => month, :count => count})
|
200
|
+
end
|
201
|
+
months.sort {|x, y| y.year + y.month <=> x.year + x.month }
|
202
|
+
end
|
203
|
+
|
204
|
+
def header
|
205
|
+
s = yield_content :header
|
206
|
+
s unless s.blank?
|
207
|
+
end
|
208
|
+
|
209
|
+
def footer
|
210
|
+
s = yield_content :footer
|
211
|
+
s unless s.blank?
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
data/lib/lokka/option.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Option
|
2
|
+
include DataMapper::Resource
|
3
|
+
|
4
|
+
property :name, String, :length => 255, :key => true
|
5
|
+
property :value, Text
|
6
|
+
property :created_at, DateTime
|
7
|
+
property :updated_at, DateTime
|
8
|
+
|
9
|
+
validates_presence_of :name
|
10
|
+
|
11
|
+
def self.method_missing(method, *args)
|
12
|
+
attribute = method.to_s
|
13
|
+
if attribute =~ /=$/
|
14
|
+
column = attribute[0, attribute.size - 1]
|
15
|
+
o = self.first_or_new(:name => column)
|
16
|
+
o.value = args.first
|
17
|
+
o.save
|
18
|
+
else
|
19
|
+
o = self.first_or_new(:name => method)
|
20
|
+
o.value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/lokka/site.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class Site
|
2
|
+
include DataMapper::Resource
|
3
|
+
|
4
|
+
property :id, Serial
|
5
|
+
property :title, String, :length => 255
|
6
|
+
property :description, String, :length => 255
|
7
|
+
property :theme, String, :length => 64
|
8
|
+
property :created_at, DateTime
|
9
|
+
property :updated_at, DateTime
|
10
|
+
|
11
|
+
def method_missing(method, *args)
|
12
|
+
if method.to_s =~ /=$/
|
13
|
+
super
|
14
|
+
else
|
15
|
+
o = Option.first_or_new(:name => method)
|
16
|
+
o.value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|