better_seo 0.7.0 → 0.9.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 +4 -4
- data/CHANGELOG.md +88 -0
- data/README.md +186 -17
- data/lib/better_seo/version.rb +1 -1
- data/lib/better_seo.rb +7 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 02c10b033ffd80fd718852f24434af741e4804e8353b792dfa37bdb70ea1583c
|
|
4
|
+
data.tar.gz: cec2c0bd8391ec44eeffeedaf9f64c35c2070e575f9addb999e4f04034da561e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d03af8f52407d32434526df94a5b871dc797a28cb6352d52acf850b5b4626b30db22bb35641858801f7d25ae07614ac94913718558c1486d89a69caecc295966
|
|
7
|
+
data.tar.gz: 003afa3422b02cfb5f043b92799b67ab099304f95fe99e80469226dae9c67dfcfb1f1835692462a203b4c3b8fbf4db5ed092866c333d7ddf8abaaf2247e6b644
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,94 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.0] - 2025-01-23
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Five additional Structured Data types for comprehensive SEO coverage
|
|
14
|
+
- `StructuredData::LocalBusiness` - Physical business locations
|
|
15
|
+
- Complete address with PostalAddress schema
|
|
16
|
+
- Geographic coordinates with GeoCoordinates
|
|
17
|
+
- Opening hours (string and structured specification)
|
|
18
|
+
- Price range and cuisine information
|
|
19
|
+
- Aggregate ratings for customer reviews
|
|
20
|
+
- `StructuredData::Event` - Conferences, webinars, and events
|
|
21
|
+
- Event dates with Date/Time/DateTime support
|
|
22
|
+
- Event status (EventScheduled, EventCancelled, EventPostponed, EventRescheduled)
|
|
23
|
+
- Event attendance mode (Offline, Online, Mixed)
|
|
24
|
+
- Physical and virtual locations with Place/VirtualLocation
|
|
25
|
+
- Organizer (Organization or Person)
|
|
26
|
+
- Multiple ticket offers with pricing and availability
|
|
27
|
+
- Performer support (single or multiple)
|
|
28
|
+
- `StructuredData::FAQPage` - Structured FAQ pages
|
|
29
|
+
- Add single or multiple questions
|
|
30
|
+
- Automatic Question/Answer schema formatting
|
|
31
|
+
- Clear method to reset questions
|
|
32
|
+
- Rich snippets support in search results
|
|
33
|
+
- `StructuredData::HowTo` - Step-by-step guides
|
|
34
|
+
- Named steps with descriptions
|
|
35
|
+
- Automatic position numbering
|
|
36
|
+
- Supply and tool lists
|
|
37
|
+
- Total time estimation
|
|
38
|
+
- Step images and URLs
|
|
39
|
+
- `StructuredData::Recipe` - Cooking recipes
|
|
40
|
+
- Ingredients list management
|
|
41
|
+
- Step-by-step instructions with HowToStep format
|
|
42
|
+
- Prep time, cook time, total time
|
|
43
|
+
- Recipe yield, category, cuisine
|
|
44
|
+
- Nutrition information with NutritionInformation schema
|
|
45
|
+
- Aggregate ratings
|
|
46
|
+
- Keywords support
|
|
47
|
+
- Generator helper methods for all new types
|
|
48
|
+
- `Generator.local_business` with block support
|
|
49
|
+
- `Generator.event` with block support
|
|
50
|
+
- `Generator.faq_page` with block support
|
|
51
|
+
- `Generator.how_to` with block support
|
|
52
|
+
- `Generator.recipe` with block support
|
|
53
|
+
- Rails view helpers for all new types
|
|
54
|
+
- `local_business_sd(**properties, &block)`
|
|
55
|
+
- `event_sd(**properties, &block)`
|
|
56
|
+
- `faq_page_sd(questions:, &block)` - with array support
|
|
57
|
+
- `how_to_sd(steps:, &block)` - with array support
|
|
58
|
+
- `recipe_sd(ingredients:, instructions:, &block)` - with array support
|
|
59
|
+
- Enhanced TYPE_MAPPING in StructuredDataHelper with all 10 types
|
|
60
|
+
|
|
61
|
+
### Test Coverage
|
|
62
|
+
- 669 tests passing (+117 from v0.8.0)
|
|
63
|
+
- 95.79% code coverage (1205/1258 lines)
|
|
64
|
+
- 117 new tests across 5 structured data types:
|
|
65
|
+
- LocalBusiness: 25 tests
|
|
66
|
+
- Event: 36 tests
|
|
67
|
+
- FAQPage: 11 tests
|
|
68
|
+
- HowTo: 18 tests
|
|
69
|
+
- Recipe: 27 tests
|
|
70
|
+
|
|
71
|
+
## [0.8.0] - 2025-01-23
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
- Rails Structured Data View Helpers for easy integration
|
|
75
|
+
- `structured_data_tag(type, **properties, &block)` - Generic helper with type symbol or object
|
|
76
|
+
- `organization_sd(**properties, &block)` - Organization structured data helper
|
|
77
|
+
- `article_sd(**properties, &block)` - Article structured data helper
|
|
78
|
+
- `person_sd(**properties, &block)` - Person structured data helper
|
|
79
|
+
- `product_sd(**properties, &block)` - Product structured data helper
|
|
80
|
+
- `breadcrumb_list_sd(items:, &block)` - Breadcrumb list structured data helper
|
|
81
|
+
- `structured_data_tags(array)` - Multiple structured data tags generation
|
|
82
|
+
- Helper features
|
|
83
|
+
- Support for both hash configuration and block-based DSL
|
|
84
|
+
- Type mapping with symbol-based factory methods
|
|
85
|
+
- Automatic HTML safety with `raw` method
|
|
86
|
+
- Pass existing structured data objects or create on-the-fly
|
|
87
|
+
- Seamless integration with Rails views and layouts
|
|
88
|
+
- Complete Rails integration examples
|
|
89
|
+
- Product page with breadcrumbs and structured data
|
|
90
|
+
- Helper method reference table
|
|
91
|
+
- Type-specific helper examples
|
|
92
|
+
|
|
93
|
+
### Test Coverage
|
|
94
|
+
- 552 tests passing (+22 from v0.7.0)
|
|
95
|
+
- 98.83% code coverage (931/942 lines)
|
|
96
|
+
- 22 new tests for StructuredDataHelper
|
|
97
|
+
|
|
10
98
|
## [0.7.0] - 2025-01-23
|
|
11
99
|
|
|
12
100
|
### 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
|
-
[](https://github.com/yourusername/better_seo)
|
|
6
|
+
[](https://github.com/yourusername/better_seo)
|
|
7
7
|
[](https://www.ruby-lang.org)
|
|
8
8
|
[](https://rubyonrails.org)
|
|
9
9
|
|
|
10
10
|
## Features
|
|
11
11
|
|
|
12
|
-
### ✅ Implemented (v0.
|
|
12
|
+
### ✅ Implemented (v0.9.0)
|
|
13
13
|
|
|
14
14
|
- **Core Configuration System**
|
|
15
15
|
- Singleton configuration with block-style setup
|
|
@@ -33,7 +33,8 @@ A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a cl
|
|
|
33
33
|
- Integration with DSL builders
|
|
34
34
|
|
|
35
35
|
- **Rails Integration**
|
|
36
|
-
- **View Helpers**: `seo_meta_tags`, `seo_open_graph_tags`, `seo_twitter_tags`, `seo_tags`
|
|
36
|
+
- **SEO View Helpers**: `seo_meta_tags`, `seo_open_graph_tags`, `seo_twitter_tags`, `seo_tags`
|
|
37
|
+
- **Structured Data Helpers**: `structured_data_tag`, `organization_sd`, `article_sd`, `person_sd`, `product_sd`, `breadcrumb_list_sd`, `local_business_sd`, `event_sd`, `faq_page_sd`, `how_to_sd`, `recipe_sd`
|
|
37
38
|
- Support for hash configuration and DSL blocks
|
|
38
39
|
- Automatic HTML safety with `raw` helper
|
|
39
40
|
- Integration with global configuration defaults
|
|
@@ -48,27 +49,25 @@ A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a cl
|
|
|
48
49
|
- **Validation**: Automatic URL validation (format, protocol)
|
|
49
50
|
- **Method Chaining**: Fluent interface for adding multiple URLs
|
|
50
51
|
|
|
51
|
-
- **Structured Data (JSON-LD)**
|
|
52
|
+
- **Structured Data (JSON-LD)** - 10 comprehensive types
|
|
52
53
|
- **Base Class**: Generic structured data with full Schema.org support
|
|
53
54
|
- **Organization**: Company/organization information with address, social profiles
|
|
54
55
|
- **Article**: Blog posts, news articles with author, publisher, metadata
|
|
55
56
|
- **Person**: Author profiles, team members with job title, social links
|
|
56
57
|
- **Product**: E-commerce products with price, availability, ratings, reviews
|
|
57
58
|
- **BreadcrumbList**: Navigation breadcrumbs for improved site structure
|
|
58
|
-
- **
|
|
59
|
+
- **LocalBusiness**: Physical locations with address, hours, geo coordinates, ratings
|
|
60
|
+
- **Event**: Conferences, webinars with dates, location, tickets, performers
|
|
61
|
+
- **FAQPage**: Structured FAQ with questions/answers for rich snippets
|
|
62
|
+
- **HowTo**: Step-by-step guides with supplies, tools, and instructions
|
|
63
|
+
- **Recipe**: Cooking recipes with ingredients, nutrition, cooking time
|
|
64
|
+
- **Generator Helper**: Factory methods for all types with block support
|
|
59
65
|
- **Nested Data**: Automatic handling of complex object relationships
|
|
60
66
|
- **JSON-LD Output**: Valid Schema.org JSON-LD format
|
|
61
|
-
- **Rails Integration**:
|
|
67
|
+
- **Rails Integration**: Complete view helpers for all types
|
|
62
68
|
|
|
63
69
|
### 🚧 Planned
|
|
64
70
|
|
|
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
71
|
- **Advanced Generators** (v0.7.0)
|
|
73
72
|
- Breadcrumbs HTML generator
|
|
74
73
|
- AMP HTML generator
|
|
@@ -1312,6 +1311,174 @@ And in article views:
|
|
|
1312
1311
|
<%= article_structured_data(@article) %>
|
|
1313
1312
|
```
|
|
1314
1313
|
|
|
1314
|
+
#### Rails View Helpers (v0.8.0)
|
|
1315
|
+
|
|
1316
|
+
BetterSeo includes built-in Rails view helpers for easy structured data integration:
|
|
1317
|
+
|
|
1318
|
+
**Generic Helper - `structured_data_tag`**
|
|
1319
|
+
|
|
1320
|
+
```erb
|
|
1321
|
+
<%# Create from type symbol with hash %>
|
|
1322
|
+
<%= structured_data_tag(:organization,
|
|
1323
|
+
name: "Acme Corp",
|
|
1324
|
+
url: "https://acme.com",
|
|
1325
|
+
logo: "https://acme.com/logo.png"
|
|
1326
|
+
) %>
|
|
1327
|
+
|
|
1328
|
+
<%# Create from type symbol with block %>
|
|
1329
|
+
<%= structured_data_tag(:article) do |article|
|
|
1330
|
+
article.headline("My Article")
|
|
1331
|
+
article.author("John Doe")
|
|
1332
|
+
article.date_published("2024-01-15")
|
|
1333
|
+
end %>
|
|
1334
|
+
|
|
1335
|
+
<%# Pass an existing object %>
|
|
1336
|
+
<% org = BetterSeo::StructuredData::Organization.new(name: "Acme") %>
|
|
1337
|
+
<%= structured_data_tag(org) %>
|
|
1338
|
+
```
|
|
1339
|
+
|
|
1340
|
+
**Type-Specific Helpers**
|
|
1341
|
+
|
|
1342
|
+
Convenience methods for each structured data type:
|
|
1343
|
+
|
|
1344
|
+
```erb
|
|
1345
|
+
<%# Organization %>
|
|
1346
|
+
<%= organization_sd(
|
|
1347
|
+
name: "Acme Corp",
|
|
1348
|
+
url: "https://acme.com"
|
|
1349
|
+
) %>
|
|
1350
|
+
|
|
1351
|
+
<%# Or with block %>
|
|
1352
|
+
<%= organization_sd do |org|
|
|
1353
|
+
org.name("Acme Corp")
|
|
1354
|
+
org.url("https://acme.com")
|
|
1355
|
+
org.logo("https://acme.com/logo.png")
|
|
1356
|
+
end %>
|
|
1357
|
+
|
|
1358
|
+
<%# Article %>
|
|
1359
|
+
<%= article_sd(
|
|
1360
|
+
headline: @article.title,
|
|
1361
|
+
author: @article.author.name,
|
|
1362
|
+
date_published: @article.published_at.iso8601
|
|
1363
|
+
) %>
|
|
1364
|
+
|
|
1365
|
+
<%# Person %>
|
|
1366
|
+
<%= person_sd do |person|
|
|
1367
|
+
person.name("John Doe")
|
|
1368
|
+
person.email("john@example.com")
|
|
1369
|
+
person.job_title("Software Engineer")
|
|
1370
|
+
end %>
|
|
1371
|
+
|
|
1372
|
+
<%# Product %>
|
|
1373
|
+
<%= product_sd do |product|
|
|
1374
|
+
product.name(@product.name)
|
|
1375
|
+
product.brand(@product.brand)
|
|
1376
|
+
product.offers(
|
|
1377
|
+
price: @product.price,
|
|
1378
|
+
price_currency: "USD",
|
|
1379
|
+
availability: "InStock"
|
|
1380
|
+
)
|
|
1381
|
+
product.aggregate_rating(
|
|
1382
|
+
rating_value: @product.average_rating,
|
|
1383
|
+
review_count: @product.reviews_count
|
|
1384
|
+
)
|
|
1385
|
+
end %>
|
|
1386
|
+
|
|
1387
|
+
<%# Breadcrumb List %>
|
|
1388
|
+
<%= breadcrumb_list_sd do |breadcrumb|
|
|
1389
|
+
breadcrumb.add_item(name: "Home", url: root_url)
|
|
1390
|
+
breadcrumb.add_item(name: "Products", url: products_url)
|
|
1391
|
+
breadcrumb.add_item(name: @product.name, url: product_url(@product))
|
|
1392
|
+
end %>
|
|
1393
|
+
|
|
1394
|
+
<%# Or from array %>
|
|
1395
|
+
<% items = [
|
|
1396
|
+
{ name: "Home", url: root_url },
|
|
1397
|
+
{ name: "Products", url: products_url }
|
|
1398
|
+
] %>
|
|
1399
|
+
<%= breadcrumb_list_sd(items: items) %>
|
|
1400
|
+
```
|
|
1401
|
+
|
|
1402
|
+
**Multiple Tags Helper - `structured_data_tags`**
|
|
1403
|
+
|
|
1404
|
+
Generate multiple script tags at once:
|
|
1405
|
+
|
|
1406
|
+
```erb
|
|
1407
|
+
<% org = BetterSeo::StructuredData::Organization.new(name: "Acme") %>
|
|
1408
|
+
<% person = BetterSeo::StructuredData::Person.new(name: "John") %>
|
|
1409
|
+
<% article = BetterSeo::StructuredData::Article.new(headline: "Title") %>
|
|
1410
|
+
|
|
1411
|
+
<%= structured_data_tags([org, person, article]) %>
|
|
1412
|
+
```
|
|
1413
|
+
|
|
1414
|
+
**Complete Rails Example**
|
|
1415
|
+
|
|
1416
|
+
```erb
|
|
1417
|
+
<%# app/views/products/show.html.erb %>
|
|
1418
|
+
<head>
|
|
1419
|
+
<%# Page SEO tags %>
|
|
1420
|
+
<%= seo_tags do |seo|
|
|
1421
|
+
seo.meta do |meta|
|
|
1422
|
+
meta.title @product.name
|
|
1423
|
+
meta.description @product.description
|
|
1424
|
+
end
|
|
1425
|
+
seo.og do |og|
|
|
1426
|
+
og.type "product"
|
|
1427
|
+
og.title @product.name
|
|
1428
|
+
og.image @product.image_url
|
|
1429
|
+
end
|
|
1430
|
+
end %>
|
|
1431
|
+
|
|
1432
|
+
<%# Structured data %>
|
|
1433
|
+
<%= organization_sd do |org|
|
|
1434
|
+
org.name("My Shop")
|
|
1435
|
+
org.url(root_url)
|
|
1436
|
+
end %>
|
|
1437
|
+
|
|
1438
|
+
<%= breadcrumb_list_sd do |bc|
|
|
1439
|
+
bc.add_item(name: "Home", url: root_url)
|
|
1440
|
+
bc.add_item(name: "Products", url: products_url)
|
|
1441
|
+
bc.add_item(name: @product.category, url: category_url(@product.category))
|
|
1442
|
+
bc.add_item(name: @product.name, url: product_url(@product))
|
|
1443
|
+
end %>
|
|
1444
|
+
|
|
1445
|
+
<%= product_sd do |product|
|
|
1446
|
+
product.name(@product.name)
|
|
1447
|
+
product.description(@product.description)
|
|
1448
|
+
product.image(@product.image_url)
|
|
1449
|
+
product.brand(@product.brand)
|
|
1450
|
+
product.sku(@product.sku)
|
|
1451
|
+
product.offers(
|
|
1452
|
+
price: @product.price,
|
|
1453
|
+
price_currency: "USD",
|
|
1454
|
+
availability: @product.in_stock? ? "InStock" : "OutOfStock",
|
|
1455
|
+
url: product_url(@product)
|
|
1456
|
+
)
|
|
1457
|
+
if @product.reviews.any?
|
|
1458
|
+
product.aggregate_rating(
|
|
1459
|
+
rating_value: @product.average_rating,
|
|
1460
|
+
review_count: @product.reviews_count,
|
|
1461
|
+
best_rating: 5
|
|
1462
|
+
)
|
|
1463
|
+
end
|
|
1464
|
+
end %>
|
|
1465
|
+
</head>
|
|
1466
|
+
```
|
|
1467
|
+
|
|
1468
|
+
**Helper Method Reference**
|
|
1469
|
+
|
|
1470
|
+
| Helper | Description |
|
|
1471
|
+
|--------|-------------|
|
|
1472
|
+
| `structured_data_tag(type, **props, &block)` | Generic helper for any type |
|
|
1473
|
+
| `organization_sd(**props, &block)` | Organization structured data |
|
|
1474
|
+
| `article_sd(**props, &block)` | Article structured data |
|
|
1475
|
+
| `person_sd(**props, &block)` | Person structured data |
|
|
1476
|
+
| `product_sd(**props, &block)` | Product structured data |
|
|
1477
|
+
| `breadcrumb_list_sd(items:, &block)` | Breadcrumb list structured data |
|
|
1478
|
+
| `structured_data_tags(array)` | Multiple structured data tags |
|
|
1479
|
+
|
|
1480
|
+
All helpers support both hash configuration and block-based DSL for maximum flexibility.
|
|
1481
|
+
|
|
1315
1482
|
#### Complete Example
|
|
1316
1483
|
|
|
1317
1484
|
```ruby
|
|
@@ -1478,11 +1645,13 @@ bundle exec rspec --format documentation
|
|
|
1478
1645
|
```
|
|
1479
1646
|
|
|
1480
1647
|
Current test statistics:
|
|
1481
|
-
- **
|
|
1482
|
-
- **
|
|
1648
|
+
- **669 tests** passing
|
|
1649
|
+
- **95.79% code coverage** (1205/1258 lines)
|
|
1483
1650
|
- **3 DSL builders** fully tested
|
|
1484
1651
|
- **3 HTML generators** fully tested
|
|
1485
|
-
- **
|
|
1652
|
+
- **2 Rails view helper modules** fully tested
|
|
1653
|
+
- **10 Structured data types** fully tested
|
|
1654
|
+
- **1 Sitemap generation system** fully tested
|
|
1486
1655
|
- **1 core configuration system** fully tested
|
|
1487
1656
|
|
|
1488
1657
|
## Architecture
|
data/lib/better_seo/version.rb
CHANGED
data/lib/better_seo.rb
CHANGED
|
@@ -13,7 +13,6 @@ require_relative "better_seo/dsl/twitter_cards"
|
|
|
13
13
|
require_relative "better_seo/generators/meta_tags_generator"
|
|
14
14
|
require_relative "better_seo/generators/open_graph_generator"
|
|
15
15
|
require_relative "better_seo/generators/twitter_cards_generator"
|
|
16
|
-
require_relative "better_seo/rails/helpers/seo_helper"
|
|
17
16
|
require_relative "better_seo/sitemap/url_entry"
|
|
18
17
|
require_relative "better_seo/sitemap/builder"
|
|
19
18
|
require_relative "better_seo/sitemap/generator"
|
|
@@ -23,7 +22,14 @@ require_relative "better_seo/structured_data/article"
|
|
|
23
22
|
require_relative "better_seo/structured_data/person"
|
|
24
23
|
require_relative "better_seo/structured_data/product"
|
|
25
24
|
require_relative "better_seo/structured_data/breadcrumb_list"
|
|
25
|
+
require_relative "better_seo/structured_data/local_business"
|
|
26
|
+
require_relative "better_seo/structured_data/event"
|
|
27
|
+
require_relative "better_seo/structured_data/faq_page"
|
|
28
|
+
require_relative "better_seo/structured_data/how_to"
|
|
29
|
+
require_relative "better_seo/structured_data/recipe"
|
|
26
30
|
require_relative "better_seo/structured_data/generator"
|
|
31
|
+
require_relative "better_seo/rails/helpers/seo_helper"
|
|
32
|
+
require_relative "better_seo/rails/helpers/structured_data_helper"
|
|
27
33
|
|
|
28
34
|
module BetterSeo
|
|
29
35
|
class << self
|