better_seo 0.5.0 → 0.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96812d57f991f56ae85d042ed90d67cd804da41be917f557c9035b7103704fa0
4
- data.tar.gz: ba04b33847262251dbce411840acee273e7f36c3f25e3b02a6fd2aaacf88bbe9
3
+ metadata.gz: 5c5febaa764505c7680d89bd6858600708fbd362d811818c7206b6e8f8768b32
4
+ data.tar.gz: 7a6928082bed979115b7411049182fbd6591ac0156fa5670a9cadb843d3b23d8
5
5
  SHA512:
6
- metadata.gz: 587ba80330156dc5a305ea2d92831939fa9f80b6341bdb1052d639d371b8892d9827ddd0ce24b4b07c0c67714aec87151dcc31bc515031aee055a10703d3bf0f
7
- data.tar.gz: 8dfe3c3526d621ee904535484e70529c68550d2388f289408a40f044651f154f6cb424f8715967d3d9dcaf8aa652f48bdb0ddda1e505c882c37f8fe01c9a1dbc
6
+ metadata.gz: 8a4c80163add6a90ddabb694ec95c6defddf0ef4a3357bc0e3defc2ea4cb3ace4556bec7f5303571dbc72caf860f0092f54c43e61a4f8a70f573b88d6d39b146
7
+ data.tar.gz: 9abc8a475e9380e85b0a410547f63eca11682f21b0271acbab83a6f855212c888c3a937d9db5358e0518697acb3af61d9e852060a0f871dd80b86c313eb43916
data/CHANGELOG.md CHANGED
@@ -7,6 +7,73 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.0] - 2025-01-23
11
+
12
+ ### Added
13
+ - Additional Structured Data types for e-commerce and navigation
14
+ - `StructuredData::Product` - E-commerce products with comprehensive schema
15
+ - `StructuredData::BreadcrumbList` - Navigation breadcrumbs for site structure
16
+ - Product features
17
+ - Full product information (name, description, image, brand)
18
+ - SKU, GTIN, MPN identifiers support
19
+ - Offers with price, currency, availability (InStock, OutOfStock, PreOrder, etc.)
20
+ - Multiple offers support for variants
21
+ - Aggregate ratings with review count
22
+ - Individual reviews with author and rating
23
+ - Multiple reviews array support
24
+ - Availability URL mapping to Schema.org standards
25
+ - BreadcrumbList features
26
+ - Add single items with `add_item`
27
+ - Add multiple items with `add_items`
28
+ - Automatic position numbering
29
+ - Manual position override support
30
+ - Clear all items with `clear`
31
+ - Fluent method chaining
32
+ - Generates proper ListItem structure
33
+ - Generator helper methods
34
+ - `Generator.product` factory method with block support
35
+ - `Generator.breadcrumb_list` factory method
36
+ - Rails integration examples
37
+ - Product page structured data helpers
38
+ - Breadcrumb integration with Rails routes
39
+ - E-commerce view helpers
40
+
41
+ ### Test Coverage
42
+ - 530 tests passing (+39 from v0.6.0)
43
+ - 98.89% code coverage (894/904 lines)
44
+ - 39 new tests for Product and BreadcrumbList
45
+
46
+ ## [0.6.0] - 2025-01-23
47
+
48
+ ### Added
49
+ - Structured Data (JSON-LD) support with comprehensive Schema.org implementation
50
+ - `StructuredData::Base` - Generic base class for all structured data types
51
+ - `StructuredData::Organization` - Company/organization information with full schema support
52
+ - `StructuredData::Article` - Blog posts, news articles with author/publisher metadata
53
+ - `StructuredData::Person` - Author profiles, team members with social links
54
+ - `StructuredData::Generator` - Helper class with factory methods
55
+ - Structured data features
56
+ - Fluent API with method chaining for all types
57
+ - Automatic nested object handling (Person within Article, etc.)
58
+ - JSON-LD generation with `to_json` and `to_script_tag` methods
59
+ - Schema.org compliant output format
60
+ - Address handling with PostalAddress schema
61
+ - Social profile links with sameAs property
62
+ - Rails integration patterns
63
+ - View helpers for structured data
64
+ - Layout integration examples
65
+ - Complete production examples
66
+ - Comprehensive documentation
67
+ - 300+ lines of structured data documentation in README
68
+ - Complete examples for Organization, Article, Person
69
+ - Rails integration patterns and helper methods
70
+ - Nested data examples
71
+
72
+ ### Test Coverage
73
+ - 491 tests passing (+107 from v0.5.0)
74
+ - 99.64% code coverage (820/823 lines)
75
+ - 117 new tests for structured data functionality
76
+
10
77
  ## [0.5.0] - 2025-01-23
11
78
 
12
79
  ### Added
data/README.md CHANGED
@@ -2,14 +2,14 @@
2
2
 
3
3
  A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a clean, fluent DSL for managing meta tags, Open Graph, Twitter Cards, structured data, sitemaps, and more.
4
4
 
5
- [![Tests](https://img.shields.io/badge/tests-384%20passing-brightgreen)](https://github.com/yourusername/better_seo)
6
- [![Coverage](https://img.shields.io/badge/coverage-99.71%25-brightgreen)](https://github.com/yourusername/better_seo)
5
+ [![Tests](https://img.shields.io/badge/tests-530%20passing-brightgreen)](https://github.com/yourusername/better_seo)
6
+ [![Coverage](https://img.shields.io/badge/coverage-98.89%25-brightgreen)](https://github.com/yourusername/better_seo)
7
7
  [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.0.0-red)](https://www.ruby-lang.org)
8
8
  [![Rails](https://img.shields.io/badge/rails-%3E%3D%206.1-red)](https://rubyonrails.org)
9
9
 
10
10
  ## Features
11
11
 
12
- ### ✅ Implemented (v0.5.0)
12
+ ### ✅ Implemented (v0.7.0)
13
13
 
14
14
  - **Core Configuration System**
15
15
  - Singleton configuration with block-style setup
@@ -48,19 +48,39 @@ A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a cl
48
48
  - **Validation**: Automatic URL validation (format, protocol)
49
49
  - **Method Chaining**: Fluent interface for adding multiple URLs
50
50
 
51
+ - **Structured Data (JSON-LD)**
52
+ - **Base Class**: Generic structured data with full Schema.org support
53
+ - **Organization**: Company/organization information with address, social profiles
54
+ - **Article**: Blog posts, news articles with author, publisher, metadata
55
+ - **Person**: Author profiles, team members with job title, social links
56
+ - **Product**: E-commerce products with price, availability, ratings, reviews
57
+ - **BreadcrumbList**: Navigation breadcrumbs for improved site structure
58
+ - **Generator Helper**: Factory methods and batch script tag generation
59
+ - **Nested Data**: Automatic handling of complex object relationships
60
+ - **JSON-LD Output**: Valid Schema.org JSON-LD format
61
+ - **Rails Integration**: View helpers and layout integration
62
+
51
63
  ### 🚧 Planned
52
64
 
53
- - **Advanced Generators** (v0.6.0)
54
- - Schema.org JSON-LD generator
55
- - Breadcrumbs generator
65
+ - **Additional Structured Data Types** (v0.8.0)
66
+ - LocalBusiness (physical locations with hours, geo)
67
+ - Event (conferences, webinars with dates, location)
68
+ - FAQPage (structured FAQ with questions/answers)
69
+ - HowTo (step-by-step guides)
70
+ - Recipe (cooking recipes with ingredients)
71
+
72
+ - **Advanced Generators** (v0.7.0)
73
+ - Breadcrumbs HTML generator
56
74
  - AMP HTML generator
75
+ - Canonical URL management
57
76
 
58
- - **Advanced Rails Integration** (v0.6.0)
77
+ - **Advanced Rails Integration** (v0.7.0)
59
78
  - Controller helpers for setting page SEO
60
79
  - Railtie for automatic initialization
61
80
  - Generator for initializer file
81
+ - Automatic meta tags from model attributes
62
82
 
63
- - **Advanced Sitemap Features** (v0.6.0)
83
+ - **Advanced Sitemap Features** (v0.7.0)
64
84
  - Multi-language sitemap support (hreflang)
65
85
  - Sitemap index for large sites (50,000+ URLs)
66
86
  - Image/video sitemap extensions
@@ -79,7 +99,7 @@ A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a cl
79
99
  Add this line to your application's Gemfile:
80
100
 
81
101
  ```ruby
82
- gem 'better_seo', '~> 0.5.0'
102
+ gem 'better_seo', '~> 0.7.0'
83
103
  ```
84
104
 
85
105
  And then execute:
@@ -99,7 +119,7 @@ gem install better_seo
99
119
  Add this line to your application's Gemfile:
100
120
 
101
121
  ```ruby
102
- gem 'better_seo', git: 'https://github.com/alessiobussolari/better_seo.git', tag: 'v0.5.0'
122
+ gem 'better_seo', git: 'https://github.com/alessiobussolari/better_seo.git', tag: 'v0.7.0'
103
123
  ```
104
124
 
105
125
  Or clone and build locally:
@@ -108,7 +128,7 @@ Or clone and build locally:
108
128
  git clone https://github.com/alessiobussolari/better_seo.git
109
129
  cd better_seo
110
130
  gem build better_seo.gemspec
111
- gem install better_seo-0.5.0.gem
131
+ gem install better_seo-0.7.0.gem
112
132
  ```
113
133
 
114
134
  ## Quick Start
@@ -1020,6 +1040,335 @@ end
1020
1040
  # SitemapGeneratorService.generate
1021
1041
  ```
1022
1042
 
1043
+ ### 7. Structured Data (JSON-LD)
1044
+
1045
+ BetterSeo provides comprehensive support for Schema.org structured data using JSON-LD format, helping search engines better understand your content.
1046
+
1047
+ #### Basic Usage
1048
+
1049
+ Create structured data objects and generate JSON-LD script tags:
1050
+
1051
+ ```ruby
1052
+ # Create an Organization
1053
+ org = BetterSeo::StructuredData::Organization.new
1054
+ org.name("Acme Corporation")
1055
+ org.url("https://www.acme.com")
1056
+ org.logo("https://www.acme.com/logo.png")
1057
+ org.description("Leading provider of innovative solutions")
1058
+
1059
+ # Generate JSON-LD script tag
1060
+ org.to_script_tag
1061
+ # <script type="application/ld+json">
1062
+ # {
1063
+ # "@context": "https://schema.org",
1064
+ # "@type": "Organization",
1065
+ # "name": "Acme Corporation",
1066
+ # ...
1067
+ # }
1068
+ # </script>
1069
+ ```
1070
+
1071
+ #### Available Types
1072
+
1073
+ **Organization** - Company/organization information:
1074
+
1075
+ ```ruby
1076
+ org = BetterSeo::StructuredData::Organization.new
1077
+ org.name("Tech Innovations Inc")
1078
+ org.url("https://techinnovations.com")
1079
+ org.logo("https://techinnovations.com/logo.png")
1080
+ org.description("Innovative technology solutions")
1081
+ org.email("contact@techinnovations.com")
1082
+ org.telephone("+1-555-0100")
1083
+ org.address(
1084
+ street: "123 Tech Boulevard",
1085
+ city: "San Francisco",
1086
+ region: "CA",
1087
+ postal_code: "94105",
1088
+ country: "US"
1089
+ )
1090
+ org.same_as([
1091
+ "https://twitter.com/techinnovations",
1092
+ "https://linkedin.com/company/techinnovations"
1093
+ ])
1094
+ org.founding_date("2015-03-20")
1095
+ ```
1096
+
1097
+ **Article** - Blog posts, news articles, content:
1098
+
1099
+ ```ruby
1100
+ article = BetterSeo::StructuredData::Article.new
1101
+ article.headline("The Future of Web Development")
1102
+ article.description("An in-depth analysis of emerging trends")
1103
+ article.image("https://example.com/article-image.jpg")
1104
+ article.author("Jane Smith") # Or use Person object
1105
+ article.date_published("2024-01-15T09:00:00Z")
1106
+ article.date_modified("2024-01-20T14:30:00Z")
1107
+ article.url("https://example.com/articles/future-of-web-dev")
1108
+ article.word_count(2500)
1109
+ article.keywords(["Web Development", "Technology", "Trends"])
1110
+ article.article_section("Technology")
1111
+ ```
1112
+
1113
+ **Person** - Author profiles, team members:
1114
+
1115
+ ```ruby
1116
+ person = BetterSeo::StructuredData::Person.new
1117
+ person.name("Dr. Jane Smith")
1118
+ person.given_name("Jane")
1119
+ person.family_name("Smith")
1120
+ person.email("jane@example.com")
1121
+ person.url("https://janesmith.dev")
1122
+ person.image("https://janesmith.dev/profile.jpg")
1123
+ person.job_title("Chief Technology Officer")
1124
+ person.telephone("+1-555-0199")
1125
+ person.same_as([
1126
+ "https://twitter.com/janesmith",
1127
+ "https://linkedin.com/in/janesmith"
1128
+ ])
1129
+ ```
1130
+
1131
+ **Product** - E-commerce products:
1132
+
1133
+ ```ruby
1134
+ product = BetterSeo::StructuredData::Product.new
1135
+ product.name("Premium Wireless Headphones")
1136
+ product.description("High-quality wireless headphones with noise cancellation")
1137
+ product.image("https://example.com/headphones.jpg")
1138
+ product.brand("AudioTech")
1139
+ product.sku("HEADPHONES-WL-NC-2024")
1140
+ product.offers(
1141
+ price: 299.99,
1142
+ price_currency: "USD",
1143
+ availability: "InStock",
1144
+ url: "https://example.com/products/headphones"
1145
+ )
1146
+ product.aggregate_rating(
1147
+ rating_value: 4.7,
1148
+ review_count: 342
1149
+ )
1150
+ ```
1151
+
1152
+ **BreadcrumbList** - Navigation breadcrumbs:
1153
+
1154
+ ```ruby
1155
+ breadcrumb = BetterSeo::StructuredData::BreadcrumbList.new
1156
+ breadcrumb
1157
+ .add_item(name: "Home", url: "https://example.com")
1158
+ .add_item(name: "Electronics", url: "https://example.com/electronics")
1159
+ .add_item(name: "Headphones", url: "https://example.com/electronics/headphones")
1160
+ ```
1161
+
1162
+ #### Method Chaining
1163
+
1164
+ All structured data classes support fluent method chaining:
1165
+
1166
+ ```ruby
1167
+ org = BetterSeo::StructuredData::Organization.new
1168
+ .name("Acme Corp")
1169
+ .url("https://acme.com")
1170
+ .logo("https://acme.com/logo.png")
1171
+ .description("Innovation at its finest")
1172
+ ```
1173
+
1174
+ #### Nested Structured Data
1175
+
1176
+ Combine multiple structured data objects:
1177
+
1178
+ ```ruby
1179
+ # Create publisher organization
1180
+ publisher = BetterSeo::StructuredData::Organization.new
1181
+ publisher.name("Tech Publishing Co")
1182
+ publisher.logo("https://techpub.com/logo.png")
1183
+
1184
+ # Create author person
1185
+ author = BetterSeo::StructuredData::Person.new
1186
+ author.name("Jane Smith")
1187
+ author.email("jane@techpub.com")
1188
+ author.url("https://janesmith.dev")
1189
+
1190
+ # Create article with nested data
1191
+ article = BetterSeo::StructuredData::Article.new
1192
+ article.headline("Introduction to Ruby on Rails")
1193
+ article.description("A comprehensive guide for beginners")
1194
+ article.image("https://example.com/rails-guide.jpg")
1195
+ article.author(author) # Nested Person
1196
+ article.publisher(publisher) # Nested Organization
1197
+ article.date_published("2024-01-15")
1198
+
1199
+ # Generates nested JSON-LD automatically
1200
+ article.to_script_tag
1201
+ ```
1202
+
1203
+ #### Using the Generator Helper
1204
+
1205
+ The Generator class provides convenient factory methods:
1206
+
1207
+ ```ruby
1208
+ # Create with block
1209
+ org = BetterSeo::StructuredData::Generator.organization do |o|
1210
+ o.name("Acme Corp")
1211
+ o.url("https://acme.com")
1212
+ o.logo("https://acme.com/logo.png")
1213
+ end
1214
+
1215
+ article = BetterSeo::StructuredData::Generator.article do |a|
1216
+ a.headline("Amazing Article")
1217
+ a.author("John Doe")
1218
+ a.date_published("2024-01-15")
1219
+ end
1220
+
1221
+ person = BetterSeo::StructuredData::Generator.person do |p|
1222
+ p.name("John Doe")
1223
+ p.email("john@example.com")
1224
+ end
1225
+
1226
+ # Generate multiple script tags at once
1227
+ tags = BetterSeo::StructuredData::Generator.generate_script_tags([org, article, person])
1228
+ # Returns all three script tags joined with newlines
1229
+ ```
1230
+
1231
+ #### Rails Integration
1232
+
1233
+ Add structured data to your Rails views:
1234
+
1235
+ ```erb
1236
+ <%# app/views/articles/show.html.erb %>
1237
+ <%
1238
+ author = BetterSeo::StructuredData::Generator.person do |p|
1239
+ p.name(@article.author.name)
1240
+ p.email(@article.author.email)
1241
+ p.url(@article.author.website)
1242
+ end
1243
+
1244
+ article_sd = BetterSeo::StructuredData::Generator.article do |a|
1245
+ a.headline(@article.title)
1246
+ a.description(@article.excerpt)
1247
+ a.image(url_for(@article.cover_image))
1248
+ a.author(author)
1249
+ a.date_published(@article.published_at.iso8601)
1250
+ a.date_modified(@article.updated_at.iso8601)
1251
+ a.url(article_url(@article))
1252
+ a.word_count(@article.word_count)
1253
+ a.keywords(@article.tags.pluck(:name))
1254
+ end
1255
+ %>
1256
+
1257
+ <%== article_sd.to_script_tag %>
1258
+ ```
1259
+
1260
+ Or in a helper:
1261
+
1262
+ ```ruby
1263
+ # app/helpers/structured_data_helper.rb
1264
+ module StructuredDataHelper
1265
+ def article_structured_data(article)
1266
+ author = BetterSeo::StructuredData::Generator.person do |p|
1267
+ p.name(article.author.name)
1268
+ p.url(author_url(article.author))
1269
+ end
1270
+
1271
+ article_sd = BetterSeo::StructuredData::Generator.article do |a|
1272
+ a.headline(article.title)
1273
+ a.description(article.excerpt)
1274
+ a.author(author)
1275
+ a.date_published(article.published_at.iso8601)
1276
+ a.url(article_url(article))
1277
+ end
1278
+
1279
+ article_sd.to_script_tag.html_safe
1280
+ end
1281
+
1282
+ def organization_structured_data
1283
+ org = BetterSeo::StructuredData::Generator.organization do |o|
1284
+ o.name(Rails.application.config.site_name)
1285
+ o.url(root_url)
1286
+ o.logo(image_url('logo.png'))
1287
+ o.same_as([
1288
+ "https://twitter.com/yourcompany",
1289
+ "https://facebook.com/yourcompany"
1290
+ ])
1291
+ end
1292
+
1293
+ org.to_script_tag.html_safe
1294
+ end
1295
+ end
1296
+ ```
1297
+
1298
+ Then in your layout:
1299
+
1300
+ ```erb
1301
+ <%# app/views/layouts/application.html.erb %>
1302
+ <head>
1303
+ ...
1304
+ <%= organization_structured_data %>
1305
+ </head>
1306
+ ```
1307
+
1308
+ And in article views:
1309
+
1310
+ ```erb
1311
+ <%# app/views/articles/show.html.erb %>
1312
+ <%= article_structured_data(@article) %>
1313
+ ```
1314
+
1315
+ #### Complete Example
1316
+
1317
+ ```ruby
1318
+ # Create complete structured data for a blog article
1319
+ publisher = BetterSeo::StructuredData::Generator.organization do |o|
1320
+ o.name("Tech Blog Publishing")
1321
+ o.url("https://techblog.com")
1322
+ o.logo("https://techblog.com/logo.png")
1323
+ end
1324
+
1325
+ author = BetterSeo::StructuredData::Generator.person do |p|
1326
+ p.name("Dr. Sarah Johnson")
1327
+ p.email("sarah@techblog.com")
1328
+ p.url("https://sarahjohnson.dev")
1329
+ p.job_title("Senior Technology Writer")
1330
+ end
1331
+
1332
+ article = BetterSeo::StructuredData::Generator.article do |a|
1333
+ a.headline("The Complete Guide to Ruby on Rails in 2024")
1334
+ a.description("Everything you need to know about Rails")
1335
+ a.image([
1336
+ "https://techblog.com/images/rails-2024-1.jpg",
1337
+ "https://techblog.com/images/rails-2024-2.jpg"
1338
+ ])
1339
+ a.author(author)
1340
+ a.publisher(publisher)
1341
+ a.date_published("2024-01-15T09:00:00Z")
1342
+ a.date_modified("2024-01-20T15:30:00Z")
1343
+ a.url("https://techblog.com/rails-complete-guide-2024")
1344
+ a.word_count(3500)
1345
+ a.keywords(["Ruby on Rails", "Web Development", "2024"])
1346
+ a.article_section("Programming")
1347
+ end
1348
+
1349
+ # Get JSON-LD
1350
+ json_ld = article.to_json
1351
+
1352
+ # Get script tag for HTML
1353
+ script_tag = article.to_script_tag
1354
+
1355
+ # Or generate all at once
1356
+ all_tags = BetterSeo::StructuredData::Generator.generate_script_tags([
1357
+ publisher,
1358
+ author,
1359
+ article
1360
+ ])
1361
+ ```
1362
+
1363
+ #### Benefits
1364
+
1365
+ - **SEO Enhancement**: Help search engines understand your content better
1366
+ - **Rich Snippets**: Enable rich results in search results (ratings, images, etc.)
1367
+ - **Type Safety**: Fluent API with method chaining
1368
+ - **Nested Data**: Automatic handling of complex relationships
1369
+ - **Standards Compliant**: Follows Schema.org specifications
1370
+ - **Easy Integration**: Works seamlessly with Rails views and helpers
1371
+
1023
1372
  ## Configuration Reference
1024
1373
 
1025
1374
  ### Global Configuration
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BetterSeo
4
- VERSION = "0.5.0"
4
+ VERSION = "0.7.0"
5
5
  end
data/lib/better_seo.rb CHANGED
@@ -17,6 +17,13 @@ require_relative "better_seo/rails/helpers/seo_helper"
17
17
  require_relative "better_seo/sitemap/url_entry"
18
18
  require_relative "better_seo/sitemap/builder"
19
19
  require_relative "better_seo/sitemap/generator"
20
+ require_relative "better_seo/structured_data/base"
21
+ require_relative "better_seo/structured_data/organization"
22
+ require_relative "better_seo/structured_data/article"
23
+ require_relative "better_seo/structured_data/person"
24
+ require_relative "better_seo/structured_data/product"
25
+ require_relative "better_seo/structured_data/breadcrumb_list"
26
+ require_relative "better_seo/structured_data/generator"
20
27
 
21
28
  module BetterSeo
22
29
  class << self
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: better_seo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - alessiobussolari
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-22 00:00:00.000000000 Z
11
+ date: 2025-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport