rhyhann-merb_stathyc_slice 0.1

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.
Files changed (41) hide show
  1. data/LICENSE +21 -0
  2. data/README.markdown +106 -0
  3. data/Rakefile +55 -0
  4. data/TODO +5 -0
  5. data/app/controllers/application.rb +3 -0
  6. data/app/controllers/pages.rb +62 -0
  7. data/app/helpers/application_helper.rb +136 -0
  8. data/app/helpers/pages_helper.rb +49 -0
  9. data/app/models/page.rb +49 -0
  10. data/app/views/layout/static_slice.html.haml +27 -0
  11. data/app/views/pages/_cud.html.haml +11 -0
  12. data/app/views/pages/_sidebar.html.haml +2 -0
  13. data/app/views/pages/delete.html.haml +2 -0
  14. data/app/views/pages/edit.html.haml +6 -0
  15. data/app/views/pages/index.html.haml +5 -0
  16. data/app/views/pages/new.html.haml +6 -0
  17. data/app/views/pages/show.html.haml +5 -0
  18. data/lib/static_slice.rb +85 -0
  19. data/lib/static_slice/merbtasks.rb +103 -0
  20. data/lib/static_slice/slicetasks.rb +18 -0
  21. data/lib/static_slice/spectasks.rb +65 -0
  22. data/public/images/css/banner_mountains.jpg +0 -0
  23. data/public/images/css/bg.png +0 -0
  24. data/public/images/css/bg02-blue-left.png +0 -0
  25. data/public/images/css/bg02-blue-right.png +0 -0
  26. data/public/images/css/bg02-left.png +0 -0
  27. data/public/images/css/bg02-right.png +0 -0
  28. data/public/images/css/bg02-white-left.png +0 -0
  29. data/public/images/css/bg02-white-right.png +0 -0
  30. data/public/images/css/logo.png +0 -0
  31. data/public/images/css/menu.png +0 -0
  32. data/public/images/css/menuleft.png +0 -0
  33. data/public/images/css/menuright.png +0 -0
  34. data/public/stylesheets/master.css +138 -0
  35. data/spec/models/page_spec.rb +7 -0
  36. data/spec/requests/pages_spec.rb +110 -0
  37. data/spec/spec_helper.rb +43 -0
  38. data/spec/static_slice_spec.rb +19 -0
  39. data/stubs/app/controllers/application.rb +2 -0
  40. data/stubs/app/controllers/main.rb +2 -0
  41. metadata +118 -0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ (The MIT/X11 License)
2
+
3
+ Copyright (c) <2008> <Othmane Benkirane>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,106 @@
1
+ /!\ My version numbers mean that they are stable when they are pair (2,4,6,8…) and
2
+ nearly bugfree when they finish with a 0 (10,20,30) so if you see version 1, just know
3
+ that it's not meant for production now!
4
+
5
+ StaticSlice
6
+ ===========
7
+
8
+ A slice for the Merb framework that provides the core static pages functionnalities.
9
+ Just see the views for edit.
10
+
11
+ To see all available tasks for StaticSlice run:
12
+ rake -T slices:static_slice
13
+
14
+ CUD Customization
15
+ -----------------
16
+
17
+ If you want to protect the CUD actions, you must know that: ALL of them are located in
18
+ a content named *for_cud*. simple.
19
+ If you want to change the look of the CUD operations, it's stored in a partial named *_cud*.
20
+ But _please see the default one first_.
21
+
22
+ Sidebar
23
+ -------
24
+
25
+ A partial called *_sidebar* may help you with Sidebar customization.
26
+
27
+ Installation
28
+ ============
29
+
30
+ * dependency (config/init.rb)
31
+
32
+ \# add the slice as a regular dependency
33
+ dependency 'static_slice'
34
+
35
+ * router
36
+
37
+ \# example: /static_slice/:controller/:action/:id
38
+ add_slice(:StaticSlice)
39
+ \# example: /foo/:controller/:action/:id
40
+ add_slice(:StaticSlice, 'foo') # same as :path => 'foo'
41
+ \# example: /:lang/:controller/:action/:id
42
+ add_slice(:StaticSlice, :path => ':lang')
43
+ \# example: /:controller/:action/:id
44
+ slice(:StaticSlice)
45
+
46
+ * rake
47
+
48
+ rake slices:static_slice:install
49
+
50
+ Uses
51
+ ====
52
+
53
+ You can put your overrides here:
54
+ host-app/slices/static_slice/app - controllers, models, views ...
55
+
56
+ Templates are located in this order:
57
+ 1. host-app/slices/static_slice/app/views/*
58
+ 2. gems/static_slice/app/views/*
59
+ 3. host-app/app/views/*
60
+
61
+ You can use the host application's layout by configuring the
62
+ static_slice slice in a before_app_loads block:
63
+
64
+ Merb::Slices.config[:static_slice] = { :layout => :application }
65
+
66
+ By default :static_slice is used. If you need to override
67
+ stylesheets or javascripts, just specify your own files in your layout
68
+ instead/in addition to the ones supplied (if any) in
69
+ host-app/public/slices/static_slice.
70
+
71
+ In any case don't edit those files directly as they may be clobbered any time
72
+ rake static_slice:install is run.
73
+
74
+ About Slices
75
+ ============
76
+
77
+ Merb-Slices is a Merb plugin for using and creating application 'slices' which
78
+ help you modularize your application. Usually these are reuseable extractions
79
+ from your main app. In effect, a Slice is just like a regular Merb MVC
80
+ application, both in functionality as well as in structure.
81
+
82
+ When you generate a Slice stub structure, a module is setup to serve as a
83
+ namespace for your controller, models, helpers etc. This ensures maximum
84
+ encapsulation. You could say a Slice is a mixture between a Merb plugin (a
85
+ Gem) and a Merb application, reaping the benefits of both.
86
+
87
+ A host application can 'mount' a Slice inside the router, which means you have
88
+ full over control how it integrates. By default a Slice's routes are prefixed
89
+ by its name (a router :namespace), but you can easily provide your own prefix
90
+ or leave it out, mounting it at the root of your url-schema. You can even
91
+ mount a Slice multiple times and give extra parameters to customize an
92
+ instance's behaviour.
93
+
94
+ A Slice's Application controller uses controller_for_slice to setup slice
95
+ specific behaviour, which mainly affects cascaded view handling. Additionaly,
96
+ this method is available to any kind of controller, so it can be used for
97
+ Merb Mailer too for example.
98
+
99
+ There are many ways which let you customize a Slice's functionality and
100
+ appearance without ever touching the Gem-level code itself. It's not only easy
101
+ to add template/layout overrides, you can also add/modify controllers, models
102
+ and other runtime code from within the host application.
103
+
104
+ To create your own Slice run this (somewhere outside of your merb app):
105
+
106
+ merb-gen slice <your-lowercase-slice-name>
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ require 'merb-core'
5
+ require 'merb-core/tasks/merb'
6
+
7
+ GEM_NAME = "merb_stathyc_slice"
8
+ AUTHOR = "Othmane Benkirane (rhyhann)"
9
+ EMAIL = "eo-in-rhyhann-net"
10
+ HOMEPAGE = "http://github.com/rhyhann/merb-stathyc_slice"
11
+ SUMMARY = "Merb Slice that provides core static pages functionnalities"
12
+ GEM_VERSION = "0.1"
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.rubyforge_project = 'merb'
16
+ s.name = GEM_NAME
17
+ s.version = GEM_VERSION
18
+ s.platform = Gem::Platform::RUBY
19
+ s.has_rdoc = true
20
+ s.extra_rdoc_files = ["README.markdown", "LICENSE", 'TODO']
21
+ s.summary = SUMMARY
22
+ s.description = s.summary
23
+ s.author = AUTHOR
24
+ s.email = EMAIL
25
+ s.homepage = HOMEPAGE
26
+ s.add_dependency('merb-slices', '>= 1.0')
27
+ s.require_path = 'lib'
28
+ s.files = %w(LICENSE README.markdown Rakefile TODO) + Dir.glob("{lib,spec,app,public,stubs}/**/*")
29
+ end
30
+
31
+ Rake::GemPackageTask.new(spec) do |pkg|
32
+ pkg.gem_spec = spec
33
+ end
34
+
35
+ desc "Install the gem"
36
+ task :install do
37
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
38
+ end
39
+
40
+ desc "Uninstall the gem"
41
+ task :uninstall do
42
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
43
+ end
44
+
45
+ desc "Create a gemspec file"
46
+ task :gemspec do
47
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
48
+ file.puts spec.to_ruby
49
+ end
50
+ end
51
+
52
+ require 'spec/rake/spectask'
53
+ require 'merb-core/test/tasks/spectasks'
54
+ desc 'Default: run spec examples'
55
+ task :default => 'spec'
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ TODO:
2
+
3
+ - Specs
4
+ - CUD partial
5
+
@@ -0,0 +1,3 @@
1
+ class StaticSlice::Application < Merb::Controller
2
+ controller_for_slice
3
+ end
@@ -0,0 +1,62 @@
1
+ class StaticSlice::Pages < StaticSlice::Application
2
+ # provides :xml, :yaml, :js
3
+ def index
4
+ @pages = Page.all
5
+ display @pages
6
+ end
7
+
8
+ def show(id)
9
+ @page = Page.get(id)
10
+ raise NotFound unless @page
11
+ display @page
12
+ end
13
+
14
+ def new
15
+ only_provides :html
16
+ @page = Page.new
17
+ display @page
18
+ end
19
+
20
+ def edit(id)
21
+ only_provides :html
22
+ @page = Page.get(id)
23
+ raise NotFound unless @page
24
+ display @page
25
+ end
26
+
27
+ def create(page)
28
+ @page = Page.new(page)
29
+ if @page.save
30
+ redirect resource(@page), :message => {:notice => "Page was successfully created"}
31
+ else
32
+ message[:error] = "Page failed to be created"
33
+ render :new
34
+ end
35
+ end
36
+
37
+ def update(id, page)
38
+ @page = Page.get(id)
39
+ raise NotFound unless @page
40
+ if @page.update_attributes(page)
41
+ redirect resource(@page)
42
+ else
43
+ display @page, :edit
44
+ end
45
+ end
46
+
47
+ def delete(id)
48
+ @page = Page.get(id)
49
+ raise NotFound unless @page
50
+ display @page
51
+ end
52
+ def destroy(id)
53
+ @page = Page.get(id)
54
+ raise NotFound unless @page
55
+ if @page.destroy
56
+ redirect resource(:pages)
57
+ else
58
+ raise InternalServerError
59
+ end
60
+ end
61
+
62
+ end # Pages
@@ -0,0 +1,136 @@
1
+ module Merb
2
+ module StaticSlice
3
+ module ApplicationHelper
4
+
5
+ # @param *segments<Array[#to_s]> Path segments to append.
6
+ #
7
+ # @return <String>
8
+ # A path relative to the public directory, with added segments.
9
+ def image_path(*segments)
10
+ public_path_for(:image, *segments)
11
+ end
12
+
13
+ # @param *segments<Array[#to_s]> Path segments to append.
14
+ #
15
+ # @return <String>
16
+ # A path relative to the public directory, with added segments.
17
+ def javascript_path(*segments)
18
+ public_path_for(:javascript, *segments)
19
+ end
20
+
21
+ # @param *segments<Array[#to_s]> Path segments to append.
22
+ #
23
+ # @return <String>
24
+ # A path relative to the public directory, with added segments.
25
+ def stylesheet_path(*segments)
26
+ public_path_for(:stylesheet, *segments)
27
+ end
28
+
29
+ # Construct a path relative to the public directory
30
+ #
31
+ # @param <Symbol> The type of component.
32
+ # @param *segments<Array[#to_s]> Path segments to append.
33
+ #
34
+ # @return <String>
35
+ # A path relative to the public directory, with added segments.
36
+ def public_path_for(type, *segments)
37
+ ::StaticSlice.public_path_for(type, *segments)
38
+ end
39
+
40
+ # Construct an app-level path.
41
+ #
42
+ # @param <Symbol> The type of component.
43
+ # @param *segments<Array[#to_s]> Path segments to append.
44
+ #
45
+ # @return <String>
46
+ # A path within the host application, with added segments.
47
+ def app_path_for(type, *segments)
48
+ ::StaticSlice.app_path_for(type, *segments)
49
+ end
50
+
51
+ # Construct a slice-level path.
52
+ #
53
+ # @param <Symbol> The type of component.
54
+ # @param *segments<Array[#to_s]> Path segments to append.
55
+ #
56
+ # @return <String>
57
+ # A path within the slice source (Gem), with added segments.
58
+ def slice_path_for(type, *segments)
59
+ ::StaticSlice.slice_path_for(type, *segments)
60
+ end
61
+
62
+
63
+
64
+ # This function takes the Model.sexhy hash and guesses the untyped variables, sorts it
65
+ # and then returns the incredible formù!
66
+ def sexify(object, f_d = {:properties => {}})
67
+ f = ''
68
+ f_d = object_labels(object, object_types(object))
69
+ f_d[:properties].delete_if {|k,v| [:id,:created_at,:updated_at].include?(k)}
70
+ f_d[:properties].to_a.sort_by {|a|a[1][:order]}.each do |element|
71
+ type, options = element[0], element[1]
72
+ # TODO: default hashes
73
+ html = object.class.sexhy[:html]
74
+ f << nl(open_tag(:div))
75
+ f << nl(html[:label][:tag],
76
+ options[:label],
77
+ html[:label][:attributes].merge(
78
+ {:for => "#{object.class.to_s.downcase}_#{type.to_s}"}
79
+ )
80
+ )
81
+ eval "f << nl(html[:input][:tag],
82
+ (#{options[:input]}(:#{type})).to_s,
83
+ html[:input][:attributes]
84
+ )"
85
+ f << nl(close_tag(:div))
86
+ end
87
+ f
88
+ end
89
+ def order(hash)
90
+ n = 0
91
+ hash[:properties].each do |k,v|
92
+ n+=1
93
+ hash[:properties][k][:order] = n if hash[:properties][k][:order].nil?
94
+ end
95
+ hash
96
+ end
97
+ # This function returns the list of the inputs.
98
+ # It will first try to merge it to the given hash, then to the model's hash
99
+ # then to nothing.
100
+ def object_types(o, c_d = {:properties => {}})
101
+ c_d = o.class.sexhy if c_d == {:properties => {}} && o.class.methods.include?('sexhy')
102
+ c_d = order c_d
103
+ properties = {}
104
+ o.class.properties.each do |pr|
105
+ t = DataMapper::Types
106
+ properties[pr.name] = {}
107
+ properties[pr.name][:input] = if pr.type.is_a?(t::Boolean) ||
108
+ pr.type.is_a?(TrueClass); 'check_box'
109
+ elsif [String, Float, Fixnum,
110
+ Integer, BigDecimal,
111
+ ].include?(pr.type); 'text_field'
112
+ elsif pr.type == t::Text; 'text_area'
113
+ elsif pr.type.is_a?(Date); 'date'
114
+ end
115
+ end
116
+ c_d[:properties].each {|k,v|
117
+ properties[k].merge!(v)}
118
+ {:properties => properties}
119
+ end
120
+ def object_labels(o, c_d = {:properties => {}})
121
+ c_d = o.class.sexhy if c_d == {} && o.class.methods.include?('sexhy')
122
+ properties = {}
123
+ o.class.properties.each do |pr|
124
+ properties[pr.name] = {}
125
+ properties[pr.name][:label] = pr.name.to_s.capitalize
126
+ end
127
+ c_d[:properties].each {|k,v| properties[k].merge!(v)}
128
+ {:properties => properties}
129
+ end
130
+ # This function returns its arguments with new lines
131
+ def nl(*arg)
132
+ arg[0].is_a?(Symbol) ? nl(tag(*arg)) : " \n #{arg[0]}"
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,49 @@
1
+ module Merb
2
+ module PagesHelper
3
+ def sexify(object, form_definition = {})
4
+ f = "\n"
5
+ object.class.properties.each do |pr|
6
+ t = DataMapper::Types
7
+ if pr.type.is_a?(t::Boolean) || pr.type.is_a?(TrueClass)
8
+ f << nl(label(:"#{pr.name}"))
9
+ f << nl(check_box(:"#{pr.name}"))
10
+ elsif [String, Float, Fixnum, Integer, BigDecimal].include?(pr.type)
11
+ f << nl(label(:"#{pr.name}"))
12
+ f << nl(text_field(:"#{pr.name}"))
13
+ elsif pr.type == t::Text
14
+ f << nl(label( :"#{pr.name}" ))
15
+ f << nl(text_area(:"#{pr.name}"))
16
+ elsif pr.type.is_a?(Date)
17
+ dater = "\n"
18
+ f << tag(:label, :class => :date) do
19
+ yearc = (Time.now.year-100..Time.now.year)
20
+ dater << select(:"#{pr.name}_month", :collection => (1..12).to_a); dater << " / "
21
+ dater << select(:"#{pr.name}_day" , :collection => (1..31).to_a); dater << " / "
22
+ dater << select(:"#{pr.name}_year" , :collection => (yearc).to_a); dater << " / "
23
+ dater
24
+ end
25
+ end
26
+ end
27
+ f
28
+ end
29
+ def hy_guess_type(object)
30
+ object.class.properties.each do |pr|
31
+ t = DataMapper::Types
32
+ inputs = {}
33
+ inputs[:"#{pr.name}"] = if pr.type.is_a?(t::Boolean) ||
34
+ pr.type.is_a?(TrueClass); :check_box
35
+ elsif [String, Float, Fixnum,
36
+ Integer, BigDecimal,
37
+ ].include?(pr.type); :text_field
38
+ elsif pr.type == t::Text; :text_area
39
+ elsif pr.type.is_a?(Date); :date
40
+ end
41
+ inputs
42
+ end
43
+ end
44
+ # This function returns its arguments with new lines
45
+ def nl(arg)
46
+ tag(:div, "\n #{arg}\n")
47
+ end
48
+ end
49
+ end # Merb