sibu 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +33 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/config/sibu_manifest.js +2 -0
  6. data/app/assets/javascripts/sibu/sibu.js.erb +3 -0
  7. data/app/assets/stylesheets/sibu/sibu.scss.erb +36 -0
  8. data/app/controllers/sibu/application_controller.rb +6 -0
  9. data/app/controllers/sibu/pages_controller.rb +106 -0
  10. data/app/controllers/sibu/sites_controller.rb +59 -0
  11. data/app/helpers/sibu/application_helper.rb +7 -0
  12. data/app/helpers/sibu/pages_helper.rb +16 -0
  13. data/app/helpers/sibu/sites_helper.rb +4 -0
  14. data/app/jobs/sibu/application_job.rb +4 -0
  15. data/app/mailers/sibu/application_mailer.rb +6 -0
  16. data/app/models/concerns/sibu/image_uploader.rb +3 -0
  17. data/app/models/concerns/sibu/sections_concern.rb +53 -0
  18. data/app/models/sibu/application_record.rb +5 -0
  19. data/app/models/sibu/image.rb +5 -0
  20. data/app/models/sibu/page.rb +11 -0
  21. data/app/models/sibu/site.rb +34 -0
  22. data/app/models/sibu/site_template.rb +4 -0
  23. data/app/views/layouts/sibu/application.html.erb +18 -0
  24. data/app/views/layouts/sibu/edit_content.html.erb +49 -0
  25. data/app/views/layouts/sibu/site.html.erb +21 -0
  26. data/app/views/sibu/pages/_edit_panel.html.erb +19 -0
  27. data/app/views/sibu/pages/_form.html.erb +31 -0
  28. data/app/views/sibu/pages/destroy.html.erb +2 -0
  29. data/app/views/sibu/pages/edit.html.erb +9 -0
  30. data/app/views/sibu/pages/edit_content.html.erb +3 -0
  31. data/app/views/sibu/pages/edit_element.js.erb +4 -0
  32. data/app/views/sibu/pages/index.html.erb +39 -0
  33. data/app/views/sibu/pages/new.html.erb +9 -0
  34. data/app/views/sibu/pages/show.html.erb +1 -0
  35. data/app/views/sibu/pages/update.html.erb +2 -0
  36. data/app/views/sibu/pages/update_element.js.erb +7 -0
  37. data/app/views/sibu/sites/_form.html.erb +15 -0
  38. data/app/views/sibu/sites/destroy.html.erb +2 -0
  39. data/app/views/sibu/sites/edit.html.erb +9 -0
  40. data/app/views/sibu/sites/index.html.erb +37 -0
  41. data/app/views/sibu/sites/new.html.erb +9 -0
  42. data/app/views/sibu/sites/show.html.erb +1 -0
  43. data/app/views/sibu/sites/update.html.erb +2 -0
  44. data/config/initializers/shrine.rb +10 -0
  45. data/config/initializers/tag_helper.rb +75 -0
  46. data/config/routes.rb +17 -0
  47. data/db/migrate/20180124095041_create_sibu_sites.rb +12 -0
  48. data/db/migrate/20180124095213_create_sibu_pages.rb +15 -0
  49. data/db/migrate/20180124145030_create_sibu_site_templates.rb +10 -0
  50. data/db/migrate/20180125231638_add_user_id_to_sites.rb +5 -0
  51. data/db/migrate/20180126114522_rename_url_to_path_in_pages.rb +5 -0
  52. data/db/migrate/20180126114628_add_domain_to_sites.rb +5 -0
  53. data/db/migrate/20180127211533_create_sibu_images.rb +11 -0
  54. data/lib/sibu.rb +5 -0
  55. data/lib/sibu/engine.rb +7 -0
  56. data/lib/sibu/version.rb +3 -0
  57. data/lib/tasks/sibu_tasks.rake +4 -0
  58. metadata +185 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 94fb79f4ed5e7be7da2b75486ef62d4c49d5d480
4
+ data.tar.gz: 36ac40fe3388192c777786841dd34e48288bd932
5
+ SHA512:
6
+ metadata.gz: ff50420aa841d23e9b7eb846ded520e0fafee12e54561a2289872f991ebe0c4aaa6f9645f5b8a00120ca4477cd1223c4e1070582349111777d404c2cda2e0f56
7
+ data.tar.gz: 670a6deddbde376b06cecd419995e2e4864bef2cac6a3c95bb1e6d7ee93ceaa4424434140b401752d9847b5dd24fc4950f95f2be779d7eb43b1391fa668750da
@@ -0,0 +1,20 @@
1
+ Copyright 2018 Jean-Baptiste Vilain
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,33 @@
1
+ # Sibu - A site builder engine for Ruby on Rails
2
+ This is an engine for Ruby on Rails that enables creation of static
3
+ websites in a simple & wysiwyg way.
4
+
5
+ ## Usage
6
+ How to use my plugin.
7
+
8
+ ## Installation
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'sibu'
13
+ ```
14
+
15
+ And then execute:
16
+ ```bash
17
+ $ bundle
18
+ ```
19
+
20
+ Or install it yourself as:
21
+ ```bash
22
+ $ gem install sibu
23
+ ```
24
+
25
+ ## Improvements
26
+ - Use a specific controller & helper for site display
27
+ - Move page templates to SiteTemplate model
28
+
29
+ ## Contributing
30
+ Contribution directions go here.
31
+
32
+ ## License
33
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,36 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Sibu'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ require 'bundler/gem_tasks'
26
+
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'test'
31
+ t.pattern = 'test/**/*_test.rb'
32
+ t.verbose = false
33
+ end
34
+
35
+
36
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/sibu .js
2
+ //= link_directory ../stylesheets/sibu .css
@@ -0,0 +1,3 @@
1
+ //= require jquery
2
+ //= require jquery_ujs
3
+ //= require_self
@@ -0,0 +1,36 @@
1
+ sb-edit,
2
+ [class*='sb-'] {
3
+ position: relative;
4
+
5
+ &:hover > .sb-overlay {
6
+ cursor: pointer;
7
+ display: flex;
8
+ }
9
+ }
10
+
11
+ .sb-overlay {
12
+ position: absolute;
13
+ top: 0;
14
+ left: 0;
15
+ z-index: 999;
16
+ width: 100%;
17
+ height: 100%;
18
+ display: none;
19
+ flex-wrap: wrap;
20
+ align-items: center;
21
+ justify-content: center;
22
+ text-align: center;
23
+
24
+ > * {
25
+ flex: 1 1 0%;
26
+ }
27
+ }
28
+
29
+ #edit_panel {
30
+ position: absolute;
31
+ left: 0;
32
+ bottom: 0;
33
+ width: 100%;
34
+ display: none;
35
+ z-index: 1000;
36
+ }
@@ -0,0 +1,6 @@
1
+ module Sibu
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ before_action Rails.application.config.sibu[:auth_filter]
5
+ end
6
+ end
@@ -0,0 +1,106 @@
1
+ require_dependency "sibu/application_controller"
2
+
3
+ module Sibu
4
+ class PagesController < ApplicationController
5
+ before_action :set_page, only: [:edit, :update, :destroy, :edit_element, :update_element, :edit_section]
6
+ before_action :set_site, only: [:index, :new]
7
+ before_action :set_edit_context, only: [:edit_element, :update_element]
8
+ skip_before_action Rails.application.config.sibu[:auth_filter], only: [:show]
9
+
10
+ def index
11
+ @pages = @site.pages.order(:created_at)
12
+ end
13
+
14
+ def show
15
+ if params[:site_id].blank?
16
+ @site = Sibu::Site.find_by_domain(request.domain)
17
+ if @site
18
+ @page = @site.page(params[:path])
19
+ view_template = @page ? 'show' : @site.not_found
20
+ else
21
+ view_template = Rails.application.config.sibu[:not_found]
22
+ end
23
+ else
24
+ @site = Sibu::Site.find(params[:site_id])
25
+ @page = Sibu::Page.find(params[:id])
26
+ view_template = 'show'
27
+ end
28
+
29
+ render view_template, layout: 'sibu/site'
30
+ end
31
+
32
+ def new
33
+ @page = Sibu::Page.new(site_id: @site.id)
34
+ end
35
+
36
+ def create
37
+ @page = Sibu::Page.new(page_params)
38
+ if @page.save
39
+ redirect_to site_pages_url(@page.site_id), "La page a bien été créée."
40
+ else
41
+ flash.now[:alert] = "Une erreur s'est produite lors de la création de la page."
42
+ render :new
43
+ end
44
+ end
45
+
46
+ def edit
47
+ end
48
+
49
+ def update
50
+ if @page.update(page_params)
51
+ redirect_to site_pages_url(@page.site_id), notice: "La page a bien été mise à jour."
52
+ else
53
+ flash.now[:alert] = "Une erreur s'est produite lors de l'enregistrement de la page."
54
+ render :edit
55
+ end
56
+ end
57
+
58
+ def destroy
59
+ end
60
+
61
+ def edit_content
62
+ @page = Sibu::Page.find(params[:page_id])
63
+ @site = @page.site if @page
64
+ render :edit_content, layout: 'sibu/edit_content'
65
+ end
66
+
67
+ def edit_element
68
+ end
69
+
70
+ def update_element
71
+ @updated = @entity.update_element(@section_id, @element_id, element_params)
72
+ end
73
+
74
+ def edit_section
75
+ end
76
+
77
+ def update_section
78
+ end
79
+
80
+ private
81
+
82
+ def set_page
83
+ @page = Sibu::Page.find(params[:id])
84
+ @site = @page.site if @page
85
+ end
86
+
87
+ def set_site
88
+ @site = Sibu::Site.find(params[:site_id])
89
+ end
90
+
91
+ def set_edit_context
92
+ @entity_type = params[:entity]
93
+ @section_id = params[:section_id]
94
+ @element_id = params[:element_id]
95
+ @entity = @entity_type == 'site' ? @site : @page
96
+ end
97
+
98
+ def page_params
99
+ params.require(:page).permit!
100
+ end
101
+
102
+ def element_params
103
+ params.require(:element).permit!
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,59 @@
1
+ require_dependency "sibu/application_controller"
2
+
3
+ module Sibu
4
+ class SitesController < ApplicationController
5
+ before_action :set_site, only: [:show, :edit, :update, :destroy]
6
+ skip_before_action Rails.application.config.sibu[:auth_filter], only: [:show]
7
+
8
+ def index
9
+ @sites = Sibu::Site.where(user_id: send(Rails.application.config.sibu[:current_user]).id)
10
+ end
11
+
12
+ def show
13
+ @page = @site.page('')
14
+ redirect_to site_page_path(@site.id, @page.id)
15
+ end
16
+
17
+ def new
18
+ @site = Sibu::Site.new(user_id: send(Rails.application.config.sibu[:current_user]).id)
19
+ end
20
+
21
+ def create
22
+ @site = Sibu::Site.new(site_params)
23
+ @site.init_data(:default)
24
+ if @site.save
25
+ redirect_to sites_url, notice: "Le site a bien été créé."
26
+ else
27
+ flash.now[:alert] = "Une erreur s'est produite lors de la création du site."
28
+ render :new
29
+ end
30
+ end
31
+
32
+ def edit
33
+ end
34
+
35
+ def update
36
+ if @site.update(site_params)
37
+ redirect_to sites_url, notice: "Le site a bien été mis à jour."
38
+ else
39
+ flash.now[:alert] = "Une erreur s'est produite lors de l'enregistrement du site."
40
+ render :edit
41
+ end
42
+ end
43
+
44
+ def destroy
45
+ @site.destroy
46
+ redirect_to sites_url, notice: "Le site a bien été supprimé."
47
+ end
48
+
49
+ private
50
+
51
+ def set_site
52
+ @site = Sibu::Site.find(params[:id])
53
+ end
54
+
55
+ def site_params
56
+ params.require(:site).permit!
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,7 @@
1
+ module Sibu
2
+ module ApplicationHelper
3
+ def conf
4
+ Rails.application.config.sibu
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,16 @@
1
+ module Sibu
2
+ module PagesHelper
3
+ def link_path(page_id)
4
+ p = @site.page_by_id(page_id)
5
+ p ? (@site.domain.blank? ? site_page_path(@site.id, p.id) : "/#{p.path}") : "#"
6
+ end
7
+
8
+ def page_templates
9
+ [['Accueil', 'home'], ['Offre', 'offer'], ['Galerie', 'gallery'], ['Destination', 'destination']]
10
+ end
11
+
12
+ def page_languages
13
+ [['Français', 'fr'], ['Anglais', 'en']]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ module Sibu
2
+ module SitesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Sibu
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Sibu
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ class ImageUploader < Shrine
2
+ # plugins and uploading logic
3
+ end
@@ -0,0 +1,53 @@
1
+ module Sibu
2
+ module SectionsConcern
3
+ include ActiveSupport::Concern
4
+
5
+ def section(*ids)
6
+ if ids.length == 1
7
+ s = nil
8
+ if sections.blank?
9
+ self.sections = {}
10
+ else
11
+ s = sections[ids[0]]
12
+ end
13
+ if s.nil?
14
+ s = []
15
+ self.sections[ids[0]] = s
16
+ save
17
+ end
18
+ s
19
+ elsif ids.length == 2
20
+ s = section(ids[0])
21
+ sub = s.select {|elt| elt["id"] == ids[1]}
22
+ unless sub
23
+ sub = {"id" => ids[1], "elements" => []}
24
+ self.sections[ids[0]] << sub
25
+ save
26
+ end
27
+ sub
28
+ end
29
+ end
30
+
31
+ def element(section_id, element_id)
32
+ elt = section(section_id).select {|e| e["id"] == element_id}.first
33
+ elt || {}
34
+ end
35
+
36
+ def update_section(*ids, value)
37
+ end
38
+
39
+ # Note : only 2 levels supported for now
40
+ def update_element(*ids, value)
41
+ updated = nil
42
+ if ids.length > 1
43
+ if self.sections[ids[0]].any? {|elt| elt["id"] == ids[1]}
44
+ self.sections[ids[0]].map! {|elt| elt["id"] == ids[1] ? elt.value : elt}
45
+ else
46
+ self.sections[ids[0]] << {"id" => ids[1]}.merge(value)
47
+ end
48
+ updated = value if save
49
+ end
50
+ updated
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,5 @@
1
+ module Sibu
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Sibu
2
+ class Image < ApplicationRecord
3
+ include ImageUploader::Attachment.new(:file)
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ module Sibu
2
+ class Page < ApplicationRecord
3
+ include Sibu::SectionsConcern
4
+
5
+ belongs_to :site, :class_name => 'Sibu::Site'
6
+
7
+ store :metadata, accessors: [:title, :description], coder: JSON
8
+
9
+ validates_presence_of :name, :site, :language, :template
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ module Sibu
2
+ class Site < ApplicationRecord
3
+ include Sibu::SectionsConcern
4
+
5
+ belongs_to :site_template, :class_name => 'Sibu::SiteTemplate'
6
+ has_many :pages, :class_name => 'Sibu::Page', dependent: :destroy
7
+
8
+ validates_presence_of :name, :site_template
9
+
10
+ def page_template(page)
11
+ "#{site_template.path}/#{page.template}"
12
+ end
13
+
14
+ def not_found
15
+ "#{site_template.path}/not_found"
16
+ end
17
+
18
+ def page(path)
19
+ pages.where(path: path).first
20
+ end
21
+
22
+ def page_by_id(page_id)
23
+ pages.where(id: page_id).first
24
+ end
25
+
26
+ def init_data(source)
27
+ site_data = Rails.application.config.sibu[:site_data][source]
28
+ self.sections = site_data.sections
29
+ site_data.pages.each do |p|
30
+ self.pages << Sibu::Page.new(p)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,4 @@
1
+ module Sibu
2
+ class SiteTemplate < ApplicationRecord
3
+ end
4
+ end
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html class="sibu">
3
+ <head>
4
+ <title><%= conf[:title] %></title>
5
+ <%= stylesheet_link_tag conf[:stylesheet], media: 'all' %>
6
+ <%= javascript_include_tag conf[:javascript] %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+ <% [:top_panel, :side_panel, :content_panel, :bottom_panel].each do |panel| %>
11
+ <% unless conf[panel].blank? %>
12
+ <div class="sibu_panel">
13
+ <%= render conf[panel] %>
14
+ </div>
15
+ <% end %>
16
+ <% end %>
17
+ </body>
18
+ </html>
@@ -0,0 +1,49 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= conf[:title] %></title>
5
+ <%= stylesheet_link_tag conf[:stylesheet], media: 'all' %>
6
+ <%= javascript_include_tag conf[:javascript] %>
7
+ <%= stylesheet_link_tag 'sibu/sibu', media: 'all' %>
8
+ <%= javascript_include_tag 'sibu/sibu' %>
9
+ <% if @site %>
10
+ <%= stylesheet_link_tag @site.site_template.path, media: "all" %>
11
+ <%= javascript_include_tag @site.site_template.path %>
12
+ <% end %>
13
+ <%= csrf_meta_tags %>
14
+ </head>
15
+ <body>
16
+ <% [:top_panel, :side_panel, :content_panel, :bottom_panel].each do |panel| %>
17
+ <% unless conf[panel].blank? %>
18
+ <div class="<%= 'sibu_panel' unless panel == :content_panel %>">
19
+ <%= render conf[panel] %>
20
+ </div>
21
+ <% end %>
22
+ <% end %>
23
+ <div id="edit_panel" class="sibu_view"></div>
24
+
25
+ <script>
26
+ $(function() {
27
+ initOverlays();
28
+ });
29
+
30
+ function initOverlays() {
31
+ var elts = $("[class*='sb-']");
32
+ elts.each(function() {
33
+ var elt = $(this);
34
+ elt.find(".sb-overlay").remove();
35
+ var section = elt.parents("sb-edit").first();
36
+ var eltId = elt.data("id"), sectionId = section.data("id"), entity = section.data("entity");
37
+ elt.append(
38
+ '<div class="sb-overlay sibu_panel">' +
39
+ '<a href="<%= edit_element_site_page_path(@site.id, @page.id) %>?element_id=' + eltId + '&section_id=' + sectionId +
40
+ '&entity=' + entity + '" data-remote="true">Modifier</a>' +
41
+ '</div>'
42
+ );
43
+ });
44
+
45
+ }
46
+ </script>
47
+ <%= yield :scripts %>
48
+ </body>
49
+ </html>
@@ -0,0 +1,21 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= @page ? @page.title : 'Page inconnue' %></title>
5
+ <meta charset="UTF-8">
6
+ <meta name="description" content="<%= @page.description if @page %>">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+
9
+ <% if @site %>
10
+ <%= stylesheet_link_tag @site.site_template.path, media: "all" %>
11
+ <%= javascript_include_tag @site.site_template.path %>
12
+ <% end %>
13
+ <%= csrf_meta_tags %>
14
+ </head>
15
+ <body>
16
+
17
+ <%= yield %>
18
+
19
+ <%= yield :scripts %>
20
+ </body>
21
+ </html>
@@ -0,0 +1,19 @@
1
+ <h2>Modifier l'élément</h2>
2
+ <div id="edit_msg"></div>
3
+ <div class="sibu_form">
4
+ <%= form_tag(update_element_site_page_path(@site.id, @page.id), method: :patch, remote: true) do |f| %>
5
+ <div class="sibu_field">
6
+ <%= label_tag 'element[text]', 'Texte' %>
7
+ <%= text_area_tag 'element[text]' %>
8
+ </div>
9
+ <%= hidden_field_tag :section_id, @section_id %>
10
+ <%= hidden_field_tag :element_id, @element_id %>
11
+ <%= hidden_field_tag :entity, @entity_type %>
12
+ <div class="sibu_actions">
13
+ <%= submit_tag 'Valider' %>
14
+ <%= link_to 'Annuler', '#', onclick: '$("#edit_panel").slideUp("fast"); return false;' %>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+
19
+
@@ -0,0 +1,31 @@
1
+ <%= form_for([@site, @page]) do |f| %>
2
+ <div class="sibu_field">
3
+ <%= f.label :name, 'Nom de la page' %>
4
+ <%= f.text_field :name, placeholder: "Ex : Accueil, contact..." %>
5
+ </div>
6
+ <div class="sibu_field">
7
+ <%= f.label :template, 'Modèle' %>
8
+ <%= f.select(:template, page_templates, {prompt: 'Sélectionnez un modèle de page'}) %>
9
+ </div>
10
+ <div class="sibu_field">
11
+ <%= f.label :path, "Chemin d'accès" %>
12
+ <%= f.text_field :path, placeholder: "Adresse de la page" %>
13
+ </div>
14
+ <div class="sibu_field">
15
+ <%= f.label :language, "Langue" %>
16
+ <%= f.select(:language, page_languages, {prompt: 'Sélectionnez une langue'}) %>
17
+ </div>
18
+ <div class="sibu_field">
19
+ <%= f.label :title, 'Titre' %>
20
+ <%= f.text_field :title, placeholder: "Titre de la page" %>
21
+ </div>
22
+ <div class="sibu_field">
23
+ <%= f.label :description, 'Description' %>
24
+ <%= f.text_area :description, placeholder: "Description de la page" %>
25
+ </div>
26
+ <%= f.hidden_field :site_id %>
27
+ <div class="sibu_actions">
28
+ <%= f.submit 'Valider' %>
29
+ <%= link_to 'Annuler', :back %>
30
+ </div>
31
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <h1>Pages#destroy</h1>
2
+ <p>Find me in app/views/sibu/pages/destroy.html.erb</p>
@@ -0,0 +1,9 @@
1
+ <div class="sibu_view">
2
+ <div class="actions">
3
+ <%= link_to 'Retour', :back %>
4
+ </div>
5
+ <h2>Modifier une page</h2>
6
+ <div class="sibu_form">
7
+ <%= render 'form' %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,3 @@
1
+ <div class="edit_content">
2
+ <%= render "shared/#{@site.site_template.path}/site" %>
3
+ </div>
@@ -0,0 +1,4 @@
1
+ var editPanel = $("#edit_panel");
2
+ editPanel.html("<%= j(render 'edit_panel') %>");
3
+ editPanel.find("#element").val("<%= @entity.element(@section_id, @element_id)["text"] %>");
4
+ editPanel.slideDown("fast");
@@ -0,0 +1,39 @@
1
+ <div id="pages" class="sibu_view">
2
+ <div class="actions">
3
+ <%= link_to 'Créer une page', new_site_page_path(@site.id) %> | <%= link_to 'Retour', :back %>
4
+ </div>
5
+ <h2>Pages du site "<%= @site.name %>"</h2>
6
+ <table>
7
+ <thead>
8
+ <tr>
9
+ <th>Nom</th>
10
+ <th>Modèle</th>
11
+ <th>Chemin d'accès</th>
12
+ <th>Mise à jour</th>
13
+ <th></th>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <% @pages.each do |p| %>
18
+ <tr>
19
+ <td><%= p.name %></td>
20
+ <td><%= p.template %></td>
21
+ <td><%= p.path %></td>
22
+ <td><%= l p.updated_at %></td>
23
+ <td>
24
+ <%= link_to 'Voir', site_page_path(@site.id, p), target: '_blank' %> |
25
+ <%= link_to 'Editer', site_page_edit_content_path(site_id: @site.id, page_id: p.id) %> |
26
+ <%= link_to 'Modifier', edit_site_page_path(@site.id, p) %> |
27
+ <%= link_to 'Supprimer', site_page_path(@site.id, p), method: :delete, data: {confirm: "Supprimer la page \"#{p.name}\" ?"} %>
28
+ </td>
29
+ </tr>
30
+ <% end %>
31
+ <% if @pages.empty? %>
32
+ <tr>
33
+ <td colspan="4">Aucune page créée pour le moment.</td>
34
+ </tr>
35
+ <% end %>
36
+ </tbody>
37
+ </table>
38
+ </div>
39
+
@@ -0,0 +1,9 @@
1
+ <div class="sibu_view">
2
+ <div class="actions">
3
+ <%= link_to 'Retour', :back %>
4
+ </div>
5
+ <h2>Créer une page</h2>
6
+ <div class="sibu_form">
7
+ <%= render 'form' %>
8
+ </div>
9
+ </div>
@@ -0,0 +1 @@
1
+ <%= render "shared/#{@site.site_template.path}/site" %>
@@ -0,0 +1,2 @@
1
+ <h1>Pages#update</h1>
2
+ <p>Find me in app/views/sibu/pages/update.html.erb</p>
@@ -0,0 +1,7 @@
1
+ <% if @updated.nil? %>
2
+ $("#edit_panel #edit_msg").html("<p class='sibu_alert'>Une erreur s'est produite lors de l'enregistrement.</p>");
3
+ <% else %>
4
+ $("#edit_panel").slideUp();
5
+ $("sb-edit[data-id='<%= @section_id %>']").find("[data-id='<%= @element_id %>']").text("<%= @updated["text"] %>");
6
+ initOverlays();
7
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <%= form_for @site do |f| %>
2
+ <div class="sibu_field">
3
+ <%= f.label :name, 'Nom du site' %>
4
+ <%= f.text_field :name, placeholder: "Ex : Site de l'Hôtel du Lac" %>
5
+ </div>
6
+ <div class="sibu_field">
7
+ <%= f.label :site_template_id, 'Modèle' %>
8
+ <%= f.collection_select(:site_template_id, Sibu::SiteTemplate.all, :id, :name, {prompt: 'Sélectionnez un modèle de site'}) %>
9
+ </div>
10
+ <%= f.hidden_field :user_id %>
11
+ <div class="sibu_actions">
12
+ <%= f.submit 'Valider' %>
13
+ <%= link_to 'Annuler', :back %>
14
+ </div>
15
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <h1>Sites#destroy</h1>
2
+ <p>Find me in app/views/sibu/sites/destroy.html.erb</p>
@@ -0,0 +1,9 @@
1
+ <div class="sibu_view">
2
+ <div class="actions">
3
+ <%= link_to 'Retour', :back %>
4
+ </div>
5
+ <h2>Modifier un site</h2>
6
+ <div class="sibu_form">
7
+ <%= render 'form' %>
8
+ </div>
9
+ </div>
@@ -0,0 +1,37 @@
1
+ <div class="sibu_view">
2
+ <div class="actions">
3
+ <%= link_to 'Créer un site', new_site_path %>
4
+ </div>
5
+ <h2>Liste des sites</h2>
6
+ <table>
7
+ <thead>
8
+ <tr>
9
+ <th>Nom</th>
10
+ <th>Modèle</th>
11
+ <th>Mise à jour</th>
12
+ <th></th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <% @sites.each do |s| %>
17
+ <tr>
18
+ <td><%= s.name %></td>
19
+ <td><%= s.site_template.name if s.site_template %></td>
20
+ <td><%= l s.updated_at %></td>
21
+ <td>
22
+ <%= link_to 'Voir', site_path(s), target: '_blank' %> |
23
+ <%= link_to 'Pages', site_pages_path(s) %> |
24
+ <%= link_to 'Modifier', edit_site_path(s) %> |
25
+ <%= link_to 'Supprimer', site_path(s), method: :delete, data: {confirm: "Supprimer le site \"#{s.name}\" ?"} %>
26
+ </td>
27
+ </tr>
28
+ <% end %>
29
+ <% if @sites.empty? %>
30
+ <tr>
31
+ <td colspan="4">Aucun site créé pour le moment.</td>
32
+ </tr>
33
+ <% end %>
34
+ </tbody>
35
+ </table>
36
+ </div>
37
+
@@ -0,0 +1,9 @@
1
+ <div class="sibu_view">
2
+ <div class="actions">
3
+ <%= link_to 'Retour', :back %>
4
+ </div>
5
+ <h2>Créer un site</h2>
6
+ <div class="sibu_form">
7
+ <%= render 'form' %>
8
+ </div>
9
+ </div>
@@ -0,0 +1 @@
1
+ <%= render "shared/#{@site.site_template.path}/site" %>
@@ -0,0 +1,2 @@
1
+ <h1>Sites#update</h1>
2
+ <p>Find me in app/views/sibu/sites/update.html.erb</p>
@@ -0,0 +1,10 @@
1
+ require "shrine"
2
+ require "shrine/storage/file_system"
3
+
4
+ Shrine.storages = {
5
+ cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"), # temporary
6
+ store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/store"), # permanent
7
+ }
8
+
9
+ Shrine.plugin :activerecord
10
+ Shrine.plugin :cached_attachment_data
@@ -0,0 +1,75 @@
1
+ module ActionView
2
+ module Helpers
3
+ module TagHelper
4
+ # Todo : handle default values => sections can be totally empty or have at least 1 elt
5
+ # If "emptyable", how do we add the 1st elt ? If not, how do we provide a default value ?
6
+ class SectionHelper
7
+ include ActionView::Helpers::TagHelper
8
+
9
+ attr_reader :entity_type
10
+
11
+ [:h1, :h2, :h3, :h4, :h5, :h6, :p, :span, :div].each do |t|
12
+ define_method(t) do |id, html_opts = {}|
13
+ html_opts.merge!({class: "sb-#{t} #{html_opts[:class]}", data: {id: id}}) if @edit
14
+ content_tag(t, (@elements.dig(id, "text") || "Texte à modifier"), html_opts)
15
+ end
16
+ end
17
+
18
+ def initialize(*ids, entity, edit_mode)
19
+ @id = ids.join('|')
20
+ @entity_type = entity.is_a?(Sibu::Page) ? 'page' : 'site'
21
+ elts = entity.section(*ids)
22
+ @elements = elts.blank? ? {"default" => {}} : Hash[elts.map {|e| [e["id"], e.except("id")]}]
23
+ @edit = edit_mode
24
+ end
25
+
26
+ # Note : add sb-img back - see how the extra div could be removed
27
+ def img(id, html_opts = {})
28
+ content = id == "default" ? {"src" => "/default.jpg"} : (@elements[id] || {"src" => "/default.jpg"})
29
+ if @edit
30
+ content_tag(:div, content_tag(:img, nil, content.merge(html_opts)), {class: "rel h100 #{html_opts[:class]}", data: {id: id}})
31
+ else
32
+ content_tag(:img, nil, content.merge(html_opts))
33
+ end
34
+ end
35
+
36
+ def lnk(id)
37
+ @elements[id] || {"href" => "#", "text" => "Nouveau lien"}
38
+ end
39
+
40
+ # def subsection(id, &block)
41
+ # section
42
+ # s = SectionHelper.new(id, @entity_type, @elements[id], @edit)
43
+ # if !@edit
44
+ # capture(s, &block)
45
+ # else
46
+ # "<sb-edit data-id='#{id}' data-entity='#{@entity_type}'>#{capture(s, &block)}</sb-edit>".html_safe
47
+ # end
48
+ # end
49
+
50
+ def elements(&block)
51
+ @elements.each_pair(&block)
52
+ end
53
+ end
54
+
55
+ def section(id, entity = @page, &block)
56
+ s = SectionHelper.new(id, entity, action_name != 'show')
57
+ if action_name == 'show'
58
+ capture(s, &block)
59
+ else
60
+ "<sb-edit data-id='#{id}' data-entity='#{s.entity_type}'>#{capture(s, &block)}</sb-edit>".html_safe
61
+ end
62
+ end
63
+
64
+ def subsection(id, sub_id, entity = @page, &block)
65
+ entity_type = entity.is_a?(Sibu::Page) ? 'page' : 'site'
66
+ s = SectionHelper.new(id, sub_id, entity, action_name != 'show')
67
+ # if action_name == 'show'
68
+ capture(s, &block)
69
+ # else
70
+ # "<sb-edit data-id='#{id}' data-entity='#{s.entity_type}'>#{capture(s, &block)}</sb-edit>".html_safe
71
+ # end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,17 @@
1
+ Sibu::Engine.routes.draw do
2
+
3
+ get '/', to: 'pages#show', constraints: lambda {|req| req.domain != Rails.application.config.sibu[:domain]}
4
+ get '*path', to: 'pages#show', constraints: lambda {|req| req.domain != Rails.application.config.sibu[:domain]}
5
+
6
+ scope path_names: {new: 'creer', edit: 'modifier'} do
7
+ resources :sites do
8
+ resources :pages do
9
+ get :edit_content, to: 'pages#edit_content', path: 'editer'
10
+ get :edit_element, on: :member
11
+ get :edit_section, on: :member
12
+ patch 'update_element', on: :member
13
+ patch 'update_section', on: :member
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ class CreateSibuSites < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :sibu_sites do |t|
4
+ t.string :name
5
+ t.integer :site_template_id
6
+ t.text :metadata
7
+ t.jsonb :sections
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ class CreateSibuPages < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :sibu_pages do |t|
4
+ t.string :name
5
+ t.integer :site_id
6
+ t.text :metadata
7
+ t.string :language
8
+ t.string :url
9
+ t.string :template
10
+ t.jsonb :sections
11
+
12
+ t.timestamps
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ class CreateSibuSiteTemplates < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :sibu_site_templates do |t|
4
+ t.string :name
5
+ t.string :path
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class AddUserIdToSites < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :sibu_sites, :user_id, :integer
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class RenameUrlToPathInPages < ActiveRecord::Migration[5.1]
2
+ def change
3
+ rename_column :sibu_pages, :url, :path
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddDomainToSites < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_column :sibu_sites, :domain, :string
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class CreateSibuImages < ActiveRecord::Migration[5.1]
2
+ def change
3
+ create_table :sibu_images do |t|
4
+ t.integer :user_id
5
+ t.text :metadata
6
+ t.text :data
7
+
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ require "sibu/engine"
2
+
3
+ module Sibu
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'tinymce-rails'
2
+
3
+ module Sibu
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace Sibu
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Sibu
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :sibu do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sibu
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jean-Baptiste Vilain
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-01-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: shrine
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jquery-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: tinymce-rails
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: tinymce-rails-langs
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Sibu is an engine for Ruby on Rails that enables creation of static websites
98
+ in a simple & wysiwyg way.
99
+ email:
100
+ - jbvilain@gmail.com
101
+ executables: []
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - MIT-LICENSE
106
+ - README.md
107
+ - Rakefile
108
+ - app/assets/config/sibu_manifest.js
109
+ - app/assets/javascripts/sibu/sibu.js.erb
110
+ - app/assets/stylesheets/sibu/sibu.scss.erb
111
+ - app/controllers/sibu/application_controller.rb
112
+ - app/controllers/sibu/pages_controller.rb
113
+ - app/controllers/sibu/sites_controller.rb
114
+ - app/helpers/sibu/application_helper.rb
115
+ - app/helpers/sibu/pages_helper.rb
116
+ - app/helpers/sibu/sites_helper.rb
117
+ - app/jobs/sibu/application_job.rb
118
+ - app/mailers/sibu/application_mailer.rb
119
+ - app/models/concerns/sibu/image_uploader.rb
120
+ - app/models/concerns/sibu/sections_concern.rb
121
+ - app/models/sibu/application_record.rb
122
+ - app/models/sibu/image.rb
123
+ - app/models/sibu/page.rb
124
+ - app/models/sibu/site.rb
125
+ - app/models/sibu/site_template.rb
126
+ - app/views/layouts/sibu/application.html.erb
127
+ - app/views/layouts/sibu/edit_content.html.erb
128
+ - app/views/layouts/sibu/site.html.erb
129
+ - app/views/sibu/pages/_edit_panel.html.erb
130
+ - app/views/sibu/pages/_form.html.erb
131
+ - app/views/sibu/pages/destroy.html.erb
132
+ - app/views/sibu/pages/edit.html.erb
133
+ - app/views/sibu/pages/edit_content.html.erb
134
+ - app/views/sibu/pages/edit_element.js.erb
135
+ - app/views/sibu/pages/index.html.erb
136
+ - app/views/sibu/pages/new.html.erb
137
+ - app/views/sibu/pages/show.html.erb
138
+ - app/views/sibu/pages/update.html.erb
139
+ - app/views/sibu/pages/update_element.js.erb
140
+ - app/views/sibu/sites/_form.html.erb
141
+ - app/views/sibu/sites/destroy.html.erb
142
+ - app/views/sibu/sites/edit.html.erb
143
+ - app/views/sibu/sites/index.html.erb
144
+ - app/views/sibu/sites/new.html.erb
145
+ - app/views/sibu/sites/show.html.erb
146
+ - app/views/sibu/sites/update.html.erb
147
+ - config/initializers/shrine.rb
148
+ - config/initializers/tag_helper.rb
149
+ - config/routes.rb
150
+ - db/migrate/20180124095041_create_sibu_sites.rb
151
+ - db/migrate/20180124095213_create_sibu_pages.rb
152
+ - db/migrate/20180124145030_create_sibu_site_templates.rb
153
+ - db/migrate/20180125231638_add_user_id_to_sites.rb
154
+ - db/migrate/20180126114522_rename_url_to_path_in_pages.rb
155
+ - db/migrate/20180126114628_add_domain_to_sites.rb
156
+ - db/migrate/20180127211533_create_sibu_images.rb
157
+ - lib/sibu.rb
158
+ - lib/sibu/engine.rb
159
+ - lib/sibu/version.rb
160
+ - lib/tasks/sibu_tasks.rake
161
+ homepage: http://hotentic.com
162
+ licenses:
163
+ - MIT
164
+ metadata: {}
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 2.6.13
182
+ signing_key:
183
+ specification_version: 4
184
+ summary: Sibu - A Site Builder for Ruby on Rails
185
+ test_files: []