better_seo 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 181be2cb7b7341c4b6d304b2d093351f0259212d880406d1a3673e1ceb4dbd98
4
- data.tar.gz: 812c35ed74e6250712fa668abbe8274069e601bc5d9bb342283e95061c5f7d83
3
+ metadata.gz: bbb87756b71cdc491faaba16bd349149051ef870ac1eea6dab55c31db3e09bd9
4
+ data.tar.gz: b34bc18d112710290991d430ff5525b920dadc25938aed97a6e20a3309118d45
5
5
  SHA512:
6
- metadata.gz: 546233d6a80cc7780d642fd6cf96dcc2ee931dbc39a444a9fc224173579af8a7e8235f9a588a5d212f31c5930c0d6f007fc778090c11baca021ffb690c8b85aa
7
- data.tar.gz: 4d2620e7b9c8b517d4c412b24b7f7b0b7e3aaf76d4c16f8b9c29357fb9517f1a85225b4130f816902553a0800db0f1aa51999120c07ea6973c138ebfbee7c9a7
6
+ metadata.gz: ca7e8d51f6c035725975a2326908156c0e6c5281d4ded7a10fd709775e4aa44208a5a609589fbbaf66c62ef0f54ab4f024b5a685001ab472cb2d1e0bb24097a2
7
+ data.tar.gz: b353b67665a36f045d2db900d3285996d021ec19db9b5ac7c1fd697ecfa5c4082fc895a3517190f70c79ae7f4f78d9290ab0f79034c3ecdc2da6ad490df20436
data/CHANGELOG.md CHANGED
@@ -7,6 +7,98 @@ 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
+
61
+ ## [0.11.0] - 2025-01-23
62
+
63
+ ### Added
64
+ - Advanced Sitemap Features for large and international sites
65
+ - **Multi-language Support (hreflang)**
66
+ - `UrlEntry#add_alternate(href, hreflang:)` - Add alternate language versions
67
+ - Support for region-specific alternates (en-US, en-GB, etc.)
68
+ - x-default alternate support for default language
69
+ - Automatic xhtml:link tag generation in XML
70
+ - Method chaining for adding multiple alternates
71
+ - **Image Sitemap Extensions**
72
+ - `UrlEntry#add_image(loc, title:, caption:)` - Add images to URLs
73
+ - Support for multiple images per URL
74
+ - Automatic image:image tag generation
75
+ - Optional title and caption metadata
76
+ - **Video Sitemap Extensions**
77
+ - `UrlEntry#add_video(thumbnail_loc:, title:, description:, content_loc:, duration:)` - Add videos to URLs
78
+ - Support for multiple videos per URL
79
+ - Automatic video:video tag generation
80
+ - Optional duration metadata
81
+ - **Sitemap Index** (`BetterSeo::Sitemap::SitemapIndex`)
82
+ - Manage large sites with 50,000+ URLs
83
+ - Split sitemaps across multiple files
84
+ - `add_sitemap(loc, lastmod:)` - Add sitemaps to index
85
+ - `to_xml` - Generate sitemapindex XML
86
+ - `write_to_file(path)` - Write index to file
87
+ - Automatic directory creation
88
+
89
+ ### Enhanced
90
+ - `UrlEntry` now supports alternates, images, and videos arrays
91
+ - `UrlEntry#to_xml` includes all extensions (hreflang, images, videos)
92
+ - `UrlEntry#to_h` includes alternates when present
93
+
94
+ ### Test Coverage
95
+ - 742 tests passing (+35 from v0.10.0)
96
+ - 96.12% code coverage (1364/1419 lines)
97
+ - 35 new tests across advanced sitemap features:
98
+ - Hreflang support: 11 tests
99
+ - SitemapIndex: 12 tests
100
+ - Image/Video extensions: 12 tests
101
+
10
102
  ## [0.10.0] - 2025-01-23
11
103
 
12
104
  ### 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-707%20passing-brightgreen)](https://github.com/yourusername/better_seo)
6
- [![Coverage](https://img.shields.io/badge/coverage-95.99%25-brightgreen)](https://github.com/yourusername/better_seo)
5
+ [![Tests](https://img.shields.io/badge/tests-811%20passing-brightgreen)](https://github.com/yourusername/better_seo)
6
+ [![Coverage](https://img.shields.io/badge/coverage-96.41%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.10.0)
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
 
@@ -43,10 +46,14 @@ A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a cl
43
46
  - Automatic HTML safety with `raw` helper
44
47
  - Integration with global configuration defaults
45
48
 
46
- - **Sitemap Generation**
49
+ - **Sitemap Generation** - Advanced features for large sites
47
50
  - **XML Sitemap Builder**: Fluent API for building sitemaps
48
51
  - **Sitemap Generator**: Generate from blocks, arrays, or model collections
49
52
  - **URL Entry**: Full sitemap.org protocol support (loc, lastmod, changefreq, priority)
53
+ - **Multi-language Support**: hreflang alternates for international sites
54
+ - **Image Sitemaps**: Add images with title and caption to URLs
55
+ - **Video Sitemaps**: Add videos with thumbnail, title, description, duration
56
+ - **Sitemap Index**: Manage large sites with 50,000+ URLs across multiple sitemaps
50
57
  - **Dynamic Generation**: Lambda support for dynamic attributes
51
58
  - **File Writing**: Write sitemaps directly to files
52
59
  - **Rails Integration**: Controller actions and Rake tasks
@@ -72,22 +79,11 @@ A comprehensive SEO gem for Ruby and Rails applications. BetterSeo provides a cl
72
79
 
73
80
  ### 🚧 Planned
74
81
 
75
- - **Advanced Generators** (v1.1.0)
76
- - Breadcrumbs HTML generator
77
- - AMP HTML generator
78
- - Canonical URL management
79
-
80
- - **Advanced Sitemap Features** (v1.1.0)
81
- - Multi-language sitemap support (hreflang)
82
- - Sitemap index for large sites (50,000+ URLs)
83
- - Image/video sitemap extensions
84
- - News sitemap support
85
-
86
- - **Advanced Features** (v0.6.0+)
82
+ - **Advanced Features** (v0.13.0+)
87
83
  - robots.txt generator
88
84
  - Image optimization with WebP conversion
89
- - Structured data builders (Organization, Person, Product, etc.)
90
85
  - SEO validators and recommendations
86
+ - Performance monitoring and analytics integration
91
87
 
92
88
  ## Installation
93
89
 
@@ -1534,6 +1530,269 @@ all_tags = BetterSeo::StructuredData::Generator.generate_script_tags([
1534
1530
  - **Standards Compliant**: Follows Schema.org specifications
1535
1531
  - **Easy Integration**: Works seamlessly with Rails views and helpers
1536
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
+
1537
1796
  ## Configuration Reference
1538
1797
 
1539
1798
  ### Global Configuration
@@ -1643,13 +1902,13 @@ bundle exec rspec --format documentation
1643
1902
  ```
1644
1903
 
1645
1904
  Current test statistics:
1646
- - **707 tests** passing
1647
- - **95.99% code coverage** (1293/1347 lines)
1905
+ - **742 tests** passing
1906
+ - **96.12% code coverage** (1364/1419 lines)
1648
1907
  - **3 DSL builders** fully tested
1649
1908
  - **3 HTML generators** fully tested
1650
1909
  - **3 Rails helper modules** fully tested (View, Controller, Model)
1651
1910
  - **10 Structured data types** fully tested
1652
- - **1 Sitemap generation system** fully tested
1911
+ - **1 Advanced sitemap system** with hreflang, images, videos, and index
1653
1912
  - **1 Railtie and Generator** fully tested
1654
1913
  - **1 core configuration system** fully tested
1655
1914
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BetterSeo
4
- VERSION = "0.10.0"
4
+ VERSION = "0.12.0"
5
5
  end
data/lib/better_seo.rb CHANGED
@@ -13,9 +13,13 @@ 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"
22
+ require_relative "better_seo/sitemap/sitemap_index"
19
23
  require_relative "better_seo/structured_data/base"
20
24
  require_relative "better_seo/structured_data/organization"
21
25
  require_relative "better_seo/structured_data/article"
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: 0.10.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - alessiobussolari