better_seo 1.0.0.1 → 1.0.0.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +30 -0
  3. data/.rubocop_todo.yml +360 -0
  4. data/CHANGELOG.md +44 -0
  5. data/README.md +7 -25
  6. data/lib/better_seo/analytics/google_analytics.rb +12 -12
  7. data/lib/better_seo/analytics/google_tag_manager.rb +7 -7
  8. data/lib/better_seo/configuration.rb +11 -5
  9. data/lib/better_seo/dsl/base.rb +1 -1
  10. data/lib/better_seo/dsl/open_graph.rb +2 -6
  11. data/lib/better_seo/dsl/twitter_cards.rb +5 -7
  12. data/lib/better_seo/generators/amp_generator.rb +8 -14
  13. data/lib/better_seo/generators/breadcrumbs_generator.rb +14 -13
  14. data/lib/better_seo/generators/canonical_url_manager.rb +8 -14
  15. data/lib/better_seo/generators/meta_tags_generator.rb +7 -6
  16. data/lib/better_seo/generators/open_graph_generator.rb +5 -5
  17. data/lib/better_seo/generators/robots_txt_generator.rb +5 -11
  18. data/lib/better_seo/generators/twitter_cards_generator.rb +4 -4
  19. data/lib/better_seo/image/optimizer.rb +2 -0
  20. data/lib/better_seo/rails/helpers/controller_helpers.rb +3 -1
  21. data/lib/better_seo/rails/helpers/seo_helper.rb +3 -7
  22. data/lib/better_seo/rails/helpers/structured_data_helper.rb +2 -2
  23. data/lib/better_seo/sitemap/generator.rb +1 -1
  24. data/lib/better_seo/sitemap/sitemap_index.rb +5 -5
  25. data/lib/better_seo/sitemap/url_entry.rb +9 -11
  26. data/lib/better_seo/structured_data/base.rb +2 -1
  27. data/lib/better_seo/structured_data/event.rb +1 -3
  28. data/lib/better_seo/structured_data/generator.rb +10 -10
  29. data/lib/better_seo/structured_data/recipe.rb +3 -4
  30. data/lib/better_seo/validators/seo_recommendations.rb +7 -7
  31. data/lib/better_seo/validators/seo_validator.rb +33 -23
  32. data/lib/better_seo/version.rb +1 -1
  33. data/lib/generators/better_seo/templates/better_seo.rb +2 -2
  34. metadata +3 -1
@@ -13,30 +13,37 @@ module BetterSeo
13
13
 
14
14
  length = title.length
15
15
 
16
- if length >= TITLE_MIN_LENGTH && length <= TITLE_MAX_LENGTH
16
+ if length.between?(TITLE_MIN_LENGTH, TITLE_MAX_LENGTH)
17
17
  { valid: true, score: 100, message: "Title length is optimal", length: length }
18
18
  elsif length < TITLE_MIN_LENGTH
19
19
  score = (length.to_f / TITLE_MIN_LENGTH * 70).to_i
20
- { valid: false, score: score, message: "Title is too short (minimum #{TITLE_MIN_LENGTH} characters recommended)", length: length }
20
+ { valid: false, score: score,
21
+ message: "Title is too short (minimum #{TITLE_MIN_LENGTH} characters recommended)", length: length }
21
22
  else
22
- score = [100 - (length - TITLE_MAX_LENGTH) * 2, 50].max
23
- { valid: false, score: score, message: "Title is too long (maximum #{TITLE_MAX_LENGTH} characters recommended)", length: length }
23
+ score = [100 - ((length - TITLE_MAX_LENGTH) * 2), 50].max
24
+ { valid: false, score: score,
25
+ message: "Title is too long (maximum #{TITLE_MAX_LENGTH} characters recommended)", length: length }
24
26
  end
25
27
  end
26
28
 
27
29
  def check_description(description)
28
- return { valid: false, score: 0, message: "Description is required", length: 0 } if description.nil? || description.empty?
30
+ if description.nil? || description.empty?
31
+ return { valid: false, score: 0, message: "Description is required",
32
+ length: 0 }
33
+ end
29
34
 
30
35
  length = description.length
31
36
 
32
- if length >= DESCRIPTION_MIN_LENGTH && length <= DESCRIPTION_MAX_LENGTH
37
+ if length.between?(DESCRIPTION_MIN_LENGTH, DESCRIPTION_MAX_LENGTH)
33
38
  { valid: true, score: 100, message: "Description length is optimal", length: length }
34
39
  elsif length < DESCRIPTION_MIN_LENGTH
35
40
  score = (length.to_f / DESCRIPTION_MIN_LENGTH * 70).to_i
36
- { valid: false, score: score, message: "Description is too short (minimum #{DESCRIPTION_MIN_LENGTH} characters recommended)", length: length }
41
+ { valid: false, score: score,
42
+ message: "Description is too short (minimum #{DESCRIPTION_MIN_LENGTH} characters recommended)", length: length }
37
43
  else
38
44
  score = [100 - (length - DESCRIPTION_MAX_LENGTH), 50].max
39
- { valid: false, score: score, message: "Description is too long (maximum #{DESCRIPTION_MAX_LENGTH} characters recommended)", length: length }
45
+ { valid: false, score: score,
46
+ message: "Description is too long (maximum #{DESCRIPTION_MAX_LENGTH} characters recommended)", length: length }
40
47
  end
41
48
  end
42
49
 
@@ -57,11 +64,11 @@ module BetterSeo
57
64
  total_headings: total
58
65
  }
59
66
 
60
- if h1_count == 0
67
+ if h1_count.zero?
61
68
  result.merge(valid: false, score: 50, message: "Missing H1 heading (exactly one H1 required)")
62
69
  elsif h1_count > 1
63
70
  result.merge(valid: false, score: 70, message: "Multiple H1 headings found (only one H1 recommended)")
64
- elsif total == 0
71
+ elsif total.zero?
65
72
  result.merge(valid: false, score: 0, message: "No headings found")
66
73
  else
67
74
  result.merge(valid: true, score: 100, message: "Heading structure is optimal")
@@ -73,7 +80,10 @@ module BetterSeo
73
80
  images = html.scan(/<img[^>]*>/)
74
81
  total = images.size
75
82
 
76
- return { valid: true, score: 100, total_images: 0, images_with_alt: 0, images_without_alt: 0, message: "No images to validate" } if total.zero?
83
+ if total.zero?
84
+ return { valid: true, score: 100, total_images: 0, images_with_alt: 0, images_without_alt: 0,
85
+ message: "No images to validate" }
86
+ end
77
87
 
78
88
  # Count images with alt text
79
89
  images_with_alt = images.count { |img| img =~ /alt=["'][^"']+["']/ }
@@ -95,7 +105,7 @@ module BetterSeo
95
105
 
96
106
  def validate_page(html)
97
107
  # Extract title
98
- title_match = html.match(/<title[^>]*>(.*?)<\/title>/m)
108
+ title_match = html.match(%r{<title[^>]*>(.*?)</title>}m)
99
109
  title = title_match ? title_match[1].strip : nil
100
110
 
101
111
  # Extract meta description
@@ -110,10 +120,10 @@ module BetterSeo
110
120
 
111
121
  # Calculate overall score (weighted average)
112
122
  overall_score = (
113
- title_result[:score] * 0.3 +
114
- description_result[:score] * 0.3 +
115
- headings_result[:score] * 0.2 +
116
- images_result[:score] * 0.2
123
+ (title_result[:score] * 0.3) +
124
+ (description_result[:score] * 0.3) +
125
+ (headings_result[:score] * 0.2) +
126
+ (images_result[:score] * 0.2)
117
127
  ).to_i
118
128
 
119
129
  # Collect issues
@@ -135,16 +145,16 @@ module BetterSeo
135
145
 
136
146
  def generate_report(validation)
137
147
  report = []
138
- report << "=" * 60
148
+ report << ("=" * 60)
139
149
  report << "SEO Validation Report"
140
- report << "=" * 60
150
+ report << ("=" * 60)
141
151
  report << ""
142
152
  report << "Overall Score: #{validation[:overall_score]}/100"
143
153
  report << ""
144
154
 
145
155
  # Title section
146
156
  report << "Title:"
147
- report << " Status: #{validation[:title][:valid] ? '' : ''}"
157
+ report << " Status: #{validation[:title][:valid] ? "" : ""}"
148
158
  report << " Score: #{validation[:title][:score]}/100"
149
159
  report << " Length: #{validation[:title][:length]} chars"
150
160
  report << " Message: #{validation[:title][:message]}"
@@ -152,7 +162,7 @@ module BetterSeo
152
162
 
153
163
  # Description section
154
164
  report << "Description:"
155
- report << " Status: #{validation[:description][:valid] ? '' : ''}"
165
+ report << " Status: #{validation[:description][:valid] ? "" : ""}"
156
166
  report << " Score: #{validation[:description][:score]}/100"
157
167
  report << " Length: #{validation[:description][:length]} chars"
158
168
  report << " Message: #{validation[:description][:message]}"
@@ -160,7 +170,7 @@ module BetterSeo
160
170
 
161
171
  # Headings section
162
172
  report << "Headings:"
163
- report << " Status: #{validation[:headings][:valid] ? '' : ''}"
173
+ report << " Status: #{validation[:headings][:valid] ? "" : ""}"
164
174
  report << " Score: #{validation[:headings][:score]}/100"
165
175
  report << " H1 Count: #{validation[:headings][:h1_count]}"
166
176
  report << " Total Headings: #{validation[:headings][:total_headings]}"
@@ -169,7 +179,7 @@ module BetterSeo
169
179
 
170
180
  # Images section
171
181
  report << "Images:"
172
- report << " Status: #{validation[:images][:valid] ? '' : ''}"
182
+ report << " Status: #{validation[:images][:valid] ? "" : ""}"
173
183
  report << " Score: #{validation[:images][:score]}/100"
174
184
  report << " Total Images: #{validation[:images][:total_images]}"
175
185
  report << " With Alt: #{validation[:images][:images_with_alt]}"
@@ -186,7 +196,7 @@ module BetterSeo
186
196
  report << ""
187
197
  end
188
198
 
189
- report << "=" * 60
199
+ report << ("=" * 60)
190
200
 
191
201
  report.join("\n")
192
202
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BetterSeo
4
- VERSION = "1.0.0.1"
4
+ VERSION = "1.0.0.2"
5
5
  end
@@ -4,14 +4,14 @@ BetterSeo.configure do |config|
4
4
  # Site-wide settings
5
5
  config.site_name = "My Site"
6
6
  config.default_locale = :en
7
- config.available_locales = [:en, :it, :fr, :de, :es]
7
+ config.available_locales = %i[en it fr de es]
8
8
 
9
9
  # Meta tags configuration
10
10
  config.meta_tags.default_title = "Default Title"
11
11
  config.meta_tags.title_separator = " | "
12
12
  config.meta_tags.append_site_name = true
13
13
  config.meta_tags.default_description = "Default description for your website"
14
- config.meta_tags.default_keywords = ["keyword1", "keyword2", "keyword3"]
14
+ config.meta_tags.default_keywords = %w[keyword1 keyword2 keyword3]
15
15
  config.meta_tags.default_author = "Your Name or Company"
16
16
 
17
17
  # Open Graph configuration
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_seo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.1
4
+ version: 1.0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - alessiobussolari
@@ -77,6 +77,7 @@ extra_rdoc_files: []
77
77
  files:
78
78
  - ".rspec"
79
79
  - ".rubocop.yml"
80
+ - ".rubocop_todo.yml"
80
81
  - CHANGELOG.md
81
82
  - CODE_OF_CONDUCT.md
82
83
  - LICENSE.txt
@@ -145,6 +146,7 @@ metadata:
145
146
  homepage_uri: https://github.com/alessiobussolari/better_seo
146
147
  source_code_uri: https://github.com/alessiobussolari/better_seo
147
148
  changelog_uri: https://github.com/alessiobussolari/better_seo/blob/main/CHANGELOG.md
149
+ rubygems_mfa_required: 'true'
148
150
  post_install_message:
149
151
  rdoc_options: []
150
152
  require_paths: