inverter 0.2.7 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 564ec4fa572bfa7f6cc0fa67891caad0253b272d
4
- data.tar.gz: 0fb3028fa52c4c4b5b68f8f0a736cc8fde23b6f7
3
+ metadata.gz: a12fcc4aa0c6147bbcc747c703bc98547dba6765
4
+ data.tar.gz: de490871d8ec0d0030b0a3028d9055cb1b587b80
5
5
  SHA512:
6
- metadata.gz: 3ed5adbc98926a81745305997ed573b65fe1419f14592611ef7fb592f204f296c58d3522228fae8004a0958a34069c6c7dae312e244f05b74fbce049cecbc811
7
- data.tar.gz: 4d78f109f0d6339d39716c96fe6cc366a4903a89ea34f3ad833e52265024d4758972fe667fb54456763fd906405aa67547b34bc48782c286d91083748dc2d091
6
+ metadata.gz: 166ec4a8bcac10ee30dfcfce766c2f0aa521f1712344f5a9b9a76cb3ee761cf645d56eec16393a41e19beabd0df9f482974e75fbd0e4078500cee44c3d46da3a
7
+ data.tar.gz: 9b1870192eaa8a9b1dec2ecb394f03505a71b98350a25685e8ec575348cb5435b09e87ab2a0bbb4f74af603bb9ec618d68068601c9a4bfcfba326d1071691275
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  Mark content that you want to change via CMS in Rails templates. It's automatically populated to models and is accessible via CMS. When Rails renders template it pulls editable content from databased automatically.
6
6
 
7
7
 
8
- ## Installation
8
+ ## Setup
9
9
 
10
10
  Add to ```Gemfile```:
11
11
 
@@ -13,139 +13,173 @@ Add to ```Gemfile```:
13
13
 
14
14
  Setup initializer ```config/initializers/inverter.rb```:
15
15
 
16
- ```ruby
17
- Inverter.configure do |config|
18
- # model that stores template editable blocks
19
- config.model_class = Page
16
+ ```ruby
17
+ Inverter.configure do |config|
18
+ # model that stores template editable blocks
19
+ config.model_class = Page
20
20
 
21
- # folders which templates are editable
22
- config.template_folders = %w( pages )
21
+ # folders which templates are editable
22
+ config.template_folders = %w( pages )
23
23
 
24
- # templates from template_folders the are not editable
25
- config.excluded_template_names = %w( pages/home )
26
- end
27
- ```
24
+ # templates from template_folders the are not editable
25
+ config.excluded_template_names = %w( pages/home )
26
+
27
+ # disable Inverter middleware
28
+ config.disabled_middleware = false
29
+ end
30
+ ```
28
31
 
29
32
  Configure model that stores template content, e.g. ```models/page.rb```:
30
33
 
31
- ```ruby
32
- class Page
33
- include Mongoid::Document
34
- include Mongoid::Timestamps
35
- include Mongoid::Inverter
36
- end
37
- ```
34
+ ```ruby
35
+ class Page
36
+ include Mongoid::Document
37
+ include Mongoid::Timestamps
38
+ include Mongoid::Inverter
39
+ end
40
+ ```
41
+
42
+ Setup admin page controller configuration ```controllers/admin/pages_controller.rb```:
43
+
44
+ ```ruby
45
+ class Admin::PagesController < Admin::BaseController
46
+ mongosteen
47
+ json_config({ methods: [ :list_item_title, :version_options ])
48
+ end
49
+ ```
50
+
51
+
52
+ ### Meta Tags
53
+
54
+ ```Mongoid::Inverter``` concern includes page meta tags fields. Check out [meta-tags](https://github.com/kpumuk/meta-tags) gem documentation for usage details, it helps to make pages SEO friendly.
55
+
56
+ To enable meta-tags support include following helper in application layout:
57
+
58
+ ```erb
59
+ <%= display_meta_tags title: 'Default Website Title',
60
+ description: 'Default Website Description',
61
+ open_graph: { type: 'website',
62
+ title: 'Default Website Title',
63
+ description: 'Default Website Description',
64
+ image: 'https://slate-git-images.s3-us-west-1.amazonaws.com/slate.png' } %>
65
+ ```
66
+
67
+ To override default behavior add custom fields and write own ```update_inverter_meta_tags``` implementation.
68
+
38
69
 
39
- Setup admin page controller configuration ```controllers/admin/pages_controller.rb```, this keeps models in sync with template files changes:
70
+ ### View Example
40
71
 
41
- ```ruby
42
- class Admin::PagesController < Admin::BaseController
43
- mongosteen
44
- json_config({ methods: [ :list_item_title ])
72
+ An example of editable template with five content blocks and page name (to identify page in CMS), e.g. ```pages/about.html.erb```:
45
73
 
46
- before_filter :syncronize_templates, only: [ :index ]
74
+ ```html
75
+ <!--// About //-->
76
+ <h1>About</h1>
47
77
 
48
- protected
78
+ <!--[ hero : inverter-image ]-->
79
+ <%= image_tag('hero-1.png', alt: 'Welcome to Inverter') %>
80
+ <!--END-->
49
81
 
50
- def syncronize_templates
51
- if Rails.env.development?
52
- resource_class.sync_with_templates!
53
- end
54
- end
55
- end
56
- ```
82
+ <!--[ subtitle ]-->
83
+ <p>
84
+ Blocks could have not only plain HTML but a Ruby template code as well. For
85
+ example these links below are going to be rendered and saved as HTML links in
86
+ the page objects.</p>
57
87
 
58
- Controller filter above tracks changes in editable templates on every ```index``` request. This helps to keep models up to date while app development. If new template added to folders it's linked automatically and removed if existing one deleted. Editable piece of content in the template is called name, each block should be named.
88
+ <p>
89
+ This content is editable via CMS, please go to website
90
+ <%= link_to 'admin', admin_path %> and check how it can be changed.</p>
91
+ <!--END-->
59
92
 
60
- An example of editable template with three content blocks and page name (to identify page in CMS), e.g. ```pages/about.html.erb```:
93
+ <!--[ body : markdown ]-->
94
+ You can use markdown in your views as well. [redcarpet](https://github.com/vmg/redcarpet)
95
+ gem is used as markdown rendere.
96
+ <!--END-->
61
97
 
62
- ```html
63
- <!--// About //-->
64
- <h1>About</h1>
98
+ <!--[ footer ]-->
99
+ <p>
100
+ This is an example of the content block named footer. This content is editable
101
+ via CMS, please go to website <%= link_to 'admin', admin_path %> and check how
102
+ it can be changed.</p>
103
+ <!--END-->
65
104
 
66
- <!--[ hero : inverter-image ]-->
67
- <%= image_tag('hero-1.png', alt: 'Welcome to Inverter') %>
68
- <!--END-->
105
+ <!--[ footer_link : inverter-link ]-->
106
+ <p>
107
+ <%= link_to 'Slate', 'http://www.slatestudio.com', target: '_blank' %></p>
108
+ <!--END-->
109
+ ```
69
110
 
70
- <!--[ subtitle ]-->
71
- <p>
72
- This is an example of the content block named subtitle. This content is editable
73
- via CMS, please go to website <%= link_to 'admin', admin_path %> and check how
74
- it can be changed.</p>
75
- <!--END-->
76
111
 
77
- <!--[ body ]-->
78
- <p>
79
- Blocks could have not only plain HTML but a Ruby template code as well. For
80
- example these links below are going to be rendered and saved as HTML links in
81
- the models. You can access <%= link_to 'welcome', page_path('welcome') %> &amp;
82
- <%= link_to 'about', page_path('about') %> pages.</p>
83
- <!--END-->
112
+ ### Middleware
84
113
 
85
- <!--[ footer ]-->
86
- <p>
87
- This is an example of the content block named footer. This content is editable
88
- via CMS, please go to website <%= link_to 'admin', admin_path %> and check how
89
- it can be changed.</p>
90
- <!--END-->
91
- ```
114
+ Inverter middleware helps to keep inverter objects up to date with template changes in development environment.
92
115
 
116
+ If new template added to tracked folders it's linked automatically and correspoding inverter object created. After tracked template deleted a tracking inverter object is removed as well.
93
117
 
94
- ### Character Setup
118
+ It also watches changes in templates: adding new blocks and removing existing ones. When block is renamed inverter thinks that the new one added and previous removed so content for the previous is lost.
119
+
120
+
121
+ ### Character Configuration
95
122
 
96
123
  Inverter supports [chr](https://github.com/slate-studio/chr) out of the box. Include custom input in the cms configuration file ```admin.coffee```, and setup module configuration:
97
124
 
98
- ```coffeescript
125
+ ```coffeescript
126
+
127
+ #= require inverter
99
128
 
100
- #= require inverter
129
+ pagesConfig = ->
130
+ itemTitleField: 'list_item_title'
131
+ disableNewItems: true
132
+ disableDelete: true
133
+ arrayStore: new RailsArrayStore({
134
+ resource: 'page'
135
+ path: '/admin/pages'
136
+ })
137
+ formSchema:
138
+ version: { type: 'inverter-version', path: '/admin/pages' }
139
+ _page_title: { type: 'string', label: 'Title' }
140
+ _page_description: { type: 'text', label: 'Description' }
141
+ _page_keywords: { type: 'text', label: 'Keywords' }
142
+ _page_image_url: { type: 'string', label: 'Image URL' }
143
+ _blocks: { type: 'inverter' }
144
+ ```
101
145
 
102
- pagesConfig = ->
103
- itemTitleField: 'list_item_title'
104
- disableNewItems: true
105
- disableDelete: true
106
- arrayStore: new MongosteenArrayStore({
107
- resource: 'page'
108
- path: '/admin/pages'
109
- })
110
- formSchema:
111
- _page_title: { type: 'string', label: 'Title' }
112
- _page_description: { type: 'text', label: 'Description' }
113
- _page_keywords: { type: 'text', label: 'Keywords' }
114
- _page_image_url: { type: 'string', label: 'Image URL' }
115
- blocks: { type: 'inverter' }
116
- ```
146
+ Inverer ```version``` input allows to select previous version of the page to edit.
117
147
 
118
- Inverter input has an option ```defaultInputType``` which specifies what input type should be used as default, if nothing specified ```text``` is used. This might be set to WYSIWYG editor of your choice, e.g:
148
+ Inverter input has an option ```defaultInputType``` that specifies what input type should be used as default, if nothing specified ```text``` is used. This might be set to WYSIWYG editor of your choice, e.g:
119
149
 
120
- ```coffeescript
121
- blocks: { type: 'inverter', defaultInputType: 'redactor' }
122
- ```
150
+ ```coffeescript
151
+ blocks: { type: 'inverter', defaultInputType: 'redactor' }
152
+ ```
123
153
 
124
154
  You can also specify input type that you want to use for specific block like this: ```<!--[ Main Body : text ]-->``` — in this case ```Main Body``` would be a label and ```text``` is an input type that will be used to edit this block in CMS.
125
155
 
156
+ Include inverter styles for cms inputs into character styles configuration file ```admin.scss```
126
157
 
127
- ### Meta Tags Support
158
+ ```scss
159
+ @import "inverter";
160
+ ```
128
161
 
129
- ```Mongoid::Inverter``` concern includes page meta tags fields. Check out [meta-tags](https://github.com/kpumuk/meta-tags) gem documentation for usage details, it helps to make pages SEO friendly.
130
162
 
131
- To enable meta-tags support include following helper in application layout:
163
+ ### Rake Tasks
132
164
 
133
- ```erb
134
- <%= display_meta_tags title: 'Default Website Title',
135
- description: 'Default Website Description',
136
- open_graph: { type: 'website',
137
- title: 'Default Website Title',
138
- description: 'Default Website Description',
139
- image: 'https://slate-git-images.s3-us-west-1.amazonaws.com/slate.png' } %>
140
- ```
165
+ To reset all inverter objects to template defaults run:
141
166
 
142
- To override default behavior add custom fields and write own ```update_inverter_meta_tags``` implementation.
167
+ rake inverter:reset
143
168
 
169
+ **You need to run this rake task manually after first production deploy.** Middleware synchronizes objects only for development mode.
144
170
 
145
- ## Inverter family
171
+ To sync all inverter objects with template changes run:
172
+
173
+ rake inverter:sync
174
+
175
+ **You might need to run this command on production after deploy if some templates blocks were changed.**
176
+
177
+
178
+ ## Inverter Family:
146
179
 
147
- - [Mongosteen](https://github.com/slate-studio/mongosteen): An easy way to add RESTful actions for mongoid models
148
180
  - [Character](https://github.com/slate-studio/chr): Powerful responsive javascript CMS for apps
181
+ - [Mongosteen](https://github.com/slate-studio/mongosteen): An easy way to add RESTful actions for Mongoid models
182
+ - [Inverter](https://github.com/slate-studio/inverter): An easy way to connect Rails templates content to Character CMS
149
183
  - [Loft](https://github.com/slate-studio/loft): Media assets manager for Character CMS
150
184
 
151
185
 
@@ -161,3 +195,5 @@ Copyright © 2015 [Slate Studio, LLC](http://slatestudio.com). Inverter is free
161
195
  Inverter is maintained and funded by [Slate Studio, LLC](http://slatestudio.com). Tweet your questions or suggestions to [@slatestudio](https://twitter.com/slatestudio) and while you’re at it follow us too.
162
196
 
163
197
 
198
+
199
+
@@ -8,7 +8,11 @@
8
8
 
9
9
  # -----------------------------------------------------------------------------
10
10
  # INPUT INVERTER IMAGE
11
- # - depends on Loft character plugin for assets management
11
+ #
12
+ # Dependencies:
13
+ # - Loft character plugin for assets management
14
+ # - Chr input string implementation
15
+ #
12
16
  # -----------------------------------------------------------------------------
13
17
  class @InputInverterImage extends InputString
14
18
 
@@ -30,7 +34,7 @@ class @InputInverterImage extends InputString
30
34
 
31
35
 
32
36
  _normalize_value: ->
33
- if @value.indexOf('<img') > -1
37
+ if @value && @value.indexOf('<img') > -1
34
38
  @value = @value.replace(new RegExp('"', 'g'), "'")
35
39
 
36
40
  if ! @value.indexOf(' alt=') > -1
@@ -86,7 +90,7 @@ class @InputInverterImage extends InputString
86
90
 
87
91
  @$chooseBtn.on 'click', (e) =>
88
92
  e.preventDefault()
89
- chr.modules.assets.showModal 'images', false, (objects) =>
93
+ chr.modules.loft.showModal 'images', false, (objects) =>
90
94
  newSrc = objects[0].file.url
91
95
  alt = @_alt() || objects[0].name
92
96
  @_update_value(newSrc, alt)
@@ -119,6 +123,7 @@ class @InputInverterImage extends InputString
119
123
  updateValue: (@value) ->
120
124
  @_normalize_value()
121
125
  @$input.val(@value)
126
+ @$input.trigger('change')
122
127
 
123
128
  @_update_image()
124
129
  @_update_alt()
@@ -0,0 +1,98 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Author: Alexander Kravets <alex@slatestudio.com>,
3
+ # Slate Studio (http://www.slatestudio.com)
4
+ #
5
+ # Coding Guide:
6
+ # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
+ # -----------------------------------------------------------------------------
8
+
9
+ # -----------------------------------------------------------------------------
10
+ # INPUT INVERTER LINK
11
+ # - depends on Loft character plugin for assets management
12
+ # -----------------------------------------------------------------------------
13
+ class @InputInverterLink extends InputString
14
+
15
+ # PRIVATE ===============================================
16
+
17
+ _normalize_value: ->
18
+ if ! (@value.indexOf('<a') > -1)
19
+ @value = "<a title='' href=''></a>"
20
+
21
+
22
+ _add_input: ->
23
+ @_normalize_value()
24
+
25
+ @$el.addClass('input-loft-image')
26
+ @$el.addClass('has-value')
27
+
28
+ @$input =$ "<input type='hidden' name='#{ @name }' value='#{ @_safe_value() }' />"
29
+ @$el.append @$input
30
+
31
+ @_add_title()
32
+ @_add_url()
33
+ @_add_choose_button()
34
+
35
+
36
+ _update_value: (url, title) ->
37
+ $wrapper =$ "<div>#{ @value }</div>"
38
+ $wrapper.children().attr('href', url).attr('title', title).html(title)
39
+ @updateValue($wrapper.html())
40
+
41
+
42
+ _title: -> $(@value).html()
43
+
44
+
45
+ _url: -> $(@value).attr('href')
46
+
47
+
48
+ _add_title: ->
49
+ @$titleInput =$ "<input type='text' value='' placeholder='Title' />"
50
+ @$el.append @$titleInput
51
+
52
+ @$titleInput.val(@_title())
53
+
54
+ @$titleInput.on 'change', (e) =>
55
+ newTitle = $(e.target).val()
56
+ @_update_value(@_url(), newTitle)
57
+
58
+
59
+ _add_url: ->
60
+ @$urlInput =$ "<input type='text' value='' placeholder='URL' />"
61
+ @$el.append @$urlInput
62
+
63
+ @$urlInput.val(@_url())
64
+
65
+ @$urlInput.on 'change', (e) =>
66
+ newUrl = $(e.target).val()
67
+ @_update_value(newUrl, @_title())
68
+
69
+
70
+ _add_choose_button: ->
71
+ @$chooseBtn =$ "<a href='#' class='choose'>Choose or upload a file</a>"
72
+ @$el.append @$chooseBtn
73
+
74
+ @$chooseBtn.on 'click', (e) =>
75
+ e.preventDefault()
76
+ chr.modules.loft.showModal 'all', false, (objects) =>
77
+ url = objects[0].file.url
78
+ title = @_title() || objects[0].name
79
+ @_update_value(url, title)
80
+
81
+
82
+ # PUBLIC ================================================
83
+
84
+ updateValue: (@value) ->
85
+ @_normalize_value()
86
+
87
+ @$input.val(@value)
88
+ @$input.trigger('change')
89
+
90
+ @$titleInput.val(@_title())
91
+ @$urlInput.val(@_url())
92
+
93
+
94
+ chr.formInputs['inverter-link'] = InputInverterLink
95
+
96
+
97
+
98
+
@@ -0,0 +1,42 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Author: Alexander Kravets <alex@slatestudio.com>,
3
+ # Slate Studio (http://www.slatestudio.com)
4
+ #
5
+ # Coding Guide:
6
+ # https://github.com/thoughtbot/guides/tree/master/style/coffeescript
7
+ # -----------------------------------------------------------------------------
8
+
9
+ # -----------------------------------------------------------------------------
10
+ # INPUT INVERTER VERSION SELECT
11
+ # -----------------------------------------------------------------------------
12
+ class @InputInverterVersion extends InputSelect
13
+
14
+ _create_el: ->
15
+ @config.optionsHashFieldName = 'version_options'
16
+ @config.ignoreOnSubmission = true
17
+ @config.default = 0
18
+ @url = "#{ @config.path }/#{ @object._id }.json"
19
+
20
+ @$el =$ "<div class='input-#{ @config.type } input-#{ @config.klass } #{ @config.klassName }'>"
21
+
22
+
23
+ _add_input: ->
24
+ @$input =$ """<select name='#{ @name }'></select>"""
25
+ @$el.append @$input
26
+
27
+ @$input.on 'change', (e) => @_load_version()
28
+
29
+ @_add_options()
30
+
31
+
32
+ _load_version: ->
33
+ version = @$input.val()
34
+ $.get @url, { version: version }, (object) ->
35
+ chr.module.view.form.updateValues(object)
36
+
37
+
38
+ chr.formInputs['inverter-version'] = InputInverterVersion
39
+
40
+
41
+
42
+
@@ -72,8 +72,13 @@ class @InputInverter
72
72
 
73
73
  inputClass = chr.formInputs[inputType]
74
74
 
75
+ # here we have @config.namePrefix undefined, so the second case works
76
+ # where @name is [_blocks] and name is the name of the block
75
77
  inputName = if @config.namePrefix then "#{ @config.namePrefix }#{ @name }[#{ name }]" else "#{ @name }[#{ name }]"
76
78
  inputConfig.namePrefix = @config.namePrefix
79
+ # add extra config parameter to save the original block name for hash
80
+ # function to work properly
81
+ inputConfig.blockName = name
77
82
 
78
83
  return new inputClass(inputName, value, inputConfig, @object)
79
84
 
@@ -89,8 +94,11 @@ class @InputInverter
89
94
 
90
95
  hash: (hash={}) ->
91
96
  obj = {}
97
+ # workaround for using block names to have consistency
98
+ # while caching and versioning documents
92
99
  for key, input of @inputs
93
- input.hash(obj)
100
+ obj[input.config.blockName] = input.$input.val()
101
+
94
102
  hash[@config.klassName] = obj
95
103
  return hash
96
104
 
@@ -102,6 +110,7 @@ class @InputInverter
102
110
 
103
111
  showErrorMessage: (message) -> ;
104
112
 
113
+
105
114
  hideErrorMessage: -> ;
106
115
 
107
116
 
@@ -1,2 +1,8 @@
1
1
  #= require ./input-inverter
2
- #= require ./input-inverter-image
2
+ #= require ./input-inverter-link
3
+ #= require ./input-inverter-image
4
+ #= require ./input-inverter-version
5
+
6
+
7
+
8
+
@@ -0,0 +1,12 @@
1
+ //
2
+ // Styles for Inverter Character CMS plugin, this should be included in
3
+ // admin.scss (default)
4
+ //
5
+
6
+ .view.has-unsaved-changes .input-inverter-version select {
7
+ opacity: .25;
8
+ }
9
+
10
+
11
+
12
+
data/inverter.gemspec CHANGED
@@ -25,6 +25,9 @@ pulled from databased automatically.
25
25
 
26
26
  s.add_dependency("render_anywhere", ">= 0.0.10")
27
27
  s.add_dependency("meta-tags", ">= 2.0")
28
+ s.add_dependency("mongoid-history", ">= 0.4.7")
29
+ s.add_dependency("mongoid-slug", ">= 4.0.0")
30
+ s.add_dependency("redcarpet", ">= 3.2.3")
28
31
  end
29
32
 
30
33
 
@@ -0,0 +1,3 @@
1
+ class HistoryTracker
2
+ include Mongoid::History::Tracker
3
+ end
data/lib/inverter.rb CHANGED
@@ -1,11 +1,18 @@
1
+ require "mongoid_slug"
2
+ require "mongoid-history"
3
+ require "history_tracker"
4
+ require "redcarpet"
5
+
1
6
  require "inverter/concerns/inverter"
2
7
  require "inverter/object"
8
+ require "inverter/middleware"
3
9
  require "inverter/controller_helper"
4
10
  require "inverter/configuration"
5
11
  require "inverter/parser"
12
+ require "inverter/renderer"
6
13
  require "inverter/version"
7
- require "inverter/engine"
8
14
  require "inverter/template_renderer_helper"
15
+ require "inverter/engine"
9
16
 
10
17
  module Inverter
11
18
  extend Configuration
@@ -3,7 +3,11 @@ module Mongoid
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- # attributes
6
+ include Mongoid::Timestamps
7
+ include Mongoid::Slug
8
+ include Mongoid::History::Trackable
9
+
10
+ # ATTRIBUTES
7
11
  field :_page_title, default: ''
8
12
  field :_page_description, default: ''
9
13
  field :_page_keywords, default: ''
@@ -13,12 +17,31 @@ module Mongoid
13
17
  field :_name, default: ''
14
18
  field :_blocks, type: Hash, default: {}
15
19
 
16
- # indexes
20
+ # HISTORY
21
+ track_history track_create: true
22
+ # # telling Mongoid::History how you want to track changes
23
+ # # dynamic fields will be tracked automatically (for MongoId 4.0+ you should include Mongoid::Attributes::Dynamic to your model)
24
+ # track_history :on => [:title, :body], # track title and body fields only, default is :all
25
+ # :modifier_field => :modifier, # adds "belongs_to :modifier" to track who made the change, default is :modifier
26
+ # :modifier_field_inverse_of => :nil, # adds an ":inverse_of" option to the "belongs_to :modifier" relation, default is not set
27
+ # :version_field => :version, # adds "field :version, :type => Integer" to track current version, default is :version
28
+ # :track_create => false, # track document creation, default is false
29
+ # :track_update => true, # track document updates, default is true
30
+ # :track_destroy => false # track document destruction, default is false
31
+
32
+
33
+ # INDEXES
17
34
  index({ _template_name: 1 })
18
35
 
19
- # scopes
36
+ # SCOPES
20
37
  default_scope -> { asc(:created_at) }
21
38
 
39
+ # SLUG
40
+ # used in cms for direct object access
41
+ slug do |current_object|
42
+ current_object._template_name.gsub('.html.erb', '').gsub('/', '-')
43
+ end
44
+
22
45
 
23
46
  # returns title to be used in cms and identify page in list
24
47
  def list_item_title
@@ -26,6 +49,22 @@ module Mongoid
26
49
  end
27
50
 
28
51
 
52
+ # returns list of available object versions
53
+ def version_options
54
+ hash = {}
55
+
56
+ history_tracks.only(:created_at, :version).collect do |h|
57
+ hash[h.version] = "Version #{ h.version } — #{ h.created_at }"
58
+ end
59
+
60
+ if hash.empty?
61
+ hash = { '' => '--' }
62
+ end
63
+
64
+ return hash
65
+ end
66
+
67
+
29
68
  # populates seo values to cached meta_tags object which is
30
69
  # used by ActionController while template rendering
31
70
  def update_inverter_meta_tags
@@ -51,31 +90,23 @@ module Mongoid
51
90
  end
52
91
 
53
92
 
54
- # updates blocks in provided html with values from the
55
- # objects _blocks hash
93
+ # updates blocks in html with objects _blocks hash values
56
94
  def update_html(html)
57
- map = ::Inverter::Parser.map_blocks_for(html)
58
-
59
- offset = 0
60
-
61
- map.each do |name, pos|
62
- block = "\n" + self._blocks[name] + "\n"
63
- html[offset+pos[0]..offset+pos[1]] = block
95
+ html = ::Inverter::Renderer.render(html, self._blocks)
96
+ return html
97
+ end
64
98
 
65
- block_size = block.size
66
- template_block_size = pos[1] - pos[0]
67
- offset += block_size - template_block_size - 1
68
- end
69
99
 
70
- return html
100
+ # returns datetime when template was updated
101
+ def template_updated_at
102
+ template_path = Rails.root.to_s + '/app/views/' + self._template_name
103
+ File.mtime(template_path).getgm
71
104
  end
72
105
 
73
106
 
74
107
  # check if template file was changed after object was saved
75
108
  def template_changed?
76
- template_path = Rails.root.to_s + '/app/views/' + self._template_name
77
- template_time_updated = File.mtime(template_path)
78
- template_time_updated > updated_at
109
+ template_updated_at > updated_at.getgm
79
110
  end
80
111
 
81
112
 
@@ -105,6 +136,9 @@ module Mongoid
105
136
  # update page name
106
137
  self._name = name
107
138
 
139
+ # force update_at change event the conten not changed
140
+ self.updated_at = Time.now
141
+
108
142
  save
109
143
  end
110
144
 
@@ -129,20 +163,31 @@ module Mongoid
129
163
 
130
164
  # add new objects
131
165
  if existing_template_names.size < template_names.size
166
+ puts "\nCreate Inverter objects for new templates: "
132
167
  template_names_to_create = template_names - existing_template_names
133
- template_names_to_create.each { |name| create_from_template(name) }
168
+ template_names_to_create.each do |name|
169
+ create_from_template(name)
170
+ puts " - #{ name }"
171
+ end
134
172
  end
135
173
 
136
174
  # delete object for removed templates
137
175
  if existing_template_names.size > template_names.size
176
+ puts "\nDelete Inverter objects for missing templates: "
138
177
  template_names_to_remove = existing_template_names - template_names
139
- template_names_to_remove.each { |name| find_by(_template_name: name).delete }
178
+ template_names_to_remove.each do |name|
179
+ find_by(_template_name: name).delete
180
+ puts " - #{ name }"
181
+ end
140
182
  end
141
183
 
142
184
  # update objects for changes in templates
143
- created_objects.each do |o|
144
- if o.template_changed?
185
+ changed_objects = created_objects.select { |o| o.template_changed? }
186
+ if changed_objects.size > 0
187
+ puts "\nUpdate Inverter objects for changed templates: "
188
+ changed_objects.each do |o|
145
189
  o.update_from_template!
190
+ puts " - #{ o._template_name }"
146
191
  end
147
192
  end
148
193
  end
@@ -4,7 +4,8 @@ module Inverter
4
4
  attr_accessor(
5
5
  :model_class,
6
6
  :template_folders,
7
- :excluded_templates
7
+ :excluded_templates,
8
+ :disable_middleware
8
9
  )
9
10
 
10
11
  def configure
@@ -17,6 +18,7 @@ module Inverter
17
18
 
18
19
  def set_default_configuration
19
20
  self.excluded_templates = []
21
+ self.disable_middleware = false
20
22
  end
21
23
 
22
24
  end
@@ -2,4 +2,16 @@ module Inverter
2
2
  class Engine < Rails::Engine
3
3
  # auto wire
4
4
  end
5
- end
5
+
6
+ class Railtie < Rails::Railtie
7
+ if Rails.env.development?
8
+ initializer "inverter.configure_rails_initialization" do
9
+ Rails.application.middleware.use Inverter::Middleware
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+
16
+
17
+
@@ -0,0 +1,23 @@
1
+ module Inverter
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ # workaround this method so no need to call it if:
9
+ # - not GET request
10
+ # - not action request (assets or public files)
11
+
12
+ if ! Inverter.disable_middleware
13
+ Inverter.model_class.sync_with_templates!
14
+ end
15
+
16
+ @app.call(env)
17
+ end
18
+ end
19
+ end
20
+
21
+
22
+
23
+
@@ -0,0 +1,44 @@
1
+ module Inverter
2
+ class Renderer
3
+
4
+ def self.markdown_input_type?(name)
5
+ name_and_type = name.split(':')
6
+
7
+ if name_and_type.size > 1
8
+ return name_and_type[1].strip == 'markdown'
9
+ end
10
+
11
+ return false
12
+ end
13
+
14
+ def self.render(html, blocks)
15
+ # markdown configuration
16
+ # https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
17
+ markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true)
18
+
19
+ offset = 0
20
+ map = ::Inverter::Parser.map_blocks_for(html)
21
+
22
+ map.each do |name, pos|
23
+
24
+ block = blocks[name]
25
+
26
+ if markdown_input_type?(name)
27
+ block = markdown.render(block)
28
+ end
29
+
30
+ block = "\n#{ block }\n"
31
+
32
+ html[offset+pos[0]..offset+pos[1]] = block
33
+
34
+ block_size = block.size
35
+ template_block_size = pos[1] - pos[0]
36
+ offset += block_size - template_block_size - 1
37
+
38
+ end
39
+
40
+ return html
41
+ end
42
+
43
+ end
44
+ end
@@ -1,3 +1,3 @@
1
1
  module Inverter
2
- VERSION = "0.2.7"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -0,0 +1,26 @@
1
+ namespace :inverter do
2
+
3
+ desc "Reset all inverter objects to template defaults"
4
+ task :reset => :environment do
5
+ Inverter.model_class.delete_all
6
+ Inverter.model_class.sync_with_templates!
7
+
8
+ inverter_objects = Inverter.model_class.all
9
+ inverter_objects.each do |o|
10
+ puts " - #{ o._template_name }"
11
+ end
12
+ puts "\n#{ inverter_objects.size } objects created."
13
+ end
14
+
15
+
16
+ desc "Sync all inverter objects with template changes"
17
+ task :sync => :environment do
18
+ Inverter.model_class.sync_with_templates!
19
+ puts "Objects has been updated."
20
+ end
21
+
22
+ end
23
+
24
+
25
+
26
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inverter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Kravets
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-05 00:00:00.000000000 Z
11
+ date: 2015-04-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: render_anywhere
@@ -38,6 +38,48 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mongoid-history
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.4.7
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.4.7
55
+ - !ruby/object:Gem::Dependency
56
+ name: mongoid-slug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 4.0.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 4.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: redcarpet
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 3.2.3
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.2.3
41
83
  description: |
42
84
  Easy way to connect Rails templates content to CMS. HTML content is marked using
43
85
  special formatted comments. Then it automatically populated to models and is accessible
@@ -55,18 +97,25 @@ files:
55
97
  - README.md
56
98
  - Rakefile
57
99
  - app/assets/javascripts/input-inverter-image.coffee
100
+ - app/assets/javascripts/input-inverter-link.coffee
101
+ - app/assets/javascripts/input-inverter-version.coffee
58
102
  - app/assets/javascripts/input-inverter.coffee
59
103
  - app/assets/javascripts/inverter.coffee
104
+ - app/assets/stylesheets/_inverter.scss
60
105
  - inverter.gemspec
106
+ - lib/history_tracker.rb
61
107
  - lib/inverter.rb
62
108
  - lib/inverter/concerns/inverter.rb
63
109
  - lib/inverter/configuration.rb
64
110
  - lib/inverter/controller_helper.rb
65
111
  - lib/inverter/engine.rb
112
+ - lib/inverter/middleware.rb
66
113
  - lib/inverter/object.rb
67
114
  - lib/inverter/parser.rb
115
+ - lib/inverter/renderer.rb
68
116
  - lib/inverter/template_renderer_helper.rb
69
117
  - lib/inverter/version.rb
118
+ - lib/tasks/inverter.rake
70
119
  homepage: http://slatestudio.com
71
120
  licenses:
72
121
  - MIT