olelo 0.9.0
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.
- data/.gitignore +10 -0
- data/.gitmodules +3 -0
- data/Gemfile +3 -0
- data/README.markdown +104 -0
- data/Rakefile +92 -0
- data/bin/olelo +5 -0
- data/config.ru +86 -0
- data/config/aspects.rb +256 -0
- data/config/config.yml.default +154 -0
- data/config/initializers/00-mime_types.rb +29 -0
- data/config/initializers/01-slim.rb +2 -0
- data/config/interwiki.yml +11 -0
- data/doc/AUTHORS +7 -0
- data/doc/LICENSE +22 -0
- data/lib/olelo.rb +39 -0
- data/lib/olelo/application.rb +294 -0
- data/lib/olelo/attributes.rb +285 -0
- data/lib/olelo/config.rb +88 -0
- data/lib/olelo/extensions.rb +252 -0
- data/lib/olelo/helper.rb +290 -0
- data/lib/olelo/hooks.rb +142 -0
- data/lib/olelo/html_safe.rb +29 -0
- data/lib/olelo/initializer.rb +76 -0
- data/lib/olelo/locale.rb +63 -0
- data/lib/olelo/locale.yml +284 -0
- data/lib/olelo/menu.rb +101 -0
- data/lib/olelo/middleware/blacklist.rb +25 -0
- data/lib/olelo/middleware/degrade_mime_type.rb +19 -0
- data/lib/olelo/middleware/flash.rb +97 -0
- data/lib/olelo/middleware/force_encoding.rb +41 -0
- data/lib/olelo/page.rb +266 -0
- data/lib/olelo/patch.rb +311 -0
- data/lib/olelo/plugin.rb +188 -0
- data/lib/olelo/repository.rb +225 -0
- data/lib/olelo/routing.rb +223 -0
- data/lib/olelo/templates.rb +30 -0
- data/lib/olelo/user.rb +132 -0
- data/lib/olelo/util.rb +233 -0
- data/lib/olelo/version.rb +3 -0
- data/lib/olelo/virtualfs.rb +161 -0
- data/lib/rack/olelo_patches.rb +33 -0
- data/lib/rack/relative_redirect.rb +44 -0
- data/lib/rack/static_cache.rb +93 -0
- data/lib/yard/addons.rb +1 -0
- data/lib/yard/addons/hook_handler.rb +25 -0
- data/lib/yard/addons/override_tag.rb +14 -0
- data/lib/yard/addons/route_handler.rb +33 -0
- data/lib/yard/addons/sanitize_anchor.rb +16 -0
- data/olelo.gemspec +31 -0
- data/plugins/aspects/changelog.rb +45 -0
- data/plugins/aspects/documentbrowser.rb +57 -0
- data/plugins/aspects/download.rb +11 -0
- data/plugins/aspects/highlight.rb +8 -0
- data/plugins/aspects/image.rb +41 -0
- data/plugins/aspects/imageinfo.rb +64 -0
- data/plugins/aspects/locale.yml +60 -0
- data/plugins/aspects/main.rb +199 -0
- data/plugins/aspects/pageinfo.rb +37 -0
- data/plugins/aspects/source.rb +6 -0
- data/plugins/aspects/subpages.rb +44 -0
- data/plugins/aspects/text.rb +9 -0
- data/plugins/blog/blog.css +1 -0
- data/plugins/blog/blog.scss +37 -0
- data/plugins/blog/locale.yml +12 -0
- data/plugins/blog/main.rb +85 -0
- data/plugins/editor/locale.yml +18 -0
- data/plugins/editor/markup/main.rb +3 -0
- data/plugins/editor/markup/script.js +10 -0
- data/plugins/editor/markup/script/00-jquery.textselection.js +267 -0
- data/plugins/editor/markup/script/01-olelo.markupeditor.js +116 -0
- data/plugins/editor/markup/script/init.js +10 -0
- data/plugins/editor/preview.rb +52 -0
- data/plugins/editor/recaptcha.rb +56 -0
- data/plugins/filters/creole.rb +37 -0
- data/plugins/filters/disposition.rb +9 -0
- data/plugins/filters/editsection.rb +67 -0
- data/plugins/filters/fix_img_tag.rb +16 -0
- data/plugins/filters/html_wrapper.rb +12 -0
- data/plugins/filters/interwiki.rb +19 -0
- data/plugins/filters/link_classifier.rb +26 -0
- data/plugins/filters/locale.yml +15 -0
- data/plugins/filters/main.rb +202 -0
- data/plugins/filters/markdown_nowiki.rb +15 -0
- data/plugins/filters/numbering.xsl +93 -0
- data/plugins/filters/orgmode.rb +6 -0
- data/plugins/filters/rubypants.rb +6 -0
- data/plugins/filters/s5/main.rb +32 -0
- data/plugins/filters/s5/s5.xsl +118 -0
- data/plugins/filters/tilt.rb +17 -0
- data/plugins/filters/toc.rb +50 -0
- data/plugins/filters/xhtml2latex.xsl +232 -0
- data/plugins/filters/xslt.rb +22 -0
- data/plugins/gallery/gallery.css +1 -0
- data/plugins/gallery/gallery.scss +28 -0
- data/plugins/gallery/main.rb +34 -0
- data/plugins/misc/fancybox/images/blank.gif +0 -0
- data/plugins/misc/fancybox/images/fancy_close.png +0 -0
- data/plugins/misc/fancybox/images/fancy_loading.png +0 -0
- data/plugins/misc/fancybox/images/fancy_nav_left.png +0 -0
- data/plugins/misc/fancybox/images/fancy_nav_right.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_e.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_n.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_ne.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_nw.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_s.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_se.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_sw.png +0 -0
- data/plugins/misc/fancybox/images/fancy_shadow_w.png +0 -0
- data/plugins/misc/fancybox/images/fancy_title_left.png +0 -0
- data/plugins/misc/fancybox/images/fancy_title_main.png +0 -0
- data/plugins/misc/fancybox/images/fancy_title_over.png +0 -0
- data/plugins/misc/fancybox/images/fancy_title_right.png +0 -0
- data/plugins/misc/fancybox/images/fancybox-x.png +0 -0
- data/plugins/misc/fancybox/images/fancybox-y.png +0 -0
- data/plugins/misc/fancybox/images/fancybox.png +0 -0
- data/plugins/misc/fancybox/jquery.fancybox.css +1 -0
- data/plugins/misc/fancybox/jquery.fancybox.scss +323 -0
- data/plugins/misc/fancybox/main.rb +4 -0
- data/plugins/misc/fancybox/script.js +37 -0
- data/plugins/misc/fancybox/script/00-jquery.mousewheel.js +84 -0
- data/plugins/misc/fancybox/script/01-jquery.easing.js +205 -0
- data/plugins/misc/fancybox/script/02-jquery.fancybox.js +1156 -0
- data/plugins/misc/fancybox/script/init.js +18 -0
- data/plugins/misc/system.rb +192 -0
- data/plugins/misc/variables.rb +29 -0
- data/plugins/misc/webdav.rb +45 -0
- data/plugins/repositories/git_grep.rb +69 -0
- data/plugins/repositories/gitrb_repository.rb +204 -0
- data/plugins/repositories/locale.yml +12 -0
- data/plugins/repositories/rugged_repository.rb +454 -0
- data/plugins/security/acl.rb +57 -0
- data/plugins/security/basic_auth.rb +21 -0
- data/plugins/security/locale.yml +21 -0
- data/plugins/security/persistent_login.rb +32 -0
- data/plugins/security/portal.rb +28 -0
- data/plugins/security/private_wiki.rb +24 -0
- data/plugins/security/readonly_wiki.rb +25 -0
- data/plugins/security/stack.rb +20 -0
- data/plugins/security/yamlfile.rb +66 -0
- data/plugins/tags/code.rb +6 -0
- data/plugins/tags/footnotes.rb +35 -0
- data/plugins/tags/gist-embed.css +123 -0
- data/plugins/tags/gist.rb +13 -0
- data/plugins/tags/html.rb +57 -0
- data/plugins/tags/include.rb +20 -0
- data/plugins/tags/main.rb +353 -0
- data/plugins/tags/math.rb +117 -0
- data/plugins/tags/scripting.rb +64 -0
- data/plugins/tags/sort.rb +7 -0
- data/plugins/tags/tabs.rb +20 -0
- data/plugins/treeview/images/collapsed.png +0 -0
- data/plugins/treeview/images/expanded.png +0 -0
- data/plugins/treeview/images/menu.png +0 -0
- data/plugins/treeview/images/tree.png +0 -0
- data/plugins/treeview/images/wait.gif +0 -0
- data/plugins/treeview/main.rb +16 -0
- data/plugins/treeview/script.js +5 -0
- data/plugins/treeview/script/00-jquery.treeview.js +164 -0
- data/plugins/treeview/script/init.js +25 -0
- data/plugins/treeview/treeview.css +1 -0
- data/plugins/treeview/treeview.scss +113 -0
- data/plugins/utils/assets.rb +74 -0
- data/plugins/utils/cache.rb +53 -0
- data/plugins/utils/image_magick.rb +34 -0
- data/plugins/utils/pygments.css +1 -0
- data/plugins/utils/pygments.rb +50 -0
- data/plugins/utils/pygments.scss +83 -0
- data/plugins/utils/semaphore.rb +50 -0
- data/plugins/utils/shell.rb +45 -0
- data/plugins/utils/store.rb +315 -0
- data/plugins/utils/worker.rb +36 -0
- data/plugins/utils/xml.rb +29 -0
- data/static/images/favicon.png +0 -0
- data/static/script.js +267 -0
- data/static/script/00-json2.js +486 -0
- data/static/script/01-jstorage.js +217 -0
- data/static/script/02-jquery.js +9440 -0
- data/static/script/03-jquery.ui.core.js +337 -0
- data/static/script/04-jquery.ui.widget.js +502 -0
- data/static/script/05-jquery.ui.position.js +517 -0
- data/static/script/06-jquery.ui.menu.js +609 -0
- data/static/script/07-jquery.ui.autocomplete.js +601 -0
- data/static/script/08-olelo.i18n.js +37 -0
- data/static/script/09-olelo.unsaved.js +68 -0
- data/static/script/10-olelo.historytable.js +40 -0
- data/static/script/11-olelo.pagination.js +18 -0
- data/static/script/13-olelo.tabwidget.js +57 -0
- data/static/script/14-olelo.timeago.js +70 -0
- data/static/script/15-olelo.underliner.js +31 -0
- data/static/script/16-olelo.ui.combobox.js +32 -0
- data/static/script/init.js +48 -0
- data/static/themes/atlantis/constants.scss +15 -0
- data/static/themes/atlantis/iehacks.scss +38 -0
- data/static/themes/atlantis/images/actions/delete.png +0 -0
- data/static/themes/atlantis/images/actions/edit.png +0 -0
- data/static/themes/atlantis/images/actions/history.png +0 -0
- data/static/themes/atlantis/images/actions/home.png +0 -0
- data/static/themes/atlantis/images/actions/move.png +0 -0
- data/static/themes/atlantis/images/actions/new.png +0 -0
- data/static/themes/atlantis/images/actions/page.png +0 -0
- data/static/themes/atlantis/images/bg/button.png +0 -0
- data/static/themes/atlantis/images/bg/container.png +0 -0
- data/static/themes/atlantis/images/bg/content.png +0 -0
- data/static/themes/atlantis/images/bg/footer.png +0 -0
- data/static/themes/atlantis/images/bg/header.jpg +0 -0
- data/static/themes/atlantis/images/bg/header.orig.jpg +0 -0
- data/static/themes/atlantis/images/bg/header_gray.jpg +0 -0
- data/static/themes/atlantis/images/bug.png +0 -0
- data/static/themes/atlantis/images/filetypes/7z.png +0 -0
- data/static/themes/atlantis/images/filetypes/_archive.png +0 -0
- data/static/themes/atlantis/images/filetypes/_audio.png +0 -0
- data/static/themes/atlantis/images/filetypes/_code.png +0 -0
- data/static/themes/atlantis/images/filetypes/_linux.png +0 -0
- data/static/themes/atlantis/images/filetypes/_picture.png +0 -0
- data/static/themes/atlantis/images/filetypes/_video.png +0 -0
- data/static/themes/atlantis/images/filetypes/bz2.png +0 -0
- data/static/themes/atlantis/images/filetypes/doc.png +0 -0
- data/static/themes/atlantis/images/filetypes/flac.png +0 -0
- data/static/themes/atlantis/images/filetypes/gz.png +0 -0
- data/static/themes/atlantis/images/filetypes/html.png +0 -0
- data/static/themes/atlantis/images/filetypes/java.png +0 -0
- data/static/themes/atlantis/images/filetypes/jpg.png +0 -0
- data/static/themes/atlantis/images/filetypes/midi.png +0 -0
- data/static/themes/atlantis/images/filetypes/mp3.png +0 -0
- data/static/themes/atlantis/images/filetypes/ogg.png +0 -0
- data/static/themes/atlantis/images/filetypes/pdf.png +0 -0
- data/static/themes/atlantis/images/filetypes/php.png +0 -0
- data/static/themes/atlantis/images/filetypes/png.png +0 -0
- data/static/themes/atlantis/images/filetypes/ppt.png +0 -0
- data/static/themes/atlantis/images/filetypes/psd.png +0 -0
- data/static/themes/atlantis/images/filetypes/rar.png +0 -0
- data/static/themes/atlantis/images/filetypes/rb.png +0 -0
- data/static/themes/atlantis/images/filetypes/sh.png +0 -0
- data/static/themes/atlantis/images/filetypes/tar.png +0 -0
- data/static/themes/atlantis/images/filetypes/txt.png +0 -0
- data/static/themes/atlantis/images/filetypes/wma.png +0 -0
- data/static/themes/atlantis/images/filetypes/xls.png +0 -0
- data/static/themes/atlantis/images/filetypes/zip.png +0 -0
- data/static/themes/atlantis/images/folder.png +0 -0
- data/static/themes/atlantis/images/folder_open.png +0 -0
- data/static/themes/atlantis/images/loading.gif +0 -0
- data/static/themes/atlantis/images/loading.xcf +0 -0
- data/static/themes/atlantis/images/not_found.png +0 -0
- data/static/themes/atlantis/images/page.png +0 -0
- data/static/themes/atlantis/images/search.png +0 -0
- data/static/themes/atlantis/layout.scss +115 -0
- data/static/themes/atlantis/menu.scss +99 -0
- data/static/themes/atlantis/print.scss +129 -0
- data/static/themes/atlantis/screen.scss +495 -0
- data/static/themes/atlantis/style.css +3 -0
- data/static/themes/lib/autocomplete.scss +39 -0
- data/static/themes/lib/headlines.scss +10 -0
- data/static/themes/lib/horizontal-list.scss +31 -0
- data/static/themes/lib/patch.scss +88 -0
- data/static/themes/lib/reset.scss +114 -0
- data/static/themes/lib/rounded.scss +46 -0
- data/static/themes/lib/shadow.scss +14 -0
- data/test/config_test.rb +28 -0
- data/test/factory_test.rb +29 -0
- data/test/hash_extensions_test.rb +16 -0
- data/test/helper.rb +38 -0
- data/test/hooks_test.rb +85 -0
- data/test/object_extensions_test.rb +20 -0
- data/test/page_test.rb +168 -0
- data/test/request_test.rb +166 -0
- data/test/string_extensions_test.rb +32 -0
- data/test/templates_test.rb +39 -0
- data/test/util_test.rb +71 -0
- data/views/changes.slim +22 -0
- data/views/compare.slim +8 -0
- data/views/delete.slim +9 -0
- data/views/deleted.slim +2 -0
- data/views/edit.slim +65 -0
- data/views/error.slim +6 -0
- data/views/history.slim +20 -0
- data/views/layout.slim +38 -0
- data/views/login.slim +37 -0
- data/views/move.slim +10 -0
- data/views/not_found.slim +6 -0
- data/views/profile.slim +26 -0
- data/views/show.slim +9 -0
- metadata +488 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module Olelo
|
|
2
|
+
class<< self
|
|
3
|
+
attr_accessor :logger
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class Initializer
|
|
7
|
+
include Util
|
|
8
|
+
|
|
9
|
+
def self.initialize(logger)
|
|
10
|
+
@instance ||= Initializer.new(logger)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(logger)
|
|
14
|
+
Olelo.logger = logger
|
|
15
|
+
init_locale
|
|
16
|
+
init_templates
|
|
17
|
+
init_plugins
|
|
18
|
+
init_routes
|
|
19
|
+
init_scripts
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def init_locale
|
|
25
|
+
Locale.locale = Config['locale']
|
|
26
|
+
Locale.load(File.join(File.dirname(__FILE__), 'locale.yml'))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def init_templates
|
|
30
|
+
Templates.enable_caching if Config['production']
|
|
31
|
+
Templates.loader = Class.new do
|
|
32
|
+
def context
|
|
33
|
+
Plugin.caller.first.try(:name)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def load(name)
|
|
37
|
+
VirtualFS::Union.new(Plugin.caller.first.try(:virtual_fs),
|
|
38
|
+
VirtualFS::Native.new(Config['views_path'])).read(name)
|
|
39
|
+
end
|
|
40
|
+
end.new
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def init_plugins
|
|
44
|
+
# Load locales for loaded plugins
|
|
45
|
+
Plugin.after(:load) { Locale.load(File.join(File.dirname(file), 'locale.yml')) }
|
|
46
|
+
|
|
47
|
+
# Configure plugin system
|
|
48
|
+
Plugin.disabled = Config['disabled_plugins'].to_a
|
|
49
|
+
Plugin.dir = Config['plugins_path']
|
|
50
|
+
|
|
51
|
+
Plugin.load_all
|
|
52
|
+
Plugin.start
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def init_routes
|
|
56
|
+
Application.reserved_paths = Application.router.map do |method, router|
|
|
57
|
+
router.head.map {|name, pattern, keys, function| pattern }
|
|
58
|
+
end.flatten
|
|
59
|
+
Application.router.each do |method, router|
|
|
60
|
+
Olelo.logger.debug method
|
|
61
|
+
router.each do |name, pattern, keys, function|
|
|
62
|
+
Olelo.logger.debug "#{name} -> #{pattern.inspect}"
|
|
63
|
+
end
|
|
64
|
+
end if Olelo.logger.debug?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def init_scripts
|
|
68
|
+
Dir[File.join(Config['initializers_path'], '*.rb')].sort_by do |f|
|
|
69
|
+
File.basename(f)
|
|
70
|
+
end.each do |f|
|
|
71
|
+
Olelo.logger.debug "Running script initializer #{f}"
|
|
72
|
+
instance_eval(File.read(f), f)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
data/lib/olelo/locale.rb
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Olelo
|
|
2
|
+
# Simple localization implementation
|
|
3
|
+
module Locale
|
|
4
|
+
@locale = nil
|
|
5
|
+
@translations = Hash.with_indifferent_access
|
|
6
|
+
@loaded = []
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
attr_accessor :locale
|
|
10
|
+
|
|
11
|
+
# Load locale from file
|
|
12
|
+
#
|
|
13
|
+
# A locale is a yamlfile which maps
|
|
14
|
+
# keys to strings.
|
|
15
|
+
#
|
|
16
|
+
# @param [String] file name
|
|
17
|
+
# @return [void]
|
|
18
|
+
#
|
|
19
|
+
def load(file)
|
|
20
|
+
if !@loaded.include?(file) && File.file?(file)
|
|
21
|
+
locale = YAML.load_file(file)
|
|
22
|
+
@translations.update(locale[$1] || {}) if @locale =~ /^(\w+)(_|-)/
|
|
23
|
+
@translations.update(locale[@locale] || {})
|
|
24
|
+
@translations.each_value(&:freeze)
|
|
25
|
+
@loaded << file
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Return translated string for key
|
|
30
|
+
#
|
|
31
|
+
# A translated string can contain variables which are substituted in this method.
|
|
32
|
+
# You have to pass an arguments hash.
|
|
33
|
+
#
|
|
34
|
+
# @option args [Integer] :count if count is not 1, the key #{key}_plural is looked up instead
|
|
35
|
+
# @option args [String] :fallback Fallback string if key is not found in the locale
|
|
36
|
+
# @param [Symbol, String] key which identifies string in locale
|
|
37
|
+
# @param [Hash] args Arguments hash for string interpolation
|
|
38
|
+
# @return [String] translated string
|
|
39
|
+
#
|
|
40
|
+
def translate(key, args = {})
|
|
41
|
+
if !key.to_s.ends_with?('_plural') && args[:count] && args[:count] != 1
|
|
42
|
+
translate("#{key}_plural", args)
|
|
43
|
+
elsif @translations[key]
|
|
44
|
+
args.inject(@translations[key]) {|s,(k,v)| s.gsub("#\{#{k}\}", v.to_s) }
|
|
45
|
+
else
|
|
46
|
+
args[:fallback] || "##{key}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
class Symbol
|
|
54
|
+
# Lookup translated string identified by this symbol
|
|
55
|
+
#
|
|
56
|
+
# @param [Hash] args Arguments hash for string interpolation
|
|
57
|
+
# @return [String] translated string
|
|
58
|
+
# @see Olelo::Locale#translate
|
|
59
|
+
#
|
|
60
|
+
def t(args = {})
|
|
61
|
+
Olelo::Locale.translate(self, args)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
en:
|
|
2
|
+
access_denied: 'Access denied'
|
|
3
|
+
actions: 'Actions'
|
|
4
|
+
already_exists: '#{page} exists already'
|
|
5
|
+
attribute_mime: 'Mime-Type'
|
|
6
|
+
attribute_no_title: 'Disable title'
|
|
7
|
+
attribute_title: 'Title'
|
|
8
|
+
attributes: 'Attributes'
|
|
9
|
+
attributes_edited: 'Attributes of #{page} edited'
|
|
10
|
+
auth_unsupported: 'Authentication service does not support #{name}'
|
|
11
|
+
author: 'Author'
|
|
12
|
+
binary_file: 'Binary file'
|
|
13
|
+
by: 'by'
|
|
14
|
+
cancel: 'Cancel'
|
|
15
|
+
change_password: 'Change password'
|
|
16
|
+
changes: 'Changes'
|
|
17
|
+
changes_of: 'Changes of #{page}'
|
|
18
|
+
changes_saved: 'Changes saved'
|
|
19
|
+
comment: 'Comment'
|
|
20
|
+
compare: 'Compare #{name}'
|
|
21
|
+
confirm_password: 'Confirm password'
|
|
22
|
+
head: 'Head'
|
|
23
|
+
create_page: 'Create #{page}'
|
|
24
|
+
create_redirect: 'Create redirect'
|
|
25
|
+
date: 'Date'
|
|
26
|
+
delete: 'Delete'
|
|
27
|
+
deleted: 'Deleted'
|
|
28
|
+
delete_page: 'Delete #{page}'
|
|
29
|
+
description: 'Description'
|
|
30
|
+
destination: 'Destination'
|
|
31
|
+
edit: 'Edit'
|
|
32
|
+
edit_page: 'Editing #{page}'
|
|
33
|
+
edit_page_section: 'Editing #{page} (Section)'
|
|
34
|
+
email: 'E-Mail'
|
|
35
|
+
empty_password: 'Empty password'
|
|
36
|
+
error_binary: '#{page} is a binary #{type} and cannot be edited like a text file.'
|
|
37
|
+
error_occurred: 'Oh snap! An error occurred.'
|
|
38
|
+
file: 'File'
|
|
39
|
+
groups: 'Groups'
|
|
40
|
+
history: 'History'
|
|
41
|
+
history_of: 'History of #{page}'
|
|
42
|
+
invalid_email: 'E-Mail is invalid'
|
|
43
|
+
invalid_name: 'Name is invalid'
|
|
44
|
+
invalid_path: 'Invalid path'
|
|
45
|
+
last_modified: 'Last modified'
|
|
46
|
+
login: 'Login'
|
|
47
|
+
logout: 'Logout'
|
|
48
|
+
menu_actions_edit_new: 'New Page'
|
|
49
|
+
move: 'Move'
|
|
50
|
+
move_page: 'Move #{page}'
|
|
51
|
+
name: 'Name'
|
|
52
|
+
newer: 'Newer'
|
|
53
|
+
new_page: 'New Page'
|
|
54
|
+
no_changes: 'No changes'
|
|
55
|
+
not_found: '#{id} not found'
|
|
56
|
+
old_password: 'Old password'
|
|
57
|
+
page: 'Page'
|
|
58
|
+
page_edited: '#{page} edited'
|
|
59
|
+
page_not_found: 'Sorry, the page you were looking for was not found.'
|
|
60
|
+
page_uploaded: 'Page #{page} uploaded'
|
|
61
|
+
password: 'Password'
|
|
62
|
+
passwords_do_not_match: 'Passwords do not match'
|
|
63
|
+
parents: 'Parents'
|
|
64
|
+
path: 'Path'
|
|
65
|
+
profile_title: 'Profile of #{user}'
|
|
66
|
+
really_delete: 'Really delete?'
|
|
67
|
+
reserved_path: 'Path is reserved'
|
|
68
|
+
reset: 'Reset'
|
|
69
|
+
root: 'Root'
|
|
70
|
+
page_deleted: '#{page} deleted.'
|
|
71
|
+
page_moved: '#{page} moved to #{destination}.'
|
|
72
|
+
save: 'Save'
|
|
73
|
+
save_and_close: 'Save & Close'
|
|
74
|
+
search: 'Search'
|
|
75
|
+
settings: 'Settings'
|
|
76
|
+
signup: 'Sign up'
|
|
77
|
+
summary: 'Summary'
|
|
78
|
+
text: 'Text'
|
|
79
|
+
title: 'Title'
|
|
80
|
+
tree: 'Tree'
|
|
81
|
+
type_select: 'Select value'
|
|
82
|
+
type_stringlist: 'Comma-separated strings'
|
|
83
|
+
upload_file: 'Upload file'
|
|
84
|
+
upload: 'Upload'
|
|
85
|
+
user: 'User'
|
|
86
|
+
user_already_exists: 'User #{name} already exists'
|
|
87
|
+
version: 'Version'
|
|
88
|
+
version_conflict: 'Version conflict detected'
|
|
89
|
+
wrong_user_or_pw: 'Wrong username or password'
|
|
90
|
+
wrong_password: 'Wrong password'
|
|
91
|
+
de:
|
|
92
|
+
access_denied: 'Zugriff verweigert'
|
|
93
|
+
actions: 'Aktionen'
|
|
94
|
+
already_exists: '#{page} existiert bereits'
|
|
95
|
+
attribute_mime: 'Mime-Typ'
|
|
96
|
+
attribute_no_title: 'Titel deaktivieren'
|
|
97
|
+
attribute_title: 'Titel'
|
|
98
|
+
attributes: 'Attribute'
|
|
99
|
+
attributes_edited: 'Attribute von #{page} bearbeitet'
|
|
100
|
+
auth_unsupported: 'Authentifikationsservice unterstützt #{name} nicht'
|
|
101
|
+
author: 'Autor'
|
|
102
|
+
binary_file: 'Binärdatei'
|
|
103
|
+
by: 'von'
|
|
104
|
+
cancel: 'Abbrechen'
|
|
105
|
+
change_password: 'Passwort ändern'
|
|
106
|
+
changes: 'Änderungen'
|
|
107
|
+
changes_of: 'Änderungen von #{page}'
|
|
108
|
+
changes_saved: 'Änderungen gespeichert'
|
|
109
|
+
comment: 'Kommentar'
|
|
110
|
+
compare: 'Vergleiche #{name}'
|
|
111
|
+
confirm_password: 'Bestätige Passwort'
|
|
112
|
+
head: 'Kopf'
|
|
113
|
+
create_page: 'Neue #{page}'
|
|
114
|
+
create_redirect: 'Weiterleitung'
|
|
115
|
+
date: 'Datum'
|
|
116
|
+
delete: 'Löschen'
|
|
117
|
+
deleted: 'Gelöscht'
|
|
118
|
+
delete_page: 'Lösche #{page}'
|
|
119
|
+
description: 'Beschreibung'
|
|
120
|
+
destination: 'Ziel'
|
|
121
|
+
edit: 'Bearbeiten'
|
|
122
|
+
edit_page: 'Bearbeite #{page}'
|
|
123
|
+
edit_page_section: 'Bearbeite #{page} (Bereich)'
|
|
124
|
+
email: 'E-Mail'
|
|
125
|
+
empty_password: 'Leeres Passwort'
|
|
126
|
+
error_binary: '#{page} ist eine Datei mit dem Typ #{type} und kann nicht wie eine Textdatei bearbeitet werden.'
|
|
127
|
+
error_occurred: 'Hoppla! Es ist ein Fehler aufgetreten.'
|
|
128
|
+
file: 'Datei'
|
|
129
|
+
groups: 'Gruppen'
|
|
130
|
+
history: 'Historie'
|
|
131
|
+
history_of: 'Historie von #{page}'
|
|
132
|
+
invalid_email: 'E-Mail ist ungültig'
|
|
133
|
+
invalid_name: 'Name ist ungültig'
|
|
134
|
+
invalid_path: 'Ungültiger Pfad'
|
|
135
|
+
last_modified: 'Letzte Änderung'
|
|
136
|
+
login: 'Anmelden'
|
|
137
|
+
logout: 'Abmelden'
|
|
138
|
+
menu_actions_edit: 'Bearbeiten'
|
|
139
|
+
menu_actions_edit_delete: 'Löschen'
|
|
140
|
+
menu_actions_edit_move: 'Verschieben'
|
|
141
|
+
menu_actions_edit_new: 'Neue Seite'
|
|
142
|
+
menu_actions_history: 'Historie'
|
|
143
|
+
menu_actions_history_newer: 'Neuer'
|
|
144
|
+
menu_actions_history_older: 'Älter'
|
|
145
|
+
menu_actions_view: 'Ansicht'
|
|
146
|
+
move: 'Verschieben'
|
|
147
|
+
move_page: 'Verschiebe #{page}'
|
|
148
|
+
name: 'Name'
|
|
149
|
+
new_page: 'Neue Seite'
|
|
150
|
+
no_changes: 'Keine Änderungen'
|
|
151
|
+
not_found: '#{id} nicht gefunden'
|
|
152
|
+
old_password: 'Altes Passwort'
|
|
153
|
+
page: 'Seite'
|
|
154
|
+
page_edited: '#{page} edited'
|
|
155
|
+
page_not_found: 'Die Seite wurde leider nicht gefunden.'
|
|
156
|
+
page_uploaded: 'Seite #{page} hochgeladen'
|
|
157
|
+
password: 'Passwort'
|
|
158
|
+
passwords_do_not_match: 'Passwörter stimmen nicht überein'
|
|
159
|
+
parents: 'Eltern'
|
|
160
|
+
path: 'Pfad'
|
|
161
|
+
profile_title: 'Profil von #{user}'
|
|
162
|
+
really_delete: 'Wirklich löschen?'
|
|
163
|
+
reserved_path: 'Pfad ist reserviert'
|
|
164
|
+
reset: 'Zurücksetzen'
|
|
165
|
+
root: 'Root'
|
|
166
|
+
page_deleted: '#{page} gelöscht.'
|
|
167
|
+
page_moved: '#{page} verschoben nach #{destination}.'
|
|
168
|
+
save: 'Speichern'
|
|
169
|
+
save_and_close: 'Speichern & Schließen'
|
|
170
|
+
search: 'Suche'
|
|
171
|
+
settings: 'Einstellungen'
|
|
172
|
+
signup: 'Konto anlegen'
|
|
173
|
+
summary: 'Zusammenfassung'
|
|
174
|
+
text: 'Text'
|
|
175
|
+
title: 'Titel'
|
|
176
|
+
type_select: 'Wert auswählen'
|
|
177
|
+
type_stringlist: 'Durch Komma getrennte Strings'
|
|
178
|
+
tree: 'Baum'
|
|
179
|
+
upload_file: 'Datei hochladen'
|
|
180
|
+
upload: 'Hochladen'
|
|
181
|
+
user: 'Benutzer'
|
|
182
|
+
user_already_exists: 'Benutzer #{name} existiert bereits'
|
|
183
|
+
version: 'Version'
|
|
184
|
+
version_conflict: 'Versionskonflikt aufgetreten'
|
|
185
|
+
wrong_user_or_pw: 'Falscher Benutzername oder falsches Passwort'
|
|
186
|
+
wrong_password: 'Falsches Passwort'
|
|
187
|
+
cs_CZ:
|
|
188
|
+
access_denied: 'Přístup odepřen'
|
|
189
|
+
actions: 'Akce'
|
|
190
|
+
already_exists: 'Stránka #{page} již existuje'
|
|
191
|
+
attribute_mime: 'Mime-Type'
|
|
192
|
+
attribute_no_title: 'Skrýt titulek'
|
|
193
|
+
attribute_title: 'Titulek'
|
|
194
|
+
attributes: 'Atributy'
|
|
195
|
+
attributes_edited: 'Atributy stránky #{page} editovány'
|
|
196
|
+
auth_unsupported: 'Autentizační služba nepodporuje #{name}'
|
|
197
|
+
author: 'Autor'
|
|
198
|
+
binary_file: 'Binární soubor'
|
|
199
|
+
by: 'od'
|
|
200
|
+
cancel: 'Zrušit'
|
|
201
|
+
change_password: 'Změnit heslo'
|
|
202
|
+
changes: 'Změny'
|
|
203
|
+
changes_of: 'Změny stránky #{page}'
|
|
204
|
+
changes_saved: 'Změny uloženy'
|
|
205
|
+
comment: 'Komentář'
|
|
206
|
+
compare: 'Porovnat #{name}'
|
|
207
|
+
confirm_password: 'Potvrdit heslo'
|
|
208
|
+
head: 'Nejnovější'
|
|
209
|
+
create_page: 'Vytvořit stránku #{page}'
|
|
210
|
+
create_redirect: 'Vytvořit přesměrování'
|
|
211
|
+
date: 'Datum'
|
|
212
|
+
delete: 'Smazat'
|
|
213
|
+
deleted: 'Smazáno'
|
|
214
|
+
delete_page: 'Smazat stránku #{page}'
|
|
215
|
+
description: 'Popis'
|
|
216
|
+
destination: 'Cíl'
|
|
217
|
+
edit: 'Editovat'
|
|
218
|
+
edit_page: 'Editace stránky #{page}'
|
|
219
|
+
edit_page_section: 'Editovat #{page} (Sekci)'
|
|
220
|
+
email: 'e-mail'
|
|
221
|
+
empty_password: 'Prázdné heslo'
|
|
222
|
+
error_binary: 'Stránka #{page} je binární typ #{type} a nemůže být editována jako textový soubor.'
|
|
223
|
+
error_occurred: 'Ouvej! Vyskytla se chyba.'
|
|
224
|
+
file: 'Soubor'
|
|
225
|
+
groups: 'Skupiny'
|
|
226
|
+
history: 'Historie'
|
|
227
|
+
history_of: 'Historie stránky #{page}'
|
|
228
|
+
invalid_email: 'e-mail je neplatný'
|
|
229
|
+
invalid_name: 'Jméno je neplatné'
|
|
230
|
+
invalid_path: 'Neplatná cesta'
|
|
231
|
+
last_modified: 'Poslední modifikace'
|
|
232
|
+
login: 'Přihlášení'
|
|
233
|
+
logout: 'Odhlášení'
|
|
234
|
+
menu_actions_edit: 'Editovat'
|
|
235
|
+
menu_actions_edit_delete: 'Smazat'
|
|
236
|
+
menu_actions_edit_move: 'Přesunout'
|
|
237
|
+
menu_actions_edit_new: 'Nová stránka'
|
|
238
|
+
menu_actions_history: 'Historie'
|
|
239
|
+
menu_actions_history_newer: 'Novější'
|
|
240
|
+
menu_actions_history_older: 'Starší'
|
|
241
|
+
menu_actions_history_head: 'Aktuální'
|
|
242
|
+
menu_actions_view: 'Zobrazit'
|
|
243
|
+
move: 'Přesunout'
|
|
244
|
+
move_page: 'Přesunout stránku #{page}'
|
|
245
|
+
name: 'Jméno'
|
|
246
|
+
newer: 'Novější'
|
|
247
|
+
new_page: 'Nová stránka'
|
|
248
|
+
no_changes: 'Žádné změny'
|
|
249
|
+
not_found: '#{id}: nenalezeno'
|
|
250
|
+
old_password: 'Staré heslo'
|
|
251
|
+
page: 'Stránka'
|
|
252
|
+
page_edited: 'Stránka #{page} editována'
|
|
253
|
+
page_not_found: 'Pardon, stránka, kterou hledáte, nebyla nalezena.'
|
|
254
|
+
page_uploaded: 'Stránka #{page} nahrána'
|
|
255
|
+
password: 'Heslo'
|
|
256
|
+
passwords_do_not_match: 'Hesla se neshodují'
|
|
257
|
+
parents: 'Rodiče'
|
|
258
|
+
path: 'Cesta'
|
|
259
|
+
profile_title: 'Profil uživatele #{user}'
|
|
260
|
+
really_delete: 'Opravdu smazat?'
|
|
261
|
+
reserved_path: 'Cesta je rezervována'
|
|
262
|
+
reset: 'Reset'
|
|
263
|
+
root: 'Hlavní strana'
|
|
264
|
+
page_deleted: 'Stránka #{page} smazána.'
|
|
265
|
+
page_moved: 'Stránka #{page} přesunuta do #{destination}.'
|
|
266
|
+
save: 'Uložit'
|
|
267
|
+
save_and_close: 'Uložit a zavřít'
|
|
268
|
+
search: 'Hledat'
|
|
269
|
+
settings: 'Nastavení'
|
|
270
|
+
signup: 'Registrovat se'
|
|
271
|
+
summary: 'Souhrn'
|
|
272
|
+
text: 'Text'
|
|
273
|
+
title: 'Titulek'
|
|
274
|
+
tree: 'Strom'
|
|
275
|
+
type_select: 'Vybrat hodnotu'
|
|
276
|
+
type_stringlist: 'Řetězce oddělené čárkou'
|
|
277
|
+
upload_file: 'Nahrát soubor'
|
|
278
|
+
upload: 'Nahrát'
|
|
279
|
+
user: 'Uživatel'
|
|
280
|
+
user_already_exists: 'Uživatel #{name} již existuje'
|
|
281
|
+
version: 'Verze'
|
|
282
|
+
version_conflict: 'Detekován konflikt verzí'
|
|
283
|
+
wrong_user_or_pw: 'Chybné jméno uživatele nebo heslo'
|
|
284
|
+
wrong_password: 'Chybné heslo'
|
data/lib/olelo/menu.rb
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module Olelo
|
|
2
|
+
class Menu
|
|
3
|
+
include Util
|
|
4
|
+
include Enumerable
|
|
5
|
+
attr_reader :name
|
|
6
|
+
|
|
7
|
+
def initialize(name)
|
|
8
|
+
@name = name.to_sym
|
|
9
|
+
@items = []
|
|
10
|
+
@items_map = {}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def each(&block)
|
|
14
|
+
@items.each(&block)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def [](name)
|
|
18
|
+
path = path.to_s
|
|
19
|
+
i = path.index('/')
|
|
20
|
+
if i
|
|
21
|
+
item = @items_map[path[0...i]]
|
|
22
|
+
item[path[i+1..-1]] if item
|
|
23
|
+
else
|
|
24
|
+
@items_map[name.to_sym]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def item(name, options = {})
|
|
29
|
+
self << MenuItem.new(name, options)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def <<(item)
|
|
33
|
+
raise TypeError, "Only items allowed" unless MenuItem === item
|
|
34
|
+
raise "Item #{item.name} exists already in #{path.join('/')}" if @items_map.include?(item.name)
|
|
35
|
+
item.parent = self
|
|
36
|
+
@items << item
|
|
37
|
+
@items_map[item.name] = item
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def empty?
|
|
41
|
+
@items.empty?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def clear
|
|
45
|
+
@items.clear
|
|
46
|
+
@items_map.clear
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def remove(name)
|
|
50
|
+
path = name.to_s
|
|
51
|
+
i = path.index('/')
|
|
52
|
+
if i
|
|
53
|
+
item = @items_map[path[0...i]]
|
|
54
|
+
item.remove(path[i+1..-1]) if item
|
|
55
|
+
else
|
|
56
|
+
item = @items_map.delete(name.to_sym)
|
|
57
|
+
@items.delete(item) if item
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def build_menu
|
|
62
|
+
empty? ? '' : %{<ul id="menu-#{html_id}">#{map {|item| item.build_menu }.join}</ul>}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def to_html
|
|
66
|
+
build_menu.html_safe
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def html_id
|
|
70
|
+
escape_html path.join('-')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def path
|
|
74
|
+
[name]
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class MenuItem < Menu
|
|
79
|
+
attr_reader :options
|
|
80
|
+
attr_accessor :parent
|
|
81
|
+
|
|
82
|
+
def initialize(name, options = {})
|
|
83
|
+
super(name)
|
|
84
|
+
@parent = nil
|
|
85
|
+
@options = options
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def path
|
|
89
|
+
parent ? parent.path << super : super
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def build_menu
|
|
93
|
+
attrs = options.dup
|
|
94
|
+
label = attrs.delete(:label) || Locale.translate("menu_#{path.join('_')}", :fallback => titlecase(name))
|
|
95
|
+
klass = [*attrs.delete(:class)].flatten.compact
|
|
96
|
+
klass = klass.empty? ? '' : %{class="#{klass.join(' ')}" }
|
|
97
|
+
attrs = attrs.map {|k,v| %{#{k}="#{escape_html v}"} }.join(' ')
|
|
98
|
+
%{<li #{klass}id="item-#{html_id}"><a #{attrs}>#{escape_html label}</a>#{super}</li>}
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|