tenon 1.0.56 → 1.0.57

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: 3d25f0289d0204d15f98fd5cdee6f4eb20c02d57
4
- data.tar.gz: addc833b08b5718662d201b4eef53661f291cba8
3
+ metadata.gz: 2fa377e208a93cb3c4055726e4426d6c19071b95
4
+ data.tar.gz: 4a579c1c5d84967166901b55a7f4b99f64e6c7a2
5
5
  SHA512:
6
- metadata.gz: e752b86e68bcb4f30a3b209f7fc48145f2eab331f0840db60b5ca6f137d850b4a06064a755bf123e01b2d209d2f92d6e707da23b2fb425250f730a50dc737e19
7
- data.tar.gz: 84ea75bbfd4a959d4f3075a889508f4e52ef7958813cc1ebc66aad6c1f4b1636d996cc0c2dedcd0a7181f0cb5b313bb732a9a3970247695da9c521ca20d8e029
6
+ metadata.gz: e40afd867429f2e8022e558b10817730a56371cbb28fa678a86e07bca8c47f7ae474cabdbbbad876bd7868fd8f38a7637ce4c03baa3bc35164b1860bb9cfa9d7
7
+ data.tar.gz: 18ad631a0e525d60ee8397df3eacf4b5e9c936d85de9d59879a0f69b75d97332b1a49c1d8ce18eac0c9e0215af079df1495f3f86bda7b00ba77ae0492512fc03
@@ -28,7 +28,7 @@ class Tenon.features.tenonContent.ColumnSizing
28
28
  @_setSizes(word, newClass, siblingClass, newSiblingClass)
29
29
 
30
30
  _decreaseFrom: (word, num) =>
31
- unless num <= 2
31
+ unless num <= 1
32
32
  siblingClass = @_numberToWord(@_words.length - num)
33
33
  newSiblingClass = @_numberToWord(@_words.length - num + 1)
34
34
  newClass = @_numberToWord(num - 1)
@@ -4,6 +4,10 @@ module Tenon
4
4
  h.asset_icon(object)
5
5
  end
6
6
 
7
+ def tile
8
+ h.asset_tile(object)
9
+ end
10
+
7
11
  def human_size
8
12
  h.number_to_human_size(object.attachment_file_size)
9
13
  end
@@ -2,11 +2,11 @@ module Tenon
2
2
  module AssetHelper
3
3
  def asset_icon(asset)
4
4
  if asset.attachment.exists?(:thumbnail)
5
- i = image_tag(asset.attachment.url(:thumbnail))
5
+ image = image_tag(asset.attachment.url(:thumbnail))
6
6
  else
7
- i = image_tag(default_asset_thumbnail(asset))
7
+ image = image_tag(default_asset_thumbnail(asset))
8
8
  end
9
- asset_icon_link(asset, i)
9
+ asset_icon_link(asset, image)
10
10
  end
11
11
 
12
12
  def asset_icon_link(asset, icon)
@@ -17,6 +17,23 @@ module Tenon
17
17
  end
18
18
  end
19
19
 
20
+ def asset_tile(asset)
21
+ if asset.attachment.exists?(:tile)
22
+ image = image_tag(asset.attachment.url(:tile))
23
+ else
24
+ image = image_tag(default_asset_thumbnail(asset))
25
+ end
26
+ asset_tile_link(asset, image)
27
+ end
28
+
29
+ def asset_tile_link(asset, icon)
30
+ if asset.is_image?
31
+ link_to(icon, [:crop, asset], crop_options(asset))
32
+ else
33
+ link_to(icon, asset.attachment.url, target: '_')
34
+ end
35
+ end
36
+
20
37
  def default_asset_thumbnail(asset)
21
38
  if asset && asset.attachment_content_type.match('video')
22
39
  'tenon/thumb-video.png'
@@ -26,22 +43,21 @@ module Tenon
26
43
  end
27
44
 
28
45
  private
29
-
30
- def crop_options(asset)
31
- {
32
- class: 'asset-crop',
33
- data: {
34
- 'asset-id' => asset.id,
35
- 'post-crop-handler' => 'Tenon.features.AssetListPostCropHandler'
46
+ def crop_options(asset)
47
+ {
48
+ class: 'asset-crop',
49
+ data: {
50
+ 'asset-id' => asset.id,
51
+ 'post-crop-handler' => 'Tenon.features.AssetListPostCropHandler'
52
+ }
36
53
  }
37
- }
38
- end
54
+ end
39
55
 
40
- def default_options
41
- {
42
- 'data-modal-remote' => true,
43
- 'data-modal-title' => 'Edit Asset'
44
- }
56
+ def default_options
57
+ {
58
+ 'data-modal-remote' => true,
59
+ 'data-modal-title' => 'Edit Asset'
60
+ }
61
+ end
45
62
  end
46
- end
47
63
  end
@@ -0,0 +1,77 @@
1
+ module Tenon
2
+ module PieceHelper
3
+ def piece_image_tag(piece, options = {})
4
+ responsive_image_tag(piece, options, Tenon.config.breakpoints.front_end)
5
+ end
6
+
7
+ def backend_piece_image_tag(piece, options = {})
8
+ responsive_image_tag(piece, options, Tenon.config.breakpoints.back_end)
9
+ end
10
+
11
+ private
12
+ # Returns the actual image_tag
13
+ def responsive_image_tag(piece, options = {}, breakpoints)
14
+ srcset = generate_srcset(piece)
15
+ sizes = generate_sizes(piece, breakpoints)
16
+ # Let's just use an plain image_tag if responsive styles haven't been
17
+ # generated. We'll test for :x2000 to determine if that's the case
18
+ if piece.image.attachment.exists?(computed_style(piece, 'x2000'))
19
+ image_tag(piece.image.url(default_style(piece, breakpoints)), options.merge(srcset: srcset, sizes: sizes))
20
+ else
21
+ image_tag(piece.image.url(:_medium), options)
22
+ end
23
+ end
24
+
25
+ # Figure out the default style based on the largest size at the largest
26
+ # breakpoint for browsers that don't support srcset. This is at least
27
+ # better than always serving the largest style (:x2000).
28
+ def default_style(piece, breakpoints)
29
+ sizes = breakpoints[:full]
30
+
31
+ # calculate the image size at :full breakpoint based on the piece width
32
+ image_size = (piece.sizes[piece_size(piece).to_sym] / 12 * content_size(sizes, piece)).to_i
33
+
34
+ # round up to nearest 200
35
+ image_size = image_size.round(-2)
36
+ image_size += 100 if (image_size / 100).odd?
37
+
38
+ default_style = computed_style(piece, "x#{image_size}").to_sym
39
+
40
+ piece.image.attachment.exists?(default_style) ? default_style : :_medium
41
+ end
42
+
43
+ # Iterate through the defined breakpoints and lookup the tenon_content
44
+ # sizes for the piece's row's item type. Use sizes[:default] width if
45
+ # item_type-specific tenon_content width not defined.
46
+ def generate_sizes(piece, breakpoints)
47
+ breakpoints.map do |name, sizes|
48
+ "(min-width: #{sizes[:browser]}px) #{(piece.sizes[piece_size(piece).to_sym] / 12 * 100 * content_size(sizes, piece) / sizes[:browser]).to_i}vw"
49
+ end.join(', ')
50
+ end
51
+
52
+ # Build the srcset values from the list of piece styles (2000px-200px)
53
+ def generate_srcset(piece)
54
+ piece.styles.map do |name, width|
55
+ if piece.image.attachment.exists?(computed_style(piece, name).to_sym)
56
+ "#{piece.image.attachment.url(computed_style(piece, name).to_sym)} #{width}w"
57
+ else
58
+ "#{piece.image.attachment.url(:original)} #{width}w"
59
+ end
60
+ end.join(', ')
61
+ end
62
+
63
+ # Handle 'twelve' pieces that have size set to '' in the db
64
+ def piece_size(piece)
65
+ piece_size = piece.size == '' ? 'twelve' : piece.size
66
+ end
67
+
68
+ def computed_style(piece, style)
69
+ computed_style = "#{piece.image.style_prefix}_#{style}"
70
+ end
71
+
72
+ # Return the width of tenon_content for this piece, or the :default size
73
+ def content_size(sizes, piece)
74
+ sizes[piece.row.item_type.demodulize.downcase.to_sym] || sizes[:default]
75
+ end
76
+ end
77
+ end
@@ -28,18 +28,18 @@ module Tenon
28
28
 
29
29
  def tenon_content_sizes
30
30
  links = []
31
- Tenon.config.front_end[:breakpoints].each do |name, size|
32
- links << link_to(name.to_s.titleize, '#', class: 'btn btn-white', data: { size: size_for_breakpoint(size) })
31
+ Tenon.config.breakpoints.front_end.each do |name, widths|
32
+ links << link_to(name.to_s.titleize, '#', class: 'btn btn-white', data: { size: size_for_breakpoint(widths[:default]) })
33
33
  end
34
- last = Tenon.config.front_end[:breakpoints].values.last
34
+ last = Tenon.config.breakpoints.front_end.values.last
35
35
  links << link_to('Mobile', '#', class: 'btn btn-white', data: { size: 320, mobile: true })
36
36
  links.join('').html_safe
37
37
  end
38
38
 
39
39
  def size_for_breakpoint(breakpoint)
40
- content_cols = Tenon.config.front_end[:content_columns][:default]
41
- gutter_width = Tenon.config.front_end[:gutter]
42
- columns = Tenon.config.front_end[:columns]
40
+ content_cols = Tenon.config.grid.content_columns[:default]
41
+ gutter_width = Tenon.config.grid.gutter
42
+ columns = Tenon.config.grid.columns
43
43
  (((breakpoint + gutter_width) / columns.to_f) * content_cols) - gutter_width
44
44
  end
45
45
  end
@@ -1,6 +1,7 @@
1
1
  module Tenon
2
2
  class Asset < ActiveRecord::Base
3
3
  attr_accessor :crop_x, :crop_y, :crop_w, :crop_h, :duplicate
4
+
4
5
  # Scopes
5
6
  default_scope -> { order('created_at DESC').includes(:item_assets) }
6
7
 
@@ -1,7 +1,10 @@
1
1
  module Tenon
2
2
  class Photo < ActiveRecord::Base
3
3
  belongs_to :gallery, class_name: 'Gallery', foreign_key: 'gallery_id', inverse_of: :photos
4
- has_asset :file, styles: { original: '800x800>', thumbnail: '300x300#' }
4
+ has_asset :file, styles: {
5
+ original: '800x800>',
6
+ thumbnail: '300x300#' # DEPRECATED
7
+ }
5
8
  default_scope { order(:list_order) }
6
9
  end
7
10
  end
@@ -2,9 +2,43 @@ module Tenon
2
2
  module TenonContent
3
3
  class Piece < ActiveRecord::Base
4
4
  self.table_name = 'tenon_tenon_content_pieces'
5
+ attr_reader :sizes, :styles
6
+
7
+ def sizes
8
+ # to translate between the stored piece size in words and a number for math
9
+ {
10
+ :one => 1.0,
11
+ :two => 2.0,
12
+ :three => 3.0,
13
+ :four => 4.0,
14
+ :five => 5.0,
15
+ :six => 6.0,
16
+ :seven => 7.0,
17
+ :eight => 8.0,
18
+ :nine => 9.0,
19
+ :ten => 10.0,
20
+ :eleven => 11.0,
21
+ :twelve => 12.0
22
+ }
23
+ end
24
+
25
+ def styles
26
+ Hash[(1..10).map{|n| ["x#{n*200}", (n*200).to_s]}]
27
+ end
5
28
 
6
29
  # Scopes, attachments, etc.
7
- has_asset :image, styles: { wrap: '400', half: '600', full: '1400' }
30
+ has_asset :image, styles: {
31
+ x2000: '2000>',
32
+ x1800: '1800>',
33
+ x1600: '1600>',
34
+ x1400: '1400>',
35
+ x1200: '1200>',
36
+ x1000: '1000>',
37
+ x800: '800>',
38
+ x600: '600>',
39
+ x400: '400>',
40
+ x200: '200>'
41
+ }
8
42
 
9
43
  # Relationships
10
44
  belongs_to :row, class_name: '::Tenon::TenonContent::Row'
@@ -1,5 +1,5 @@
1
1
  json.extract!(asset,
2
- :id, :display_name, :icon, :to_param, :human_size,
2
+ :id, :display_name, :icon, :tile, :to_param, :human_size,
3
3
  :attachment_content_type, :edit_link, :delete_link,
4
4
  :crop_link, :download_link
5
5
  )
@@ -1,9 +1,9 @@
1
1
  .tn-tc-image{class: piece.stretch_to_fill? ? 'stretch' : ''}
2
2
  - if piece.image.present?
3
3
  - if piece.link_url.blank?
4
- = image_tag(piece.image.url(:_medium))
4
+ = piece_image_tag(piece)
5
5
  - else
6
- = link_to image_tag(piece.image.url(:_medium)), piece.link_url, target: '_'
6
+ = link_to piece_image_tag(piece), piece.link_url, target: '_'
7
7
  - else
8
8
  = image_tag('tenon/thumb-doc.png')
9
9
  - if piece.show_caption
@@ -4,7 +4,7 @@
4
4
  = f.hidden_field :stretch_to_fill
5
5
  .image{class: f.object.stretch_to_fill? ? 'stretch' : ''}
6
6
  - if f.object.image
7
- = image_tag(f.object.image.url(:_medium))
7
+ = backend_piece_image_tag(f.object)
8
8
  - else
9
9
  = link_to(new_item_asset_path, class: 'add-image', data: {'modal-remote' => true, 'modal-title' => "Select Image", 'modal-handler' => 'Tenon.features.tenonContent.AssetAttachment'}) do
10
10
  %span Add Image
@@ -2,21 +2,43 @@
2
2
  # by the site developer. There is a Settings module built into Tenon
3
3
  # where you can expose other settings to your client.
4
4
  Tenon.configure do |config|
5
- # Set up grid config for the front end. This is done here so that we can
6
- # present accurate sizing
7
- config.front_end = {
8
- breakpoints: {
9
- desktop: 1400,
10
- laptop: 960,
11
- tablet: 768
12
- },
13
- columns: 24,
14
- gutter: 20,
5
+ # Define all your breakpoints and associated tenon_content widths.
6
+ # This is necessary because you may have multiple models with tenon_content
7
+ # with different maximum widths and therefore different widths at various
8
+ # breakpoints. By getting more precise with these widths we can serve the
9
+ # most efficient responsive images to the front end.
10
+ # config.breakpoints.front_end = {
11
+ # full: {
12
+ # browser: 1920, # the width of the browser for this breakpoint
13
+ # default: 1920, # default tenon_content width for piece's without specific widths
14
+ # page: 1920, # the width of tenon_content for Pages
15
+ # post: 1920 # the width of tenon_content for Posts
16
+ # },
17
+ # desktop: {
18
+ # browser: 1400,
19
+ # default: 1400,
20
+ # page: 1400,
21
+ # post: 1400
22
+ # },
23
+ # laptop: {
24
+ # browser: 960,
25
+ # default: 960,
26
+ # page: 960,
27
+ # post: 960
28
+ # },
29
+ # tablet: {
30
+ # browser: 768,
31
+ # default: 768,
32
+ # page: 768,
33
+ # post: 768
34
+ # }
35
+ # }
15
36
 
16
- content_columns: {
17
- default: 18
18
- }
19
- }
37
+ # config.grid.columns = 24
38
+ # config.grid.gutter = 20
39
+ # config.grid.content_columns = {
40
+ # default: 18
41
+ # }
20
42
 
21
43
  # Set platform hints color(s)
22
44
  config.client_color = '#9c0f17'
@@ -47,4 +69,19 @@ Tenon.configure do |config|
47
69
 
48
70
  # If you need to add further config options you can add them
49
71
  # in lib/tenon.rb as attr_accessors to Tenon::Configuration
72
+
73
+ # config.front_end is DEPRECATED as of 1.0.57
74
+ config.front_end = {
75
+ breakpoints: {
76
+ desktop: 1400,
77
+ laptop: 960,
78
+ tablet: 768
79
+ },
80
+ columns: 24,
81
+ gutter: 20,
82
+
83
+ content_columns: {
84
+ default: 18
85
+ }
86
+ }
50
87
  end
@@ -1,4 +1,43 @@
1
- # desc "Explaining what the task does"
2
- # task :tenon do
3
- # # Task goes here
4
- # end
1
+ namespace :tenon do
2
+ desc "Generate Asset responsive styles"
3
+ task :generate_responsive_styles => :environment do
4
+ styles = [
5
+ :tenon_tenon_content_piece_image_x2000,
6
+ :tenon_tenon_content_piece_image_x1800,
7
+ :tenon_tenon_content_piece_image_x1600,
8
+ :tenon_tenon_content_piece_image_x1400,
9
+ :tenon_tenon_content_piece_image_x1200,
10
+ :tenon_tenon_content_piece_image_x1000,
11
+ :tenon_tenon_content_piece_image_x800,
12
+ :tenon_tenon_content_piece_image_x600,
13
+ :tenon_tenon_content_piece_image_x400,
14
+ :tenon_tenon_content_piece_image_x200
15
+ ]
16
+
17
+ item_assets = Tenon::ItemAsset.where(item_type: 'Tenon::TenonContent::Piece').pluck(:asset_id).uniq
18
+
19
+ # only reprocess assets that are referenced by Pieces, and only do them once each even if they are referenced by multiple pieces
20
+ Tenon::Asset.find(item_assets).each_with_index do |asset, i|
21
+ print "(#{i+1}/#{item_assets.count}) #{asset.attachment_file_name} "
22
+ styles.each do |style|
23
+ asset.attachment.reprocess! style
24
+ print '.'
25
+ $stdout.flush
26
+ end
27
+ puts ''
28
+ end
29
+ puts 'Done!'
30
+ end
31
+
32
+ desc "Regenerate all Asset styles"
33
+ task :regenerate_asset_styles => :environment do
34
+ total_assets = Tenon::Asset.all.count
35
+
36
+ Tenon::Asset.all.each_with_index do |asset, i|
37
+ puts "(#{i+1}/#{total_assets}) #{asset.attachment_file_name} "
38
+ asset.attachment.reprocess!
39
+ end
40
+ puts 'Done!'
41
+ end
42
+
43
+ end
@@ -22,7 +22,8 @@ module Tenon
22
22
  {
23
23
  original: { processors: ['cropper'], geometry: '' },
24
24
  thumbnail: '200x200#',
25
- medium: '1400>'
25
+ medium: '1400>', # DEPRECATED
26
+ tile: '350x350#',
26
27
  }
27
28
  end
28
29
 
@@ -0,0 +1,77 @@
1
+ module Tenon
2
+ class Configuration
3
+ attr_accessor :breakpoints
4
+
5
+ def breakpoints
6
+ @breakpoints ||= BreakpointConfiguration.new
7
+ end
8
+
9
+ class BreakpointConfiguration
10
+ attr_accessor :front_end, :back_end, :grid
11
+
12
+ def initialize
13
+ # Define all your breakpoints and associated tenon_content widths.
14
+ # This is necessary because you may have multiple models with tenon_content
15
+ # with different maximum widths and therefore different widths at various
16
+ # breakpoints. By getting more precise with these widths we can serve the
17
+ # most efficient responsive images to the front end.
18
+ @front_end = {
19
+ full: {
20
+ browser: 1920, # the width of the browser for this breakpoint
21
+ default: 1920, # default tenon_content width for piece's without specific widths
22
+ page: 1920, # the width of tenon_content for Pages
23
+ post: 1920 # the width of tenon_content for Posts
24
+ },
25
+ desktop: {
26
+ browser: 1400,
27
+ default: 1400,
28
+ page: 1400,
29
+ post: 1400
30
+ },
31
+ laptop: {
32
+ browser: 960,
33
+ default: 960,
34
+ page: 960,
35
+ post: 960
36
+ },
37
+ tablet: {
38
+ browser: 768,
39
+ default: 768,
40
+ page: 768,
41
+ post: 768
42
+ }
43
+ }
44
+
45
+ # set up the back-end breakpoints and associated tenon_content widths since
46
+ # we know what they always are
47
+ @back_end = {
48
+ full: {
49
+ browser: 1920,
50
+ default: 1225
51
+ },
52
+ desktop: {
53
+ browser: 1400,
54
+ default: 740
55
+ },
56
+ laptop: {
57
+ browser: 960,
58
+ default: 680
59
+ },
60
+ tablet: {
61
+ browser: 768,
62
+ default: 750
63
+ }
64
+ }
65
+
66
+ @grid = {
67
+ columns: 24,
68
+ gutter: 20,
69
+
70
+ content_columns: {
71
+ default: 18
72
+ }
73
+ }
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,21 @@
1
+ module Tenon
2
+ class Configuration
3
+ attr_accessor :grid
4
+
5
+ def grid
6
+ @grid ||= GridConfiguration.new
7
+ end
8
+
9
+ class GridConfiguration
10
+ attr_accessor :columns, :gutter, :content_columns
11
+
12
+ def initialize
13
+ @columns = 24
14
+ @gutter = 20
15
+ @content_columns = {
16
+ default: 18
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,6 +1,6 @@
1
1
  module Tenon
2
2
  class ProxyAttachment
3
- attr_reader :attachment, :asset
3
+ attr_reader :attachment, :asset, :style_prefix
4
4
 
5
5
  def initialize(attachment, klass, asset_name)
6
6
  @attachment = attachment.try(:attachment) || attachment
data/lib/tenon/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Tenon
2
- VERSION = '1.0.56'
2
+ VERSION = '1.0.57'
3
3
  end
data/lib/tenon.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'tenon/engine'
2
+ require 'tenon/config/breakpoints.rb'
2
3
  require 'tenon/config/events.rb'
4
+ require 'tenon/config/grid.rb'
3
5
  require 'tenon/can_be_foreign.rb'
4
6
  require 'tenon/can_have_comments.rb'
5
7
  require 'tenon/has_asset.rb'
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.56
4
+ version: 1.0.57
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: 2015-01-28 00:00:00.000000000 Z
11
+ date: 2015-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: better_errors
@@ -1110,6 +1110,7 @@ files:
1110
1110
  - app/helpers/tenon/i18n_helper.rb
1111
1111
  - app/helpers/tenon/item_version_helper.rb
1112
1112
  - app/helpers/tenon/nav_helper.rb
1113
+ - app/helpers/tenon/piece_helper.rb
1113
1114
  - app/helpers/tenon/platform_hints_helper.rb
1114
1115
  - app/helpers/tenon/tenon_content_helper.rb
1115
1116
  - app/helpers/tenon/tenon_helper.rb
@@ -1378,7 +1379,9 @@ files:
1378
1379
  - lib/tenon/asset_style_generator.rb
1379
1380
  - lib/tenon/can_be_foreign.rb
1380
1381
  - lib/tenon/can_have_comments.rb
1382
+ - lib/tenon/config/breakpoints.rb
1381
1383
  - lib/tenon/config/events.rb
1384
+ - lib/tenon/config/grid.rb
1382
1385
  - lib/tenon/engine.rb
1383
1386
  - lib/tenon/factories/assets.rb
1384
1387
  - lib/tenon/factories/comments.rb