rayo 0.1.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/lib/rayo.rb +11 -0
- data/lib/rayo/application.rb +54 -0
- data/lib/rayo/config.rb +57 -0
- data/lib/rayo/models/page.rb +94 -0
- data/lib/rayo/models/renderable.rb +19 -0
- data/lib/rayo/models/root_page.rb +22 -0
- data/lib/rayo/models/status_page.rb +31 -0
- data/lib/rayo/storage.rb +127 -0
- data/lib/rayo/tag_context.rb +18 -0
- data/lib/rayo/taggable.rb +19 -0
- data/lib/rayo/tags/content_tags.rb +46 -0
- data/lib/rayo/tags/navigation_tags.rb +63 -0
- data/lib/rayo/tags/property_tags.rb +25 -0
- data/lib/rayo/version.rb +9 -0
- metadata +125 -0
data/lib/rayo.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), 'storage.rb')
|
4
|
+
require File.join(File.dirname(__FILE__), 'config.rb')
|
5
|
+
|
6
|
+
class Rayo::Application < Sinatra::Base
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
attr_accessor :config # Application configuration object
|
11
|
+
|
12
|
+
# Configure application
|
13
|
+
def configure
|
14
|
+
yield @config ||= Rayo::Config.new
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def config
|
20
|
+
self.class.config
|
21
|
+
end
|
22
|
+
|
23
|
+
get '/' do
|
24
|
+
redirect_to_lang '' # Root page
|
25
|
+
end
|
26
|
+
|
27
|
+
get '*/' do |path|
|
28
|
+
redirect path # Remove trailing slashes
|
29
|
+
end
|
30
|
+
|
31
|
+
get '/*' do |path|
|
32
|
+
path = path.split '/' # Split path into segments
|
33
|
+
|
34
|
+
return redirect_to_lang path unless config.languages.include? path.first
|
35
|
+
|
36
|
+
lang = path.shift # Determine language
|
37
|
+
storage = Rayo::Storage.new( config, lang ) # Page storage
|
38
|
+
page = storage.page( path ) # Find page by path
|
39
|
+
page = storage.status_page( path, 404 ) unless page && page.file # Render 404 page if there are no page, or there are no file
|
40
|
+
|
41
|
+
[ page[:status], page.render ] # Return page status and content
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def select_language
|
47
|
+
config.languages.first
|
48
|
+
end
|
49
|
+
|
50
|
+
def redirect_to_lang( path )
|
51
|
+
redirect [select_language, *path].join '/'
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/lib/rayo/config.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'taggable.rb')
|
2
|
+
require File.join(File.dirname(__FILE__), 'tags/property_tags.rb')
|
3
|
+
require File.join(File.dirname(__FILE__), 'tags/content_tags.rb')
|
4
|
+
require File.join(File.dirname(__FILE__), 'tags/navigation_tags.rb')
|
5
|
+
|
6
|
+
class Rayo::Config
|
7
|
+
|
8
|
+
attr_accessor :content_dir
|
9
|
+
attr_accessor :languages
|
10
|
+
attr_accessor :page_exts
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@languages = ['en']
|
14
|
+
@page_exts = ['.yml']
|
15
|
+
|
16
|
+
@filters = {}
|
17
|
+
|
18
|
+
# Default filters
|
19
|
+
add_filter('html'){|source| source }
|
20
|
+
|
21
|
+
@tagger = Object.new
|
22
|
+
@tagger.extend Rayo::Taggable
|
23
|
+
|
24
|
+
# Default tags
|
25
|
+
add_tags Rayo::Tags::PropertyTags
|
26
|
+
add_tags Rayo::Tags::ContentTags
|
27
|
+
add_tags Rayo::Tags::NavigationTags
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add tags defined in module
|
31
|
+
def add_tags( tag_module )
|
32
|
+
@tagger.extend tag_module
|
33
|
+
end
|
34
|
+
|
35
|
+
# Add filter
|
36
|
+
def add_filter( ext, &filter )
|
37
|
+
@filters[".#{ext}"] = filter
|
38
|
+
end
|
39
|
+
|
40
|
+
# Create new object containing all defined tags
|
41
|
+
def create_tagger
|
42
|
+
@tagger.clone
|
43
|
+
end
|
44
|
+
|
45
|
+
def directory( content_type )
|
46
|
+
File.join( @content_dir, content_type.to_s )
|
47
|
+
end
|
48
|
+
|
49
|
+
def renderable_exts
|
50
|
+
@filters.keys
|
51
|
+
end
|
52
|
+
|
53
|
+
def filter( ext )
|
54
|
+
@filters[ ext.to_s ]
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'erubis'
|
3
|
+
require 'radius'
|
4
|
+
|
5
|
+
require File.join(File.dirname(__FILE__), '..', 'tag_context.rb')
|
6
|
+
|
7
|
+
class Rayo::Models::Page
|
8
|
+
|
9
|
+
attr_reader :storage, :parent, :path
|
10
|
+
|
11
|
+
def initialize( storage, parent, path )
|
12
|
+
@storage = storage
|
13
|
+
@parent = parent
|
14
|
+
@path = path
|
15
|
+
end
|
16
|
+
|
17
|
+
def descendant( relative_path )
|
18
|
+
relative_path.inject( self ) {|page,slug| page.child( slug ) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def children
|
22
|
+
@children ||= @storage.find_pages( directories ).map{|name| child( name ) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def child( slug )
|
26
|
+
@children_cache ||= {}
|
27
|
+
return @children_cache[ slug ] if @children_cache.include? slug
|
28
|
+
|
29
|
+
page = Rayo::Models::Page.new( @storage, self, @path + [slug] )
|
30
|
+
page = nil if page.file.nil? && page.directories.empty?
|
31
|
+
|
32
|
+
@children_cache[ slug ] = page
|
33
|
+
end
|
34
|
+
|
35
|
+
def directories
|
36
|
+
@directories ||= @storage.find_page_dirs( @parent.directories, @path.last )
|
37
|
+
end
|
38
|
+
|
39
|
+
def file
|
40
|
+
@file ||= @storage.find_page_file( @parent.directories, @path.last )
|
41
|
+
end
|
42
|
+
|
43
|
+
def parts
|
44
|
+
@parts ||= file ? @storage.find_page_parts( file ) : {}
|
45
|
+
end
|
46
|
+
|
47
|
+
def params
|
48
|
+
return @params if @params
|
49
|
+
|
50
|
+
segments = file[0..-(File.extname(file).length+1)].split(/[\/\\]/)[-@path.size..-1] || raise( "File doesn't correspond to path" )
|
51
|
+
|
52
|
+
@params = {}
|
53
|
+
|
54
|
+
segments.each_with_index do |segment,i|
|
55
|
+
@params[segment[1..-1]] = @path[i] if segment[0..0] == '%'
|
56
|
+
end
|
57
|
+
|
58
|
+
@params['path'] = path
|
59
|
+
@params
|
60
|
+
end
|
61
|
+
|
62
|
+
def context
|
63
|
+
return @context if @context
|
64
|
+
|
65
|
+
@context = @parent ? @parent.context.merge({ 'status' => 200 }) : { 'status' => 200 }
|
66
|
+
@context.merge! load_context( file ) if file
|
67
|
+
@context
|
68
|
+
end
|
69
|
+
|
70
|
+
def layout
|
71
|
+
@layout ||= @storage.layout( context['layout'] )
|
72
|
+
end
|
73
|
+
|
74
|
+
def []( key )
|
75
|
+
key = key.to_s
|
76
|
+
|
77
|
+
context[ key ] || params[ key ]
|
78
|
+
end
|
79
|
+
|
80
|
+
def render
|
81
|
+
layout.render( parser )
|
82
|
+
end
|
83
|
+
|
84
|
+
def parser
|
85
|
+
@parser ||= Radius::Parser.new( Rayo::TagContext.new( self ), :tag_prefix => 'r' )
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def load_context( filename )
|
91
|
+
YAML::load( Erubis::Eruby.new( File.read( filename ) ).result( params ) )
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Rayo::Models::Renderable
|
2
|
+
|
3
|
+
attr_reader :file
|
4
|
+
attr_reader :filter
|
5
|
+
|
6
|
+
def initialize( file, filter )
|
7
|
+
@file = file
|
8
|
+
@filter = filter
|
9
|
+
end
|
10
|
+
|
11
|
+
def source
|
12
|
+
@source ||= File.read( file )
|
13
|
+
end
|
14
|
+
|
15
|
+
def render( parser )
|
16
|
+
filter.call( parser.parse( source ) )
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'page.rb')
|
2
|
+
require File.join(File.dirname(__FILE__), 'status_page.rb')
|
3
|
+
|
4
|
+
class Rayo::Models::RootPage < Rayo::Models::Page
|
5
|
+
|
6
|
+
def initialize( storage )
|
7
|
+
super( storage, nil, [] )
|
8
|
+
end
|
9
|
+
|
10
|
+
def directories
|
11
|
+
[ @storage.config.directory :pages ]
|
12
|
+
end
|
13
|
+
|
14
|
+
def file
|
15
|
+
@file ||= @storage.find_page_file( directories, 'index' )
|
16
|
+
end
|
17
|
+
|
18
|
+
def params
|
19
|
+
@params ||= { 'path' => path }
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'page.rb')
|
2
|
+
|
3
|
+
class Rayo::Models::StatusPage < Rayo::Models::Page
|
4
|
+
|
5
|
+
def initialize( storage, root, path, status )
|
6
|
+
super( storage, root, path )
|
7
|
+
|
8
|
+
@status = status
|
9
|
+
end
|
10
|
+
|
11
|
+
def directories
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
def file
|
16
|
+
@file ||= @storage.find_page_file( @parent.directories, @status.to_s )
|
17
|
+
end
|
18
|
+
|
19
|
+
def context
|
20
|
+
return @context if @context
|
21
|
+
|
22
|
+
@context = @parent ? @parent.context.merge({ 'status' => @status }) : { 'status' => @status }
|
23
|
+
@context.merge! load_context( file + '.yml' ) if file
|
24
|
+
@context
|
25
|
+
end
|
26
|
+
|
27
|
+
def params
|
28
|
+
{ 'path' => path }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/lib/rayo/storage.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'models', 'root_page.rb')
|
2
|
+
require File.join(File.dirname(__FILE__), 'models', 'renderable.rb')
|
3
|
+
|
4
|
+
class Rayo::Storage
|
5
|
+
|
6
|
+
attr_reader :config
|
7
|
+
|
8
|
+
def initialize( config, lang )
|
9
|
+
@config = config
|
10
|
+
|
11
|
+
@lang = lang
|
12
|
+
@lang_prefix = '.' + lang
|
13
|
+
|
14
|
+
@layouts = {}
|
15
|
+
@snippets = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def snippet( name )
|
19
|
+
@snipetts[name.to_s] ||= find_renderable_file( :snippets, name.to_s ) || raise( "Snippet '#{name}' not found" )
|
20
|
+
end
|
21
|
+
|
22
|
+
def layout( name )
|
23
|
+
@layouts[name.to_s] ||= find_renderable( :layouts, name.to_s ) || raise( "Layout '#{name}' not found" )
|
24
|
+
end
|
25
|
+
|
26
|
+
def root_page
|
27
|
+
@root_page ||= Rayo::Models::RootPage.new( self )
|
28
|
+
end
|
29
|
+
|
30
|
+
def page( path )
|
31
|
+
root_page.descendant( path )
|
32
|
+
end
|
33
|
+
|
34
|
+
def status_page( path, status )
|
35
|
+
Rayo::Models::StatusPage.new( self, root_page, path, status )
|
36
|
+
end
|
37
|
+
|
38
|
+
def find_renderable( type, name )
|
39
|
+
if file = find_file( [config.directory( type )], name, config.renderable_exts )
|
40
|
+
renderable( file, File.extname( file ) )
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_page_file( dirs, slug )
|
45
|
+
find_file( dirs, slug, config.page_exts )
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_page_dirs( dirs, slug )
|
49
|
+
find_files dirs, slug, ['']
|
50
|
+
end
|
51
|
+
|
52
|
+
def find_pages( dirs )
|
53
|
+
find_files dirs, '*', config.page_exts + ['']
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_page_parts( page_file )
|
57
|
+
parts = {}
|
58
|
+
page_file_base = File.basename( page_file, File.extname( page_file ) )
|
59
|
+
glob_files File.dirname( page_file ), page_file_base + '*', config.renderable_exts do |file,base,ext|
|
60
|
+
elems = base.split('.')
|
61
|
+
|
62
|
+
if elems.shift == page_file_base # Remove base (slug or variable)
|
63
|
+
if elems.size == 0 # There are no part name and language
|
64
|
+
parts[ 'body' ] ||= renderable( file, ext )
|
65
|
+
elsif elems.size == 1 # There are no language or no part name
|
66
|
+
parts[ elems[0] ] ||= renderable( file, ext )
|
67
|
+
parts[ 'body' ] ||= renderable( file, ext ) if elems[1] == @lang
|
68
|
+
else
|
69
|
+
parts[ elems[0] ] ||= renderable( file, ext ) if elems[1] == @lang
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
parts
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def renderable( file, ext )
|
79
|
+
Rayo::Models::Renderable.new( file, config.filter( ext ) || raise( "Filter for '#{ext} not found" ) )
|
80
|
+
end
|
81
|
+
|
82
|
+
# Find first file with given name (or variable) and extension from given set
|
83
|
+
def find_file( dirs, name, exts )
|
84
|
+
glob_files( dirs, name, exts ) { |file,base,ext| return file }
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
|
88
|
+
# Find files with given name (or variable) and extension from given set
|
89
|
+
def find_files( dirs, name, exts )
|
90
|
+
results = []
|
91
|
+
glob_files( dirs, name, exts ) { |file,base,ext| results << file }
|
92
|
+
results
|
93
|
+
end
|
94
|
+
|
95
|
+
def glob_files( dirs, name, exts, &block )
|
96
|
+
glob dirs, name + @lang_prefix, //, exts, &block # Search with given name and language
|
97
|
+
glob dirs, name, //, exts, &block # Search with given name without language
|
98
|
+
glob dirs, '%*' + @lang_prefix, /^%.+\.#{@lang}$/, exts, &block # Search with variable and language
|
99
|
+
glob dirs, '%*', /^%.+$/, exts, &block # Search with variable without language
|
100
|
+
end
|
101
|
+
|
102
|
+
def glob( dirs, mask_wo_ext, base_regexp, exts )
|
103
|
+
mask = mask_wo_ext + ext_mask( exts )
|
104
|
+
|
105
|
+
dirs.each do |dir|
|
106
|
+
Dir.glob File.join( dir, mask ) do |file|
|
107
|
+
ext = File.extname( file )
|
108
|
+
base = File.basename( file, ext )
|
109
|
+
|
110
|
+
yield file, base, ext if exts.include?( ext ) && base =~ base_regexp
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def ext_mask( exts )
|
116
|
+
if exts.size == 1 # Only one extension
|
117
|
+
exts.first # Use it in mask
|
118
|
+
elsif !exts.include? '' # No empty extension
|
119
|
+
'.*' # Use any extension mask
|
120
|
+
elsif mask_wo_ext[-1..-1] == '*' # Mask ends with star
|
121
|
+
'' # No need for another star
|
122
|
+
else
|
123
|
+
'*' # Any prefix
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Rayo::TagContext < Radius::Context
|
2
|
+
|
3
|
+
attr_reader :page
|
4
|
+
|
5
|
+
def initialize(page)
|
6
|
+
super()
|
7
|
+
|
8
|
+
@page = page
|
9
|
+
|
10
|
+
globals.page = @page
|
11
|
+
|
12
|
+
tagger = @page.storage.config.create_tagger
|
13
|
+
tagger.methods.each do |name|
|
14
|
+
define_tag(name[4..-1]) { |tag_binding| tagger.send name, tag_binding } if name[0..3] == 'tag:'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Rayo::Taggable
|
2
|
+
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
def tag( name, &block )
|
6
|
+
define_method("tag:#{name}", &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.extend(ClassMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
def error( text )
|
16
|
+
"<strong class=\"error\">#{text}</strong>"
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Rayo::Tags::ContentTags
|
2
|
+
|
3
|
+
include Rayo::Taggable
|
4
|
+
|
5
|
+
tag 'content' do |tag|
|
6
|
+
part_name = tag.attr['part'] || 'body'
|
7
|
+
inherit = tag.attr['inherit'] == 'true'
|
8
|
+
|
9
|
+
page = tag.locals.page
|
10
|
+
part = page.parts[part_name]
|
11
|
+
|
12
|
+
while inherit && !part && page.parent do
|
13
|
+
page = page.parent
|
14
|
+
part = page.parts[part_name]
|
15
|
+
end
|
16
|
+
|
17
|
+
if part
|
18
|
+
part.render( tag.globals.page.parser )
|
19
|
+
else
|
20
|
+
error "No part '#{part_name}' found for page '#{tag.locals.page.path}'"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
tag 'content_for_layout' do |tag|
|
25
|
+
send 'tag:content', tag
|
26
|
+
end
|
27
|
+
|
28
|
+
tag 'snippet' do |tag|
|
29
|
+
number = (tag.attr['times'] || '1').to_i
|
30
|
+
result = ''
|
31
|
+
number.times { result << tag.expand }
|
32
|
+
result
|
33
|
+
end
|
34
|
+
|
35
|
+
tag 'hello' do
|
36
|
+
'Hello world'
|
37
|
+
end
|
38
|
+
|
39
|
+
tag 'repeat' do |tag|
|
40
|
+
number = (tag.attr['times'] || '1').to_i
|
41
|
+
result = ''
|
42
|
+
number.times { result << tag.expand }
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Rayo::Tags::NavigationTags
|
2
|
+
|
3
|
+
include Rayo::Taggable
|
4
|
+
|
5
|
+
tag 'find' do |tag|
|
6
|
+
url = tag.attr['url']
|
7
|
+
path = url.split('/')
|
8
|
+
|
9
|
+
if path.first.empty?
|
10
|
+
path.shift
|
11
|
+
page = tag.locals.page.storage.root_page
|
12
|
+
else
|
13
|
+
page = tag.locals.page
|
14
|
+
end
|
15
|
+
|
16
|
+
page = page.descendant( path )
|
17
|
+
|
18
|
+
if page
|
19
|
+
tag.locals.page = page
|
20
|
+
tag.expand
|
21
|
+
else
|
22
|
+
error "No page '#{url}' found"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
tag 'children' do |tag|
|
27
|
+
tag.locals.children = tag.locals.page.children
|
28
|
+
tag.expand
|
29
|
+
end
|
30
|
+
|
31
|
+
tag 'children:count' do |tag|
|
32
|
+
tag.locals.children.size
|
33
|
+
end
|
34
|
+
|
35
|
+
tag 'children:first' do |tag|
|
36
|
+
if first = tag.locals.children.first
|
37
|
+
tag.locals.page = first
|
38
|
+
tag.expand
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
tag 'children:last' do |tag|
|
43
|
+
if first = tag.locals.children.last
|
44
|
+
tag.locals.page = first
|
45
|
+
tag.expand
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
tag 'children:each' do |tag|
|
50
|
+
result = ''
|
51
|
+
|
52
|
+
children = tag.locals.children
|
53
|
+
children.each_with_index do |item, i|
|
54
|
+
tag.locals.child = item
|
55
|
+
tag.locals.page = item
|
56
|
+
tag.locals.first_child = i == 0
|
57
|
+
tag.locals.last_child = i == children.length - 1
|
58
|
+
result << tag.expand
|
59
|
+
end
|
60
|
+
result
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Rayo::Tags::PropertyTags
|
2
|
+
|
3
|
+
include Rayo::Taggable
|
4
|
+
|
5
|
+
tag 'title' do |tag|
|
6
|
+
tag.locals.page.context['title']
|
7
|
+
end
|
8
|
+
|
9
|
+
tag 'path' do |tag|
|
10
|
+
curpath = tag.globals.page.path
|
11
|
+
path = tag.locals.page.path
|
12
|
+
|
13
|
+
i = 0
|
14
|
+
while i < path.size && i < curpath.size && path[i] == curpath[i] do
|
15
|
+
i = i + 1
|
16
|
+
end
|
17
|
+
|
18
|
+
'../' * (curpath.size - i) + path[i..-1].join('/')
|
19
|
+
end
|
20
|
+
|
21
|
+
tag 'link' do |tag|
|
22
|
+
"<a href=\"#{send 'tag:path', tag}\">#{tag.locals.page.context['title']}</a>"
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/rayo/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rayo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Alexey Noskov
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-10-18 00:00:00 +04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: erubis
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: radius
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: sinatra
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 15
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 0
|
61
|
+
version: "1.0"
|
62
|
+
type: :runtime
|
63
|
+
version_requirements: *id003
|
64
|
+
description: It's lightweight CMS based on Sinatra framework, where data are stored in file system (so you may use Git power) and enhanced Radius gem.
|
65
|
+
email:
|
66
|
+
- alexey.noskov@gmail.com
|
67
|
+
executables: []
|
68
|
+
|
69
|
+
extensions: []
|
70
|
+
|
71
|
+
extra_rdoc_files: []
|
72
|
+
|
73
|
+
files:
|
74
|
+
- lib/rayo.rb
|
75
|
+
- lib/rayo/storage.rb
|
76
|
+
- lib/rayo/application.rb
|
77
|
+
- lib/rayo/version.rb
|
78
|
+
- lib/rayo/taggable.rb
|
79
|
+
- lib/rayo/models/root_page.rb
|
80
|
+
- lib/rayo/models/page.rb
|
81
|
+
- lib/rayo/models/status_page.rb
|
82
|
+
- lib/rayo/models/renderable.rb
|
83
|
+
- lib/rayo/tags/property_tags.rb
|
84
|
+
- lib/rayo/tags/content_tags.rb
|
85
|
+
- lib/rayo/tags/navigation_tags.rb
|
86
|
+
- lib/rayo/config.rb
|
87
|
+
- lib/rayo/tag_context.rb
|
88
|
+
has_rdoc: true
|
89
|
+
homepage: http://github.com/alno/rayo
|
90
|
+
licenses: []
|
91
|
+
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
hash: 3
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
version: "0"
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
hash: 23
|
112
|
+
segments:
|
113
|
+
- 1
|
114
|
+
- 3
|
115
|
+
- 6
|
116
|
+
version: 1.3.6
|
117
|
+
requirements: []
|
118
|
+
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 1.3.7
|
121
|
+
signing_key:
|
122
|
+
specification_version: 3
|
123
|
+
summary: Lightweight CMS based on Sinatra and Radius
|
124
|
+
test_files: []
|
125
|
+
|