better_seo 0.11.0 → 0.12.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 +51 -0
- data/README.md +272 -11
- data/lib/better_seo/version.rb +1 -1
- data/lib/better_seo.rb +3 -0
- 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: bbb87756b71cdc491faaba16bd349149051ef870ac1eea6dab55c31db3e09bd9
|
|
4
|
+
data.tar.gz: b34bc18d112710290991d430ff5525b920dadc25938aed97a6e20a3309118d45
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ca7e8d51f6c035725975a2326908156c0e6c5281d4ded7a10fd709775e4aa44208a5a609589fbbaf66c62ef0f54ab4f024b5a685001ab472cb2d1e0bb24097a2
|
|
7
|
+
data.tar.gz: b353b67665a36f045d2db900d3285996d021ec19db9b5ac7c1fd697ecfa5c4082fc895a3517190f70c79ae7f4f78d9290ab0f79034c3ecdc2da6ad490df20436
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,57 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.12.0] - 2025-01-23
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Advanced HTML Generators for modern web applications
|
|
14
|
+
- **BreadcrumbsGenerator** (`BetterSeo::Generators::BreadcrumbsGenerator`)
|
|
15
|
+
- `add_item(name, url)` - Add single breadcrumb item
|
|
16
|
+
- `add_items(array)` - Add multiple items at once
|
|
17
|
+
- `clear` - Remove all items
|
|
18
|
+
- `to_html(schema:, nav_class:, list_class:)` - Generate HTML breadcrumbs
|
|
19
|
+
- `to_json_ld` - Generate JSON-LD structured data
|
|
20
|
+
- `to_script_tag` - Generate script tag with JSON-LD
|
|
21
|
+
- Schema.org microdata support with `schema: true` option
|
|
22
|
+
- Custom CSS classes for nav and list elements
|
|
23
|
+
- Automatic position numbering for structured data
|
|
24
|
+
- Current page support (items without URLs)
|
|
25
|
+
- HTML entity escaping for security
|
|
26
|
+
- **AMP Generator** (`BetterSeo::Generators::AmpGenerator`)
|
|
27
|
+
- `to_boilerplate` - Generate required AMP boilerplate CSS
|
|
28
|
+
- `to_amp_script_tag` - Generate AMP runtime script tag
|
|
29
|
+
- `to_meta_tags` - Generate canonical and OG meta tags
|
|
30
|
+
- `to_structured_data` - Generate JSON-LD script tag
|
|
31
|
+
- `to_custom_css(css)` - Wrap custom CSS in amp-custom style tag
|
|
32
|
+
- Support for canonical URL, title, description, image
|
|
33
|
+
- Structured data integration for AMP pages
|
|
34
|
+
- Complete AMP HTML page support
|
|
35
|
+
- **Canonical URL Manager** (`BetterSeo::Generators::CanonicalUrlManager`)
|
|
36
|
+
- `to_html` - Generate canonical link HTML tag
|
|
37
|
+
- `to_http_header` - Generate Link HTTP header
|
|
38
|
+
- `validate!` - Validate canonical URL format and structure
|
|
39
|
+
- URL normalization features:
|
|
40
|
+
- Remove trailing slashes (preserves root URL)
|
|
41
|
+
- Remove fragment identifiers automatically
|
|
42
|
+
- Optional query parameter removal
|
|
43
|
+
- Optional URL lowercasing
|
|
44
|
+
- Validation for absolute URLs only
|
|
45
|
+
- HTTP/HTTPS protocol validation
|
|
46
|
+
- HTML entity escaping
|
|
47
|
+
|
|
48
|
+
### Enhanced
|
|
49
|
+
- HTML Generators section in README with comprehensive examples
|
|
50
|
+
- Documentation for all three new generators
|
|
51
|
+
- Rails integration examples for each generator
|
|
52
|
+
|
|
53
|
+
### Test Coverage
|
|
54
|
+
- 811 tests passing (+69 from v0.11.0)
|
|
55
|
+
- 96.41% code coverage (1506/1562 lines)
|
|
56
|
+
- 69 new tests across advanced generators:
|
|
57
|
+
- BreadcrumbsGenerator: 21 tests
|
|
58
|
+
- AMP Generator: 22 tests
|
|
59
|
+
- Canonical URL Manager: 26 tests
|
|
60
|
+
|
|
10
61
|
## [0.11.0] - 2025-01-23
|
|
11
62
|
|
|
12
63
|
### 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.12.0)
|
|
13
13
|
|
|
14
14
|
- **Core Configuration System**
|
|
15
15
|
- Singleton configuration with block-style setup
|
|
@@ -25,10 +25,13 @@ A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a cl
|
|
|
25
25
|
- Fluent interface with method chaining
|
|
26
26
|
- Automatic validation (title/description length, required fields)
|
|
27
27
|
|
|
28
|
-
- **HTML Generators**
|
|
28
|
+
- **HTML Generators** - Advanced generators for modern web
|
|
29
29
|
- **MetaTagsGenerator**: Converts DSL to HTML meta tags
|
|
30
30
|
- **OpenGraphGenerator**: Converts DSL to Open Graph meta tags
|
|
31
31
|
- **TwitterCardsGenerator**: Converts DSL to Twitter Card meta tags
|
|
32
|
+
- **BreadcrumbsGenerator**: HTML breadcrumb navigation with Schema.org support
|
|
33
|
+
- **AMP Generator**: Accelerated Mobile Pages (AMP) support
|
|
34
|
+
- **Canonical URL Manager**: Canonical URL normalization and management
|
|
32
35
|
- HTML entity escaping for security
|
|
33
36
|
- Integration with DSL builders
|
|
34
37
|
|
|
@@ -76,16 +79,11 @@ A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a cl
|
|
|
76
79
|
|
|
77
80
|
### 🚧 Planned
|
|
78
81
|
|
|
79
|
-
- **Advanced
|
|
80
|
-
- Breadcrumbs HTML generator
|
|
81
|
-
- AMP HTML generator
|
|
82
|
-
- Canonical URL management
|
|
83
|
-
|
|
84
|
-
- **Advanced Features** (v0.6.0+)
|
|
82
|
+
- **Advanced Features** (v0.13.0+)
|
|
85
83
|
- robots.txt generator
|
|
86
84
|
- Image optimization with WebP conversion
|
|
87
|
-
- Structured data builders (Organization, Person, Product, etc.)
|
|
88
85
|
- SEO validators and recommendations
|
|
86
|
+
- Performance monitoring and analytics integration
|
|
89
87
|
|
|
90
88
|
## Installation
|
|
91
89
|
|
|
@@ -1532,6 +1530,269 @@ all_tags = BetterSeo::StructuredData::Generator.generate_script_tags([
|
|
|
1532
1530
|
- **Standards Compliant**: Follows Schema.org specifications
|
|
1533
1531
|
- **Easy Integration**: Works seamlessly with Rails views and helpers
|
|
1534
1532
|
|
|
1533
|
+
---
|
|
1534
|
+
|
|
1535
|
+
## Advanced Generators
|
|
1536
|
+
|
|
1537
|
+
### Breadcrumbs Generator
|
|
1538
|
+
|
|
1539
|
+
Generate HTML breadcrumb navigation with Schema.org structured data support.
|
|
1540
|
+
|
|
1541
|
+
#### Basic Usage
|
|
1542
|
+
|
|
1543
|
+
```ruby
|
|
1544
|
+
generator = BetterSeo::Generators::BreadcrumbsGenerator.new
|
|
1545
|
+
generator.add_item("Home", "/")
|
|
1546
|
+
generator.add_item("Products", "/products")
|
|
1547
|
+
generator.add_item("Laptops", "/products/laptops")
|
|
1548
|
+
generator.add_item("MacBook Pro", nil) # Current page (no link)
|
|
1549
|
+
|
|
1550
|
+
# Generate HTML breadcrumbs
|
|
1551
|
+
html = generator.to_html
|
|
1552
|
+
# <nav class="breadcrumb" aria-label="breadcrumb">
|
|
1553
|
+
# <ol class="breadcrumb">
|
|
1554
|
+
# <li class="breadcrumb-item">
|
|
1555
|
+
# <a href="/">Home</a>
|
|
1556
|
+
# </li>
|
|
1557
|
+
# ...
|
|
1558
|
+
# </ol>
|
|
1559
|
+
# </nav>
|
|
1560
|
+
|
|
1561
|
+
# Generate JSON-LD structured data
|
|
1562
|
+
json_ld = generator.to_json_ld
|
|
1563
|
+
script_tag = generator.to_script_tag
|
|
1564
|
+
```
|
|
1565
|
+
|
|
1566
|
+
#### With Schema.org Markup
|
|
1567
|
+
|
|
1568
|
+
```ruby
|
|
1569
|
+
# Generate breadcrumbs with microdata
|
|
1570
|
+
html = generator.to_html(schema: true)
|
|
1571
|
+
# Includes itemscope, itemtype, itemprop attributes for rich snippets
|
|
1572
|
+
```
|
|
1573
|
+
|
|
1574
|
+
#### Custom Styling
|
|
1575
|
+
|
|
1576
|
+
```ruby
|
|
1577
|
+
html = generator.to_html(
|
|
1578
|
+
nav_class: "my-breadcrumb-nav",
|
|
1579
|
+
list_class: "my-breadcrumb-list"
|
|
1580
|
+
)
|
|
1581
|
+
```
|
|
1582
|
+
|
|
1583
|
+
#### Rails Integration
|
|
1584
|
+
|
|
1585
|
+
```erb
|
|
1586
|
+
<!-- app/views/layouts/application.html.erb -->
|
|
1587
|
+
<%
|
|
1588
|
+
breadcrumbs = BetterSeo::Generators::BreadcrumbsGenerator.new
|
|
1589
|
+
breadcrumbs.add_item("Home", root_path)
|
|
1590
|
+
breadcrumbs.add_item("Blog", blog_path)
|
|
1591
|
+
breadcrumbs.add_item(@post.title, nil)
|
|
1592
|
+
%>
|
|
1593
|
+
|
|
1594
|
+
<%= raw breadcrumbs.to_html(schema: true) %>
|
|
1595
|
+
<%= raw breadcrumbs.to_script_tag %>
|
|
1596
|
+
```
|
|
1597
|
+
|
|
1598
|
+
#### Multiple Items at Once
|
|
1599
|
+
|
|
1600
|
+
```ruby
|
|
1601
|
+
generator.add_items([
|
|
1602
|
+
{ name: "Home", url: "/" },
|
|
1603
|
+
{ name: "Products", url: "/products" },
|
|
1604
|
+
{ name: "Laptops", url: "/products/laptops" }
|
|
1605
|
+
])
|
|
1606
|
+
```
|
|
1607
|
+
|
|
1608
|
+
---
|
|
1609
|
+
|
|
1610
|
+
### AMP Generator
|
|
1611
|
+
|
|
1612
|
+
Generate Accelerated Mobile Pages (AMP) HTML components.
|
|
1613
|
+
|
|
1614
|
+
#### Basic Usage
|
|
1615
|
+
|
|
1616
|
+
```ruby
|
|
1617
|
+
amp = BetterSeo::Generators::AmpGenerator.new(
|
|
1618
|
+
canonical_url: "https://example.com/article",
|
|
1619
|
+
title: "My Article Title",
|
|
1620
|
+
description: "Article description",
|
|
1621
|
+
image: "https://example.com/image.jpg"
|
|
1622
|
+
)
|
|
1623
|
+
|
|
1624
|
+
# AMP boilerplate CSS
|
|
1625
|
+
boilerplate = amp.to_boilerplate
|
|
1626
|
+
|
|
1627
|
+
# AMP runtime script
|
|
1628
|
+
amp_script = amp.to_amp_script_tag
|
|
1629
|
+
# <script async src="https://cdn.ampproject.org/v0.js"></script>
|
|
1630
|
+
|
|
1631
|
+
# Meta tags
|
|
1632
|
+
meta_tags = amp.to_meta_tags
|
|
1633
|
+
# Includes canonical, og:title, og:description, og:image
|
|
1634
|
+
```
|
|
1635
|
+
|
|
1636
|
+
#### Complete AMP Page
|
|
1637
|
+
|
|
1638
|
+
```erb
|
|
1639
|
+
<!doctype html>
|
|
1640
|
+
<html ⚡>
|
|
1641
|
+
<head>
|
|
1642
|
+
<meta charset="utf-8">
|
|
1643
|
+
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
|
|
1644
|
+
|
|
1645
|
+
<%= raw amp.to_meta_tags %>
|
|
1646
|
+
<%= raw amp.to_amp_script_tag %>
|
|
1647
|
+
<%= raw amp.to_boilerplate %>
|
|
1648
|
+
|
|
1649
|
+
<% custom_css = "body { font-family: Arial; } h1 { color: #333; }" %>
|
|
1650
|
+
<%= raw amp.to_custom_css(custom_css) %>
|
|
1651
|
+
</head>
|
|
1652
|
+
<body>
|
|
1653
|
+
<!-- Your AMP content -->
|
|
1654
|
+
</body>
|
|
1655
|
+
</html>
|
|
1656
|
+
```
|
|
1657
|
+
|
|
1658
|
+
#### With Structured Data
|
|
1659
|
+
|
|
1660
|
+
```ruby
|
|
1661
|
+
article_data = {
|
|
1662
|
+
"@context" => "https://schema.org",
|
|
1663
|
+
"@type" => "Article",
|
|
1664
|
+
"headline" => "My Article",
|
|
1665
|
+
"author" => { "@type" => "Person", "name" => "John Doe" }
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
amp.structured_data = article_data
|
|
1669
|
+
script = amp.to_structured_data
|
|
1670
|
+
# <script type="application/ld+json">
|
|
1671
|
+
# { "@context": "https://schema.org", "@type": "Article", ... }
|
|
1672
|
+
# </script>
|
|
1673
|
+
```
|
|
1674
|
+
|
|
1675
|
+
#### Rails Controller Integration
|
|
1676
|
+
|
|
1677
|
+
```ruby
|
|
1678
|
+
class ArticlesController < ApplicationController
|
|
1679
|
+
def amp
|
|
1680
|
+
@article = Article.find(params[:id])
|
|
1681
|
+
|
|
1682
|
+
@amp = BetterSeo::Generators::AmpGenerator.new(
|
|
1683
|
+
canonical_url: article_url(@article),
|
|
1684
|
+
title: @article.title,
|
|
1685
|
+
description: @article.excerpt,
|
|
1686
|
+
image: @article.featured_image_url
|
|
1687
|
+
)
|
|
1688
|
+
|
|
1689
|
+
render layout: 'amp'
|
|
1690
|
+
end
|
|
1691
|
+
end
|
|
1692
|
+
```
|
|
1693
|
+
|
|
1694
|
+
---
|
|
1695
|
+
|
|
1696
|
+
### Canonical URL Manager
|
|
1697
|
+
|
|
1698
|
+
Manage and normalize canonical URLs with validation.
|
|
1699
|
+
|
|
1700
|
+
#### Basic Usage
|
|
1701
|
+
|
|
1702
|
+
```ruby
|
|
1703
|
+
manager = BetterSeo::Generators::CanonicalUrlManager.new("https://example.com/page")
|
|
1704
|
+
|
|
1705
|
+
# Generate HTML link tag
|
|
1706
|
+
html = manager.to_html
|
|
1707
|
+
# <link rel="canonical" href="https://example.com/page">
|
|
1708
|
+
|
|
1709
|
+
# Generate HTTP header
|
|
1710
|
+
header = manager.to_http_header
|
|
1711
|
+
# <https://example.com/page>; rel="canonical"
|
|
1712
|
+
|
|
1713
|
+
# Validate URL
|
|
1714
|
+
manager.validate! # Raises ValidationError if invalid
|
|
1715
|
+
```
|
|
1716
|
+
|
|
1717
|
+
#### URL Normalization
|
|
1718
|
+
|
|
1719
|
+
```ruby
|
|
1720
|
+
manager = BetterSeo::Generators::CanonicalUrlManager.new
|
|
1721
|
+
|
|
1722
|
+
# Removes trailing slashes
|
|
1723
|
+
manager.url = "https://example.com/page/"
|
|
1724
|
+
manager.url # => "https://example.com/page"
|
|
1725
|
+
|
|
1726
|
+
# Removes fragment identifiers
|
|
1727
|
+
manager.url = "https://example.com/page#section"
|
|
1728
|
+
manager.url # => "https://example.com/page"
|
|
1729
|
+
|
|
1730
|
+
# Optional: Remove query parameters
|
|
1731
|
+
manager.remove_query_params = true
|
|
1732
|
+
manager.url = "https://example.com/page?utm_source=twitter&ref=123"
|
|
1733
|
+
manager.url # => "https://example.com/page"
|
|
1734
|
+
|
|
1735
|
+
# Optional: Lowercase URL
|
|
1736
|
+
manager.lowercase = true
|
|
1737
|
+
manager.url = "https://Example.com/Page"
|
|
1738
|
+
manager.url # => "https://example.com/page"
|
|
1739
|
+
```
|
|
1740
|
+
|
|
1741
|
+
#### Rails Integration
|
|
1742
|
+
|
|
1743
|
+
```ruby
|
|
1744
|
+
# Controller
|
|
1745
|
+
class ArticlesController < ApplicationController
|
|
1746
|
+
def show
|
|
1747
|
+
@article = Article.find(params[:id])
|
|
1748
|
+
|
|
1749
|
+
canonical = BetterSeo::Generators::CanonicalUrlManager.new
|
|
1750
|
+
canonical.remove_query_params = true
|
|
1751
|
+
canonical.url = article_url(@article)
|
|
1752
|
+
|
|
1753
|
+
response.headers['Link'] = canonical.to_http_header
|
|
1754
|
+
@canonical_tag = canonical.to_html
|
|
1755
|
+
end
|
|
1756
|
+
end
|
|
1757
|
+
|
|
1758
|
+
# View (app/views/articles/show.html.erb)
|
|
1759
|
+
<head>
|
|
1760
|
+
<%= raw @canonical_tag %>
|
|
1761
|
+
</head>
|
|
1762
|
+
```
|
|
1763
|
+
|
|
1764
|
+
#### Advanced Normalization
|
|
1765
|
+
|
|
1766
|
+
```ruby
|
|
1767
|
+
manager = BetterSeo::Generators::CanonicalUrlManager.new
|
|
1768
|
+
manager.remove_query_params = true
|
|
1769
|
+
manager.lowercase = true
|
|
1770
|
+
manager.url = "https://Example.com/Page/?utm_source=google#section"
|
|
1771
|
+
|
|
1772
|
+
manager.url # => "https://example.com/page"
|
|
1773
|
+
manager.validate! # => true
|
|
1774
|
+
```
|
|
1775
|
+
|
|
1776
|
+
#### Error Handling
|
|
1777
|
+
|
|
1778
|
+
```ruby
|
|
1779
|
+
manager = BetterSeo::Generators::CanonicalUrlManager.new
|
|
1780
|
+
|
|
1781
|
+
# Relative URLs not allowed
|
|
1782
|
+
manager.url = "/page"
|
|
1783
|
+
manager.validate! # Raises: "Canonical URL must be absolute: /page"
|
|
1784
|
+
|
|
1785
|
+
# Invalid URL format
|
|
1786
|
+
manager.url = "not a url"
|
|
1787
|
+
manager.validate! # Raises: "Invalid URL format: not a url"
|
|
1788
|
+
|
|
1789
|
+
# URL is required
|
|
1790
|
+
manager.url = nil
|
|
1791
|
+
manager.validate! # Raises: "URL is required"
|
|
1792
|
+
```
|
|
1793
|
+
|
|
1794
|
+
---
|
|
1795
|
+
|
|
1535
1796
|
## Configuration Reference
|
|
1536
1797
|
|
|
1537
1798
|
### Global Configuration
|
data/lib/better_seo/version.rb
CHANGED
data/lib/better_seo.rb
CHANGED
|
@@ -13,6 +13,9 @@ 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/generators/breadcrumbs_generator"
|
|
17
|
+
require_relative "better_seo/generators/amp_generator"
|
|
18
|
+
require_relative "better_seo/generators/canonical_url_manager"
|
|
16
19
|
require_relative "better_seo/sitemap/url_entry"
|
|
17
20
|
require_relative "better_seo/sitemap/builder"
|
|
18
21
|
require_relative "better_seo/sitemap/generator"
|