active_permalink 0.3.2 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/active_permalink.rb +11 -1
- data/lib/active_permalink/config.rb +27 -0
- data/lib/active_permalink/generator.rb +21 -2
- data/lib/active_permalink/loader.rb +9 -16
- data/lib/active_permalink/localizer.rb +100 -38
- data/lib/active_permalink/permalink.rb +0 -2
- data/lib/active_permalink/persistence.rb +30 -9
- data/lib/active_permalink/querying.rb +0 -4
- data/lib/active_permalink/version.rb +1 -1
- data/lib/generators/active_permalink/install_generator.rb +4 -0
- data/lib/generators/active_permalink/templates/initializer.rb +8 -0
- metadata +13 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fa20c1f3b8d87d139d4a4dd071f4eaf254e920f9c548d8972bee1d039d50447
|
4
|
+
data.tar.gz: fcfc097109ae5c2a061d248047d3afce7846281caca1af726531d957b8ce19a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 983b44808444eac00eec9208294601a8dd354e63ea2fe301b1ac6e18e704923d323dab9cb9a04ac1a0ae4ef3d799bdba1cd475083fe82e6b6362853b57e6ea69
|
7
|
+
data.tar.gz: 73f7a8cf127e57656898024e6f6c9f80b7111a1d32a347cfc585ad3dd41327482f428cc826e7dd8c77557298cf8124d7cd196c3d36136389c90bbfdfc2a3a9a9
|
data/lib/active_permalink.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'stringex'
|
2
1
|
require 'active_record'
|
3
2
|
require 'active_delegate'
|
4
3
|
require 'active_permalink/version'
|
@@ -12,6 +11,17 @@ module ActivePermalink
|
|
12
11
|
autoload :Localizer
|
13
12
|
autoload :Querying
|
14
13
|
autoload :Loader
|
14
|
+
autoload :Config
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def config
|
18
|
+
@config ||= Config.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup
|
22
|
+
yield config
|
23
|
+
end
|
24
|
+
end
|
15
25
|
end
|
16
26
|
|
17
27
|
ActiveSupport.on_load(:active_record) do
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_support/configurable'
|
2
|
+
|
3
|
+
module ActivePermalink
|
4
|
+
class Config
|
5
|
+
include ActiveSupport::Configurable
|
6
|
+
|
7
|
+
config_accessor(:class_name) { 'ActivePermalink::Permalink' }
|
8
|
+
config_accessor(:querying) { true }
|
9
|
+
config_accessor(:localized) { false }
|
10
|
+
config_accessor(:locale_column) { :locale }
|
11
|
+
config_accessor(:locale_accessors) { true }
|
12
|
+
config_accessor(:fallthrough_accessors) { false }
|
13
|
+
config_accessor(:fallbacks) { false }
|
14
|
+
|
15
|
+
def options_for(**options)
|
16
|
+
options.reverse_merge(
|
17
|
+
class_name: class_name,
|
18
|
+
querying: querying,
|
19
|
+
localized: localized,
|
20
|
+
locale_column: locale_column,
|
21
|
+
locale_accessors: locale_accessors,
|
22
|
+
fallthrough_accessors: fallthrough_accessors,
|
23
|
+
fallbacks: fallbacks
|
24
|
+
)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -1,6 +1,22 @@
|
|
1
|
+
require 'any_ascii'
|
2
|
+
|
1
3
|
module ActivePermalink
|
2
4
|
class Generator
|
5
|
+
class << self
|
6
|
+
def generate(record, value, locale = nil)
|
7
|
+
return if value.nil? && !record.slug_should_generate?
|
8
|
+
|
9
|
+
options = record.permalink_options.merge(locale: locale)
|
10
|
+
generator = Generator.new(record, options)
|
11
|
+
generator.generate(value)
|
12
|
+
|
13
|
+
record.permalinks = generator.permalinks
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
3
17
|
def initialize(record, options = {})
|
18
|
+
options[:locale] = options.fetch(:locale, I18n.locale).to_s
|
19
|
+
|
4
20
|
@record = record
|
5
21
|
@options = options
|
6
22
|
@field = options[:field]
|
@@ -22,7 +38,7 @@ module ActivePermalink
|
|
22
38
|
private
|
23
39
|
|
24
40
|
def locale
|
25
|
-
|
41
|
+
@options[:locale]
|
26
42
|
end
|
27
43
|
|
28
44
|
def changed?
|
@@ -75,7 +91,10 @@ module ActivePermalink
|
|
75
91
|
def slug_from_column
|
76
92
|
@slug_from_column ||= begin
|
77
93
|
value = @new_value.presence || @record.send(@field)
|
78
|
-
value.
|
94
|
+
return if value.blank?
|
95
|
+
|
96
|
+
value = AnyAscii.transliterate(value)
|
97
|
+
value.parameterize
|
79
98
|
end
|
80
99
|
end
|
81
100
|
|
@@ -3,18 +3,13 @@ module ActivePermalink
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
class_methods do
|
6
|
-
def has_permalink(field,
|
7
|
-
|
6
|
+
def has_permalink(field, **options)
|
7
|
+
options = ActivePermalink.config.options_for(field: field, **options)
|
8
8
|
|
9
9
|
class_attribute :permalink_options
|
10
|
+
self.permalink_options = options
|
10
11
|
|
11
|
-
|
12
|
-
field: field,
|
13
|
-
localized: localized,
|
14
|
-
locale_column: locale_column
|
15
|
-
)
|
16
|
-
|
17
|
-
with_options(as: :sluggable, class_name: 'ActivePermalink::Permalink') do
|
12
|
+
with_options(as: :sluggable, class_name: options[:class_name]) do
|
18
13
|
has_many :permalinks,
|
19
14
|
dependent: :destroy,
|
20
15
|
autosave: true
|
@@ -22,24 +17,22 @@ module ActivePermalink
|
|
22
17
|
has_many :old_permalinks,
|
23
18
|
-> { inactive }
|
24
19
|
|
25
|
-
if localized
|
20
|
+
if options[:localized]
|
26
21
|
has_many :active_permalinks,
|
27
22
|
-> { active }
|
28
23
|
|
29
24
|
has_one :active_permalink,
|
30
|
-
-> { active.where(locale_column => I18n.locale) }
|
25
|
+
-> { active.where(options[:locale_column] => I18n.locale) }
|
31
26
|
else
|
32
27
|
has_one :active_permalink,
|
33
28
|
-> { active }
|
34
29
|
end
|
35
30
|
end
|
36
31
|
|
37
|
-
delegate_attribute :slug, :string,
|
38
|
-
to: :active_permalink
|
39
|
-
|
40
32
|
include Persistence
|
41
|
-
|
42
|
-
include
|
33
|
+
|
34
|
+
include Querying if options[:querying]
|
35
|
+
include Localizer if options[:localized]
|
43
36
|
end
|
44
37
|
end
|
45
38
|
end
|
@@ -3,76 +3,91 @@ module ActivePermalink
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
def
|
7
|
-
|
6
|
+
def slug_backend
|
7
|
+
@slug_backend ||= PermalinkBackend.new(self)
|
8
8
|
end
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
alias permalink_reader slug_backend
|
11
|
+
|
12
|
+
def slug?(locale: nil)
|
13
|
+
slug_backend.exists?(locale || I18n.locale)
|
12
14
|
end
|
13
15
|
|
14
|
-
def slug
|
15
|
-
|
16
|
+
def slug(locale: nil)
|
17
|
+
slug_backend.read(locale || I18n.locale)
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
20
|
+
def slug=(value, locale: nil)
|
21
|
+
slug_backend.write(value, locale || I18n.locale)
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
if permalink_options[:locale_accessors]
|
25
|
+
include SlugLocaleAccessors
|
26
|
+
elsif permalink_options[:fallthrough_accessors]
|
27
|
+
include SlugFallthroughAccessors
|
28
|
+
end
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
+
private
|
31
|
+
|
32
|
+
def _generate_permalink_slug(value)
|
33
|
+
slug_backend.write(value, I18n.locale)
|
30
34
|
end
|
31
35
|
end
|
32
36
|
|
33
|
-
class
|
34
|
-
|
37
|
+
class InvalidLocale < I18n::InvalidLocale
|
38
|
+
end
|
39
|
+
|
40
|
+
class PermalinkBackend
|
41
|
+
attr_reader :record, :permalinks, :options
|
35
42
|
|
36
|
-
def initialize(
|
37
|
-
@
|
38
|
-
@options =
|
43
|
+
def initialize(record)
|
44
|
+
@record = record
|
45
|
+
@options = record.permalink_options
|
46
|
+
@permalinks = record.permalinks.to_a
|
39
47
|
end
|
40
48
|
|
41
49
|
def fallbacks?
|
42
50
|
options[:fallbacks].present?
|
43
51
|
end
|
44
52
|
|
45
|
-
def exists?
|
46
|
-
|
53
|
+
def exists?(locale)
|
54
|
+
enforce_available_locales!(locale)
|
55
|
+
find_permalink(locale).present?
|
56
|
+
end
|
57
|
+
|
58
|
+
def read(locale)
|
59
|
+
enforce_available_locales!(locale)
|
60
|
+
find_slug(locale)
|
47
61
|
end
|
48
62
|
|
49
|
-
def value
|
50
|
-
|
63
|
+
def write(value, locale)
|
64
|
+
enforce_available_locales!(locale)
|
65
|
+
update_slug(value, locale)
|
51
66
|
end
|
52
67
|
|
53
68
|
private
|
54
69
|
|
70
|
+
def enforce_available_locales!(locale)
|
71
|
+
return unless I18n.enforce_available_locales
|
72
|
+
return if I18n.available_locales.include?(locale.to_sym)
|
73
|
+
|
74
|
+
raise InvalidLocale.new(locale)
|
75
|
+
end
|
76
|
+
|
55
77
|
def locale_column
|
56
78
|
@options[:locale_column]
|
57
79
|
end
|
58
80
|
|
59
|
-
def find_permalink(
|
60
|
-
permalinks.find do |permalink|
|
61
|
-
permalink.send(locale_column)
|
81
|
+
def find_permalink(*locales)
|
82
|
+
permalinks.select(&:active?).find do |permalink|
|
83
|
+
locale = permalink.send(locale_column)
|
84
|
+
locales.include?(locale.to_sym)
|
62
85
|
end
|
63
86
|
end
|
64
87
|
|
65
88
|
def find_fallback(locale)
|
66
|
-
|
67
|
-
|
68
|
-
permalink = nil
|
69
|
-
|
70
|
-
fallbacks.find do |fallback|
|
71
|
-
permalink = find_permalink(fallback)
|
72
|
-
permalink.present?
|
73
|
-
end
|
74
|
-
|
75
|
-
permalink
|
89
|
+
locales = I18n.fallbacks[locale]
|
90
|
+
find_permalink(*locales) if locales.present?
|
76
91
|
end
|
77
92
|
|
78
93
|
def find_slug(locale)
|
@@ -81,6 +96,53 @@ module ActivePermalink
|
|
81
96
|
|
82
97
|
permalink.try(:slug)
|
83
98
|
end
|
99
|
+
|
100
|
+
def update_slug(value, locale)
|
101
|
+
Generator.generate(record, value, locale)
|
102
|
+
@permalinks = record.permalinks.to_a
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
module SlugLocaleAccessors
|
107
|
+
extend ActiveSupport::Concern
|
108
|
+
|
109
|
+
included do
|
110
|
+
I18n.available_locales.each do |locale|
|
111
|
+
define_method(:"slug_#{locale}?") do
|
112
|
+
slug_backend.exists?(locale)
|
113
|
+
end
|
114
|
+
|
115
|
+
define_method(:"slug_#{locale}") do
|
116
|
+
slug_backend.read(locale)
|
117
|
+
end
|
118
|
+
|
119
|
+
define_method(:"slug_#{locale}=") do |value|
|
120
|
+
slug_backend.write(value, locale)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
module SlugFallthroughAccessors
|
127
|
+
extend ActiveSupport::Concern
|
128
|
+
|
129
|
+
included do
|
130
|
+
method_name_regex = /\Aslug_([a-z]{2}(_[a-z]{2})?)(=?|\??)\z/.freeze
|
131
|
+
|
132
|
+
define_method :method_missing do |method_name, *arguments, **options, &block|
|
133
|
+
if method_name =~ method_name_regex
|
134
|
+
locale, suffix = $1.split('_')
|
135
|
+
locale = "#{locale}-#{suffix.upcase}" if suffix
|
136
|
+
public_send("slug#{$3}", *arguments, **options, locale: locale.to_sym)
|
137
|
+
else
|
138
|
+
super(method_name, *arguments, &block)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
define_method :respond_to_missing? do |method_name, include_private = false|
|
143
|
+
(method_name =~ method_name_regex) || super(method_name, include_private)
|
144
|
+
end
|
145
|
+
end
|
84
146
|
end
|
85
147
|
end
|
86
148
|
end
|
@@ -2,8 +2,6 @@ module ActivePermalink
|
|
2
2
|
class Permalink < ActiveRecord::Base
|
3
3
|
self.table_name = 'permalinks'
|
4
4
|
|
5
|
-
default_scope { order created_at: :desc }
|
6
|
-
|
7
5
|
scope :global, -> { where scope: :global }
|
8
6
|
scope :active, -> { where active: true }
|
9
7
|
scope :inactive, -> { where active: false }
|
@@ -3,21 +3,42 @@ module ActivePermalink
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
|
7
|
-
|
6
|
+
include ActiveDelegate
|
7
|
+
|
8
|
+
delegate_attribute :slug, :string,
|
9
|
+
to: :active_permalink
|
10
|
+
|
11
|
+
before_validation :slug_should_generate!,
|
12
|
+
on: [:create, :update],
|
13
|
+
if: :slug_needs_generate?
|
14
|
+
|
15
|
+
def slug=(value)
|
16
|
+
_generate_permalink_slug(value)
|
8
17
|
end
|
9
18
|
|
10
|
-
|
11
|
-
|
19
|
+
def old_slugs
|
20
|
+
@old_slugs ||= old_permalinks.pluck(:slug)
|
12
21
|
end
|
13
22
|
|
14
|
-
def
|
15
|
-
|
23
|
+
def slug_should_generate?
|
24
|
+
@slug_should_generate == true
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
16
28
|
|
17
|
-
|
18
|
-
|
29
|
+
def slug_needs_generate?
|
30
|
+
!slug? && send(:"#{permalink_options[:field]}_changed?")
|
31
|
+
end
|
32
|
+
|
33
|
+
def slug_should_generate!
|
34
|
+
@slug_should_generate = true
|
35
|
+
_generate_permalink_slug(self[:slug])
|
36
|
+
ensure
|
37
|
+
@slug_should_generate = false
|
38
|
+
end
|
19
39
|
|
20
|
-
|
40
|
+
def _generate_permalink_slug(value)
|
41
|
+
Generator.generate(self, value)
|
21
42
|
end
|
22
43
|
end
|
23
44
|
end
|
@@ -13,6 +13,10 @@ module ActivePermalink
|
|
13
13
|
migration_template 'migration.rb', 'db/migrate/create_permalinks.rb'
|
14
14
|
end
|
15
15
|
|
16
|
+
def create_config_file
|
17
|
+
template 'initializer.rb', 'config/initializers/active_permalink.rb'
|
18
|
+
end
|
19
|
+
|
16
20
|
def self.next_migration_number(dirname)
|
17
21
|
::ActiveRecord::Generators::Base.next_migration_number(dirname)
|
18
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_permalink
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonian Guveli
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -45,19 +45,19 @@ dependencies:
|
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '1.0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
48
|
+
name: any_ascii
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
53
|
+
version: '0.1'
|
54
54
|
type: :runtime
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '
|
60
|
+
version: '0.1'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: bundler
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,14 +78,14 @@ dependencies:
|
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '13.0'
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '13.0'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: minitest
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- README.md
|
113
113
|
- Rakefile
|
114
114
|
- lib/active_permalink.rb
|
115
|
+
- lib/active_permalink/config.rb
|
115
116
|
- lib/active_permalink/generator.rb
|
116
117
|
- lib/active_permalink/loader.rb
|
117
118
|
- lib/active_permalink/localizer.rb
|
@@ -120,12 +121,13 @@ files:
|
|
120
121
|
- lib/active_permalink/querying.rb
|
121
122
|
- lib/active_permalink/version.rb
|
122
123
|
- lib/generators/active_permalink/install_generator.rb
|
124
|
+
- lib/generators/active_permalink/templates/initializer.rb
|
123
125
|
- lib/generators/active_permalink/templates/migration.rb
|
124
126
|
homepage: https://github.com/hardpixel/active-permalink
|
125
127
|
licenses:
|
126
128
|
- MIT
|
127
129
|
metadata: {}
|
128
|
-
post_install_message:
|
130
|
+
post_install_message:
|
129
131
|
rdoc_options: []
|
130
132
|
require_paths:
|
131
133
|
- lib
|
@@ -140,8 +142,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
142
|
- !ruby/object:Gem::Version
|
141
143
|
version: '0'
|
142
144
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
144
|
-
signing_key:
|
145
|
+
rubygems_version: 3.1.4
|
146
|
+
signing_key:
|
145
147
|
specification_version: 4
|
146
148
|
summary: Add permalinks to ActiveRecord models
|
147
149
|
test_files: []
|