tenon 1.0.28 → 1.0.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.rdoc +52 -1
  3. data/app/assets/javascripts/tenon/features/i18n_fields.js.coffee +23 -0
  4. data/app/assets/javascripts/tenon/features/record_approval.js.coffee +0 -1
  5. data/app/assets/javascripts/tenon/features/tenon_content/editor.js.coffee +10 -9
  6. data/app/assets/javascripts/tenon/features/tenon_content/pop_out.js.coffee +1 -1
  7. data/app/assets/javascripts/tenon/tenon.js +1 -1
  8. data/app/assets/stylesheets/tenon/tenon.css.scss +1 -0
  9. data/app/assets/stylesheets/tenon/ui/i18n.css.scss +18 -0
  10. data/app/form_builders/tenon/form_builder.rb +1 -1
  11. data/app/helpers/tenon/tenon_helper.rb +6 -0
  12. data/app/models/tenon/event.rb +1 -1
  13. data/app/models/tenon/page.rb +1 -1
  14. data/app/models/tenon/post.rb +1 -1
  15. data/app/views/tenon/events/_form.html.haml +2 -0
  16. data/app/views/tenon/pages/_form.html.haml +2 -0
  17. data/app/views/tenon/posts/_form.html.haml +2 -0
  18. data/app/views/tenon/shared/_i18n_language_nav.html.haml +6 -0
  19. data/app/views/tenon/tenon_content/_builder.html.haml +10 -44
  20. data/app/views/tenon/tenon_content/_embed_modal.html.haml +10 -0
  21. data/app/views/tenon/tenon_content/_fields.html.haml +40 -0
  22. data/app/views/tenon/tenon_content/_row.html.haml +2 -2
  23. data/lib/generators/tenon/i18n_migrations/i18n_migrations_generator.rb +1 -1
  24. data/lib/generators/tenon/i18n_migrations/templates/migration.rb +2 -2
  25. data/lib/generators/tenon/scaffold/templates/view__form.html.haml +2 -0
  26. data/lib/tenon/tenon_content.rb +31 -9
  27. data/lib/tenon/version.rb +1 -1
  28. metadata +8 -4
  29. data/app/assets/javascripts/tenon/features/i18n.js.coffee +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b20101b1ae5ed68cc8f35d9b9e328496d3e4f84d
4
- data.tar.gz: f80fef4d9a7f943e239e29509635a6f2cc424448
3
+ metadata.gz: 0f31292ed262bf1eeae1fb0bb00ac37acb551b10
4
+ data.tar.gz: f8b164bfc44425021669ba467f4343a43c25b02a
5
5
  SHA512:
6
- metadata.gz: b1000c12fffc2d03eac160598ec9db64a9d4fd2ac1f663772fa0a643f4c9005f54b283cdcae8973889b7160259fc1ab7316353e63fd610ffeaaba9c5ae8ec091
7
- data.tar.gz: ed8fb9276d38ffb365b780ffb89af11915e53c0b03701dc443180f92de6299912fd9d23bc8cf53dda3d0777addeacffcb9313d605c3b2b9ebfc0700f8c4f77f0
6
+ metadata.gz: 3303d7b9786edaea91f301a8d75df832456bd19a42eaa39925fd694f140353d7efe210c05b534ddbec2e9d1abd292038650a30a4c5f11e84d8fa228f69e6b134
7
+ data.tar.gz: 48fba626c993e5567c154513ff1cf3bf196fd873cd0f9da4da26245471fb0fa75d43c1c9fcb1d139528793f5a4cd68724f5b0f199078ac8b430242aea88a7978
data/README.rdoc CHANGED
@@ -61,4 +61,55 @@ Restart your app and navigate to /tenon
61
61
 
62
62
  If you want to be able to use rspec, which would be good, you will also need to run:
63
63
 
64
- bundle exec rails generate rspec:install
64
+ bundle exec rails generate rspec:install
65
+
66
+
67
+ == Scaffolding
68
+
69
+ TODO: Write this section
70
+
71
+ == Item Revisions/History
72
+
73
+ TODO: Write this section
74
+
75
+ == Internationalization
76
+
77
+ Although Tenon is currently anglocentric it supports the addition of additional
78
+ languages and provides an interface for managing content in multiple languages.
79
+
80
+ To add internationalized fields, follow these steps:
81
+
82
+ 1. Tell Tenon which languages you want to support in config/initializers/tenon.rb
83
+
84
+ config.languages = {
85
+ "French" => :fr,
86
+ "German" => :de
87
+ # etc.
88
+ }
89
+
90
+ English is always assumed to exist and be the default language, but this will likely change in the future.
91
+
92
+ 2. Create or update config/i18n_fields.yml to tell Tenon which fields you would like to have internationalized.
93
+
94
+ tables:
95
+ cars:
96
+ - title
97
+ - description
98
+
99
+ events:
100
+ - title
101
+ - location
102
+ - description
103
+
104
+ 3. Generate and run the internationalization migration. The generator will only try to create columns that don't already exist, so you can use this generator multiple times throughout the development of your application.
105
+
106
+ rails generate tenon:i18n_migrations
107
+ rake db:migrate
108
+
109
+ 4. Ensure that you have passed the i18n: true flag anywhere you are using tenon_content on a model.
110
+
111
+ class MyModel < ActiveRecord::Base
112
+ tenon_content :description, i18n: true
113
+ end
114
+
115
+ Once you've done this and restarted your app you will see a language selection nav in the sidebar of each form that has internationalized fields.
@@ -0,0 +1,23 @@
1
+ class Tenon.features.I18nFields
2
+ constructor: ->
3
+ @$i18nFields = $('.i18n')
4
+ $('[data-i18n-lang]').on('click', @switchActiveFields)
5
+ @_detabifyInactiveFields()
6
+
7
+ switchActiveFields: (e) =>
8
+ $a = $(e.currentTarget)
9
+ $active = @$i18nFields.filter(".#{$a.data('i18n-lang')}")
10
+ @$i18nFields.removeClass('active')
11
+ $active.addClass('active')
12
+ @_detabifyInactiveFields()
13
+ @_toggleActiveLink($a)
14
+
15
+ _toggleActiveLink: ($a) =>
16
+ $li = $a.closest('li')
17
+ $li.siblings().removeClass('active')
18
+ $li.addClass('active')
19
+
20
+ _detabifyInactiveFields: =>
21
+ tags = 'input, select, textarea'
22
+ $('.i18n:not(.active)').find(tags).attr('tabindex', '-1')
23
+ $('.i18n.active').find(tags).attr('tabindex', '')
@@ -12,7 +12,6 @@ class Tenon.features.RecordApproval
12
12
  .fail((data)-> console.log(data))
13
13
 
14
14
  _finishToggle: =>
15
- console.log('fired')
16
15
  @$link.toggleClass('unapprove approve')
17
16
  if @$link.hasClass('approve')
18
17
  @_setTooltip('Approve')
@@ -3,24 +3,25 @@ class Tenon.features.tenonContent.Editor
3
3
  $('.tenon-content').on('cocoon:after-insert', @_rowInserted)
4
4
  $('.tenon-content').on('cocoon:after-remove', @_rowRemoved)
5
5
  $(document).on('input', '.editable-text', @_contentUpdated)
6
- @_updateButtons()
6
+ for div in $('.tn-tc')
7
+ @_updateButtons($(div))
7
8
 
8
9
  _rowInserted: (e) =>
9
10
  Tenon.mediumEditor.deactivate()
10
11
  new Tenon.features.Medium
11
- @_updateButtons()
12
+ @_updateButtons($(e.currentTarget).closest('.tn-tc'))
12
13
 
13
14
  _rowRemoved: (e) =>
14
- @_updateButtons()
15
+ @_updateButtons($(e.currentTarget).closest('.tn-tc'))
15
16
 
16
17
  _contentUpdated: (e) =>
17
18
  $editable = $(e.currentTarget)
18
19
  $editable.next('input[type=hidden]').val($editable.html())
19
20
 
20
- _updateButtons: =>
21
- if $('.tn-tc-row:visible').length == 0
22
- $('#tn-tc-add-content').show()
23
- $('#tn-tc-pop-out').hide()
21
+ _updateButtons: ($wrap)=>
22
+ if $wrap.find('.tn-tc-row:visible').length == 0
23
+ $wrap.find('.tn-tc-add-content').show()
24
+ $wrap.find('.tn-tc-pop-out').hide()
24
25
  else
25
- $('#tn-tc-add-content').hide()
26
- $('#tn-tc-pop-out').show()
26
+ $wrap.find('.tn-tc-add-content').hide()
27
+ $wrap.find('.tn-tc-pop-out').show()
@@ -12,7 +12,7 @@ class Tenon.features.tenonContent.PopOut
12
12
  $wrap.find('.tn-tc-pop-out-close').data('place', $link)
13
13
  $wrap.appendTo($template.find('.tn-tc-sizer'))
14
14
  $template.appendTo('body')
15
- $('.tn-tc-wrap a[data-size]:first').trigger('click')
15
+ $wrap.find('a[data-size]:first').trigger('click')
16
16
  $template.removeClass('hidden')
17
17
  $wrap.trigger('tenon.content.popped')
18
18
 
@@ -32,7 +32,7 @@ var Tenon = {
32
32
 
33
33
  Tenon.features.forms.init();
34
34
  Tenon.features.fileSelectWidget.init();
35
- new Tenon.features.i18n();
35
+ new Tenon.features.I18nFields();
36
36
  new Tenon.features.Flash();
37
37
  new Tenon.features.AssetCropping();
38
38
  new Tenon.features.AssetDetachment();
@@ -38,6 +38,7 @@
38
38
  @import 'tenon/layout/mobile';
39
39
 
40
40
  // UI Components, choose as needed
41
+ @import 'tenon/ui/i18n';
41
42
  @import 'tenon/ui/alerts';
42
43
  @import 'tenon/ui/asset-attachment';
43
44
  @import 'tenon/ui/asset-cropping';
@@ -0,0 +1,18 @@
1
+ .i18n-holder, #form-header div.i18n-holder {
2
+ float: none; display: block;
3
+ }
4
+
5
+ .i18n-frame {
6
+ position: relative;
7
+ width: 100%;
8
+
9
+ .i18n {
10
+ position: absolute;
11
+ top: 0px;
12
+ left: -9999px;
13
+ }
14
+
15
+ .active {
16
+ position: static;
17
+ }
18
+ }
@@ -81,7 +81,7 @@ module Tenon
81
81
 
82
82
  def internationalize_content(generator, method_name, content, options = {})
83
83
  if Tenon.config.languages
84
- content = content_tag(:div, content, class: 'i18n en')
84
+ content = content_tag(:div, content, class: 'i18n en active')
85
85
  Tenon.config.languages.each do |lang_title, lang|
86
86
  content += content_tag(:div, send(generator, method_name, options, lang, lang_title), class: "i18n #{lang}")
87
87
  end
@@ -71,5 +71,11 @@ module Tenon
71
71
  content_tag(:div, content, class: 'form-group inline')
72
72
  end
73
73
  end
74
+
75
+ def i18n_language_nav(table)
76
+ if Tenon.config.languages && I18nLookup.fields[:tables][table]
77
+ render 'tenon/shared/i18n_language_nav'
78
+ end
79
+ end
74
80
  end
75
81
  end
@@ -5,7 +5,7 @@ module Tenon
5
5
  scope :upcoming, -> { where(['ends_at > ?', Time.now]).order(:starts_at) }
6
6
  scope :past, -> { where(['ends_at < ?', Time.now]).order(:starts_at) }
7
7
  default_scope -> { order 'starts_at DESC' }
8
- tenon_content :description
8
+ tenon_content :description, i18n: true
9
9
  has_history includes: [:description_tenon_content_rows]
10
10
 
11
11
  # Validations
@@ -4,7 +4,7 @@ module Tenon
4
4
  acts_as_nested_set
5
5
  has_history except: [:lft, :rgt, :parent_id, :depth],
6
6
  includes: [:content_tenon_content_rows]
7
- tenon_content :content
7
+ tenon_content :content, i18n: true
8
8
  default_scope { order('tenon_pages.lft, tenon_pages.list_order') }
9
9
  scope :published, -> { where('publish_at <= ?', Time.now) }
10
10
  scope :find_for_menu, -> { published.where('parent_id IS NULL AND show_in_menu = ?', true).includes(:subpages) }
@@ -4,7 +4,7 @@ module Tenon
4
4
  default_scope { order('publish_at DESC') }
5
5
  scope :posted, -> { where('publish_at <= ?', Time.now) }
6
6
  scope :for_archive, ->(year, month) { where(Post.for_archive_conditions(year, month)) }
7
- tenon_content :content
7
+ tenon_content :content, i18n: true
8
8
  has_history includes: [:content_tenon_content_rows]
9
9
 
10
10
  # Relationships
@@ -4,6 +4,8 @@
4
4
  %h2 Events
5
5
  = link_to "New Event", new_event_path, class: 'btn btn-block btn-primary'
6
6
 
7
+ = i18n_language_nav(:events)
8
+
7
9
  = error_messages_for :event
8
10
 
9
11
  = autosaving_form_for @event do |f|
@@ -9,6 +9,8 @@
9
9
  %li.active= link_to 'Page Content', '#details', data: {toggle: 'tab'}
10
10
  %li= link_to 'Search Optimization', '#seo', data: {toggle: 'tab'}
11
11
 
12
+ = i18n_language_nav(:pages)
13
+
12
14
  = autosaving_form_for @page do |f|
13
15
  = error_messages_for :page
14
16
  .fields.large.tabs
@@ -9,6 +9,8 @@
9
9
  %li.active= link_to 'Post Content', '#details', data: {toggle: 'tab'}
10
10
  %li= link_to "Search Optimization", '#seo', data: {toggle: 'tab'}
11
11
 
12
+ = i18n_language_nav(:posts)
13
+
12
14
  = render "tenon/shared/posts_nav"
13
15
 
14
16
  = autosaving_form_for @post do |f|
@@ -0,0 +1,6 @@
1
+ %h4 Languages
2
+ %nav.i18n-nav
3
+ %ul
4
+ %li.active= link_to 'English', '#', data: { 'i18n-lang' => 'en' }
5
+ - Tenon.config.languages.each do |title, lang|
6
+ %li= link_to title, '#', data: { 'i18n-lang' => lang }
@@ -1,44 +1,10 @@
1
- %label= field.to_s.titleize
2
- .explanation
3
- Select rows from the library to build this section.
4
- You can format your text by highlighting it and selecting options from the pop-up menu.
5
-
6
- .tn-tc-main-actions
7
- = link_to '#', id: 'tn-tc-pop-out', class: 'tn-tc-pop-out btn btn-primary' do
8
- = fa_icon('eye')
9
- %span Edit in Preview Mode
10
-
11
- = link_to '#', id: 'tn-tc-add-content', class: 'tn-tc-add-content btn btn-primary', 'data-modal-target' => '.tenon-library', 'data-modal-clone' => 'true', 'data-modal-title' => 'Add Content', 'data-association-insertion-node' => "##{field}-tenon-content", 'data-association-insertion-method' => 'prepend', 'data-modal-handler' => 'Tenon.features.tenonContent.Library' do
12
- = fa_icon('plus-circle')
13
- %span Add Content
14
-
15
- .tn-tc-wrap
16
- .tn-tc-sizes
17
- %h2 Preview Mode
18
- %p
19
- Use preview mode to see how your content will look on different devices. You can still make edits when you're in preview mode, but the toolbars are hidden to give you a better picture of how your content will be laid out.
20
- = tenon_content_sizes
21
- = link_to 'Done', '#', class: 'tn-tc-pop-out-close btn btn-comp'
22
- .tenon-content{id: "#{field}-tenon-content"}
23
- = f.fields_for "#{field}_tenon_content_rows" do |row|
24
- - if row.object
25
- = render "tenon/tenon_content/row", f: row, row_partial: row.object.decorate.form_partial, field: field, title: row.object.row_type.titleize
26
-
27
- .tenon-library-holder
28
- .tenon-library
29
- %ul
30
- - Tenon::TenonContent::RowTypes::LIBRARY_ROW_TYPES.each do |title, row_type|
31
- %li= row_link(title, row_type, field, f)
32
- .spacer
33
-
34
-
35
- /- Shared Embed Code Modal Body
36
- .edit-embed-code
37
- .modal-body
38
- %label{for: 'embed_code'} Paste your embed code here
39
- %p.explanation
40
- Note: In order to get your embed to work with various screen sizes, you may want to get a code from
41
- = link_to 'http://embedresponsively.com/', 'http://embedresponsively.com/', target: '_'
42
- = text_area_tag 'embed_code'
43
-
44
- .modal-footer= link_to 'Update', '#', class: 'btn btn-comp update-embed-code'
1
+ - if Tenon.config.languages && f.object.send("#{field}_i18n?")
2
+ .i18n-holder
3
+ .i18n-frame
4
+ .i18n.en.active= render 'tenon/tenon_content/fields', field: field, f: f
5
+ - Tenon.config.languages.each do |title, lang|
6
+ .i18n{class: lang}= render 'tenon/tenon_content/fields', field: "#{field}_#{lang}", lang: lang, lang_title: title, f: f
7
+ - else
8
+ = render 'tenon/tenon_content/fields', field: field, f: f
9
+
10
+ = render 'tenon/tenon_content/embed_modal'
@@ -0,0 +1,10 @@
1
+ /- Shared Embed Code Modal Body
2
+ .edit-embed-code
3
+ .modal-body
4
+ %label{for: 'embed_code'} Paste your embed code here
5
+ %p.explanation
6
+ Note: In order to get your embed to work with various screen sizes, you may want to get a code from
7
+ = link_to 'http://embedresponsively.com/', 'http://embedresponsively.com/', target: '_'
8
+ = text_area_tag 'embed_code'
9
+
10
+ .modal-footer= link_to 'Update', '#', class: 'btn btn-comp update-embed-code'
@@ -0,0 +1,40 @@
1
+ .tn-tc{class: field}
2
+ %label
3
+ - if defined?(lang)
4
+ = field.gsub("_#{lang}", '').to_s.titleize
5
+ (#{lang_title})
6
+ - else
7
+ = field.to_s.titleize
8
+
9
+ .explanation
10
+ Select rows from the library to build this section.
11
+ You can format your text by highlighting it and selecting options from the pop-up menu.
12
+
13
+ .tn-tc-main-actions
14
+ = link_to '#', class: 'tn-tc-pop-out btn btn-primary' do
15
+ = fa_icon('eye')
16
+ %span Edit in Preview Mode
17
+
18
+ = link_to '#', class: 'tn-tc-add-content btn btn-primary', 'data-modal-target' => ".#{field} .tenon-library", 'data-modal-clone' => 'true', 'data-modal-title' => 'Add Content', 'data-association-insertion-node' => "##{field}-tenon-content", 'data-association-insertion-method' => 'prepend', 'data-modal-handler' => 'Tenon.features.tenonContent.Library' do
19
+ = fa_icon('plus-circle')
20
+ %span Add Content
21
+
22
+ .tn-tc-wrap
23
+ .tn-tc-sizes
24
+ %h2 Preview Mode
25
+ %p
26
+ Use preview mode to see how your content will look on different devices. You can still make edits when you're in preview mode, but the toolbars are hidden to give you a better picture of how your content will be laid out.
27
+ = tenon_content_sizes
28
+ = link_to 'Done', '#', class: 'tn-tc-pop-out-close btn btn-comp'
29
+ .tenon-content{id: "#{field}-tenon-content"}
30
+ = f.fields_for "#{field}_tenon_content_rows" do |row|
31
+ - if row.object
32
+ = render "tenon/tenon_content/row", f: row, row_partial: row.object.decorate.form_partial, field: field, title: row.object.row_type.titleize
33
+
34
+ .tenon-library-holder
35
+ .tenon-library
36
+ %ul
37
+ - Tenon::TenonContent::RowTypes::LIBRARY_ROW_TYPES.each do |title, row_type|
38
+ %li= row_link(title, row_type, field, f)
39
+ .spacer
40
+
@@ -4,7 +4,7 @@
4
4
  .actions
5
5
  %i.fa.fa-arrows.drag-anchor
6
6
 
7
- = link_to '#', class: 'tn-tc-open-library above', 'data-modal-target' => '.tenon-library', 'data-modal-title' => "Insert Content", 'data-modal-handler' => 'Tenon.features.tenonContent.Library', 'data-modal-clone' => 'true', 'data-tooltip' => '', title: 'Insert Content' do
7
+ = link_to '#', class: 'tn-tc-open-library above', 'data-modal-target' => ".#{field} .tenon-library", 'data-modal-title' => "Insert Content", 'data-modal-handler' => 'Tenon.features.tenonContent.Library', 'data-modal-clone' => 'true', 'data-tooltip' => '', title: 'Insert Content' do
8
8
  = fa_icon('plus-circle')
9
9
 
10
10
  = link_to_remove_association(fa_icon('trash-o'), f, {'data-confirm' => 'Are you sure?', 'data-wrapper-class' => 'tn-tc-row'})
@@ -15,5 +15,5 @@
15
15
 
16
16
  .tn-tc-bottombar
17
17
  .actions
18
- = link_to '#', class: 'tn-tc-open-library below', 'data-modal-target' => '.tenon-library', 'data-modal-title' => "Insert Content", 'data-modal-handler' => 'Tenon.features.tenonContent.Library', 'data-modal-clone' => 'true', 'data-tooltip' => '', title: 'Insert Content' do
18
+ = link_to '#', class: 'tn-tc-open-library below', 'data-modal-target' => ".#{field} .tenon-library", 'data-modal-title' => "Insert Content", 'data-modal-handler' => 'Tenon.features.tenonContent.Library', 'data-modal-clone' => 'true', 'data-tooltip' => '', title: 'Insert Content' do
19
19
  = fa_icon('plus-circle')
@@ -5,7 +5,7 @@ module Tenon
5
5
 
6
6
  def copy_files
7
7
  timestamp = Time.now.strftime('%Y%m%d%H%M%S')
8
- template('migration.rb', File.join('db/migrate', "#{timestamp}_add_i18n_fields_#{file_hash.capitalize}.rb"))
8
+ template('migration.rb', File.join('db/migrate', "#{timestamp}_add_i18n_fields_#{file_hash.downcase}.rb"))
9
9
  end
10
10
 
11
11
  private
@@ -1,4 +1,4 @@
1
- class AddI18nFields<%= file_hash %> < ActiveRecord::Migration
1
+ class AddI18nFields<%= file_hash.capitalize %> < ActiveRecord::Migration
2
2
  def change
3
3
  <% tables.each do |table, columns| -%>
4
4
  <% columns.each do |column| -%>
@@ -10,5 +10,5 @@ class AddI18nFields<%= file_hash %> < ActiveRecord::Migration
10
10
  <% end -%>
11
11
  <% end -%>
12
12
  <% end -%>
13
- end
13
+ end
14
14
  end
@@ -4,6 +4,8 @@
4
4
  %h2 <%= plural_name.titleize %>
5
5
  = link_to "New <%= singular_name.titleize %>", new_<%= singular_name %>_path, class: 'btn btn-block btn-primary'
6
6
 
7
+ = i18n_language_nav(:<%= plural_name %>)
8
+
7
9
  <% if has_seo? -%>
8
10
  %h4 Edit Options
9
11
  %nav
@@ -1,18 +1,40 @@
1
1
  module Tenon
2
2
  module TenonContent
3
- def self.included(mod)
4
- mod.extend(ClassMethods)
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
5
  end
6
6
 
7
7
  module ClassMethods
8
- def tenon_content(content_field)
8
+ def tenon_content(content_field, i18n: false)
9
+ Tenon::TenonContentBuilder.add_assoc(self, content_field)
10
+
11
+ define_method("#{content_field}_i18n?") { i18n }
12
+ if i18n && Tenon.config.languages
13
+ Tenon.config.languages.each do |title, lang|
14
+ Tenon::TenonContentBuilder.add_assoc(self, "#{content_field}_#{lang}")
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ class TenonContentBuilder
22
+ class << self
23
+ def add_assoc(klass, content_field)
9
24
  assoc = "#{content_field}_tenon_content_rows".to_sym
10
- has_many assoc,
11
- -> { where(item_method: content_field) },
12
- class_name: 'Tenon::TenonContent::Row',
13
- as: :item,
14
- dependent: :destroy
15
- accepts_nested_attributes_for assoc, allow_destroy: true
25
+ args = [assoc, -> { where(item_method: content_field) }, assoc_opts]
26
+ klass.send(:has_many, *args)
27
+ klass.send(:accepts_nested_attributes_for, assoc, allow_destroy: true)
28
+ end
29
+
30
+ private
31
+
32
+ def assoc_opts
33
+ {
34
+ class_name: 'Tenon::TenonContent::Row',
35
+ as: :item,
36
+ dependent: :destroy
37
+ }
16
38
  end
17
39
  end
18
40
  end
data/lib/tenon/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Tenon
2
- VERSION = '1.0.28'
2
+ VERSION = '1.0.29'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tenon
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.28
4
+ version: 1.0.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - factor[e] design initiative
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-14 00:00:00.000000000 Z
11
+ date: 2014-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: better_errors
@@ -947,7 +947,7 @@ files:
947
947
  - app/assets/javascripts/tenon/features/forms.js.erb
948
948
  - app/assets/javascripts/tenon/features/hamburger_navigation.js.coffee
949
949
  - app/assets/javascripts/tenon/features/header_menu.js.coffee
950
- - app/assets/javascripts/tenon/features/i18n.js.coffee
950
+ - app/assets/javascripts/tenon/features/i18n_fields.js.coffee
951
951
  - app/assets/javascripts/tenon/features/infinite_loading.js.coffee
952
952
  - app/assets/javascripts/tenon/features/item_version_autosave.js.coffee
953
953
  - app/assets/javascripts/tenon/features/item_version_index_handler.js.coffee
@@ -1041,6 +1041,7 @@ files:
1041
1041
  - app/assets/stylesheets/tenon/ui/forms.css.scss
1042
1042
  - app/assets/stylesheets/tenon/ui/generic-loader.css.scss
1043
1043
  - app/assets/stylesheets/tenon/ui/header-tools.css.scss
1044
+ - app/assets/stylesheets/tenon/ui/i18n.css.scss
1044
1045
  - app/assets/stylesheets/tenon/ui/list-style-toggle.css.scss
1045
1046
  - app/assets/stylesheets/tenon/ui/login.css.scss
1046
1047
  - app/assets/stylesheets/tenon/ui/medium-editor.css.scss
@@ -1229,6 +1230,7 @@ files:
1229
1230
  - app/views/tenon/settings/_seo.html.haml
1230
1231
  - app/views/tenon/settings/show.html.haml
1231
1232
  - app/views/tenon/shared/_asset_field.html.haml
1233
+ - app/views/tenon/shared/_i18n_language_nav.html.haml
1232
1234
  - app/views/tenon/shared/_main_nav.html.haml
1233
1235
  - app/views/tenon/shared/_pagination.json.jbuilder
1234
1236
  - app/views/tenon/shared/_posts_nav.html.haml
@@ -1253,6 +1255,8 @@ files:
1253
1255
  - app/views/tenon/tenon_callouts/new.html.haml
1254
1256
  - app/views/tenon/tenon_content/_builder.html.haml
1255
1257
  - app/views/tenon/tenon_content/_display.html.haml
1258
+ - app/views/tenon/tenon_content/_embed_modal.html.haml
1259
+ - app/views/tenon/tenon_content/_fields.html.haml
1256
1260
  - app/views/tenon/tenon_content/_row.html.haml
1257
1261
  - app/views/tenon/tenon_content/piece_types/display/_embedded_content.html.haml
1258
1262
  - app/views/tenon/tenon_content/piece_types/display/_image.html.haml
@@ -1485,7 +1489,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1485
1489
  version: '0'
1486
1490
  requirements: []
1487
1491
  rubyforge_project:
1488
- rubygems_version: 2.3.0
1492
+ rubygems_version: 2.2.2
1489
1493
  signing_key:
1490
1494
  specification_version: 4
1491
1495
  summary: A highly flexible mountable Rails CMS built for rapid application development.
@@ -1,10 +0,0 @@
1
- class Tenon.features.i18n
2
- constructor: ->
3
- $("#current_language").on("change", @_switchLanguage)
4
-
5
- _switchLanguage: ->
6
- val = $(this).val()
7
- $(".i18n").css position: "absolute"
8
- $("." + val).css position: "static"
9
- $("#current_language").val val
10
-