jekyll-ai-domain-data 0.1.1
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 +7 -0
- data/CHANGELOG.md +27 -0
- data/LICENSE +22 -0
- data/README.md +188 -0
- data/lib/jekyll-ai-domain-data/generator.rb +93 -0
- data/lib/jekyll-ai-domain-data/schema.rb +78 -0
- data/lib/jekyll-ai-domain-data/tags.rb +72 -0
- data/lib/jekyll-ai-domain-data/validator.rb +41 -0
- data/lib/jekyll-ai-domain-data/version.rb +8 -0
- data/lib/jekyll-ai-domain-data.rb +18 -0
- metadata +92 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 2a4e55e4ff4d2a8c9451f95a1e68c5f822622e10915f251893c4b6de7ab0c66c
|
|
4
|
+
data.tar.gz: f4954fabf7a33fa5df670a4c2f5a1522d716479636d8fc4cfcaa3030ec100e6d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 58c8e54f60ba26619a5b0f66967ae0039d9c1f798b6cc0c4582b976d72bbc6dda6429d53248c2938872a2d4346e367fa7c71724fdd53b895ed21bef09f4682e3
|
|
7
|
+
data.tar.gz: 32c99efb6f9f4484be08b4e1e799da5831d7016fd7c06335a2398c77a50a23669c5be6f6e72db0e87ae47b60c522f2f287ca6e9ba31eaa9cf7b0a0449a201dca
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.1] - 2025-11-18
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial release
|
|
13
|
+
- Automatic generation of `.well-known/domain-profile.json` during Jekyll build
|
|
14
|
+
- Schema validation against AI Domain Data Standard v0.1.1
|
|
15
|
+
- Liquid tag `{% ai_domain_data %}` for accessing domain data in templates
|
|
16
|
+
- Support for all required and optional fields (name, description, website, contact, logo, entity_type, jsonld)
|
|
17
|
+
- Automatic field mapping from Jekyll site configuration
|
|
18
|
+
- Validation error reporting in build output
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- N/A (initial release)
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- N/A (initial release)
|
|
27
|
+
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Dylan Larson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# jekyll-ai-domain-data
|
|
2
|
+
|
|
3
|
+
A Jekyll plugin that automatically generates and validates `domain-profile.json` files according to the [AI Domain Data Standard](https://ai-domain-data.org) v0.1.1.
|
|
4
|
+
|
|
5
|
+
The AI Domain Data Standard is an open, vendor-neutral format for publishing authoritative domain identity data for AI systems, search engines, and automated agents. This plugin makes it easy to add AI Domain Data support to your Jekyll site.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add this line to your site's `Gemfile`:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem "jekyll-ai-domain-data"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
And then execute:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bundle install
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or install it yourself as:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gem install jekyll-ai-domain-data
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Then add the plugin to your `_config.yml`:
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
plugins:
|
|
31
|
+
- jekyll-ai-domain-data
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
Add an `ai_domain_data` section to your `_config.yml`:
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
ai_domain_data:
|
|
40
|
+
enabled: true # Set to false to disable generation
|
|
41
|
+
name: "Your Site Name"
|
|
42
|
+
description: "A concise description of your site or organization"
|
|
43
|
+
website: "https://example.com" # Optional, defaults to site.url
|
|
44
|
+
contact: "contact@example.com"
|
|
45
|
+
logo: "https://example.com/logo.png" # Optional
|
|
46
|
+
entity_type: "Organization" # Optional: Organization, Person, Blog, NGO, Community, Project, CreativeWork, SoftwareApplication, or Thing
|
|
47
|
+
jsonld: # Optional: Embedded JSON-LD block
|
|
48
|
+
"@context": "https://schema.org"
|
|
49
|
+
"@type": "Organization"
|
|
50
|
+
"name": "Your Site Name"
|
|
51
|
+
"url": "https://example.com"
|
|
52
|
+
"email": "contact@example.com"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Field Mapping
|
|
56
|
+
|
|
57
|
+
The plugin will automatically use values from your Jekyll config if not explicitly set:
|
|
58
|
+
|
|
59
|
+
- `name`: Falls back to `site.title` or `site.name`
|
|
60
|
+
- `description`: Falls back to `site.description`
|
|
61
|
+
- `website`: Falls back to `site.url` (will be prefixed with `https://` if missing)
|
|
62
|
+
- `contact`: Falls back to `site.email`
|
|
63
|
+
|
|
64
|
+
### Minimal Configuration
|
|
65
|
+
|
|
66
|
+
If you already have basic site metadata in `_config.yml`, you can use a minimal configuration:
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
ai_domain_data:
|
|
70
|
+
contact: "contact@example.com" # Required, no fallback
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
All other fields will be pulled from your existing Jekyll configuration.
|
|
74
|
+
|
|
75
|
+
## Usage
|
|
76
|
+
|
|
77
|
+
### Automatic Generation
|
|
78
|
+
|
|
79
|
+
Once configured, the plugin automatically generates `.well-known/domain-profile.json` during site build. The file will be available at:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
https://yourdomain.com/.well-known/domain-profile.json
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Liquid Tags
|
|
86
|
+
|
|
87
|
+
You can also access domain data in your templates using the `ai_domain_data` tag:
|
|
88
|
+
|
|
89
|
+
```liquid
|
|
90
|
+
{% ai_domain_data name %} <!-- Outputs: Your Site Name -->
|
|
91
|
+
{% ai_domain_data description %} <!-- Outputs: Your description -->
|
|
92
|
+
{% ai_domain_data website %} <!-- Outputs: https://example.com -->
|
|
93
|
+
{% ai_domain_data contact %} <!-- Outputs: contact@example.com -->
|
|
94
|
+
{% ai_domain_data logo %} <!-- Outputs: https://example.com/logo.png -->
|
|
95
|
+
{% ai_domain_data entity_type %} <!-- Outputs: Organization -->
|
|
96
|
+
{% ai_domain_data json %} <!-- Outputs: Pretty-printed JSON -->
|
|
97
|
+
{% ai_domain_data json_compact %} <!-- Outputs: Compact JSON -->
|
|
98
|
+
{% ai_domain_data %} <!-- Outputs: Pretty-printed full JSON -->
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Example: Embedding in HTML
|
|
102
|
+
|
|
103
|
+
```html
|
|
104
|
+
<script type="application/ld+json">
|
|
105
|
+
{% ai_domain_data json %}
|
|
106
|
+
</script>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Validation
|
|
110
|
+
|
|
111
|
+
The plugin validates your configuration against the AI Domain Data Standard schema before generating the file. If validation fails, you'll see warnings in the build output and the file won't be generated.
|
|
112
|
+
|
|
113
|
+
Common validation errors:
|
|
114
|
+
|
|
115
|
+
- Missing required fields (`name`, `description`, `website`, `contact`)
|
|
116
|
+
- Invalid `entity_type` (must be a valid schema.org @type value)
|
|
117
|
+
- Invalid `jsonld` structure (must include `@context: "https://schema.org"` and `@type`)
|
|
118
|
+
|
|
119
|
+
## Examples
|
|
120
|
+
|
|
121
|
+
### Basic Configuration
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
# _config.yml
|
|
125
|
+
title: "My Awesome Blog"
|
|
126
|
+
description: "A blog about web development and technology"
|
|
127
|
+
url: "https://myblog.com"
|
|
128
|
+
email: "hello@myblog.com"
|
|
129
|
+
|
|
130
|
+
ai_domain_data:
|
|
131
|
+
contact: "hello@myblog.com"
|
|
132
|
+
entity_type: "Blog"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Complete Configuration
|
|
136
|
+
|
|
137
|
+
```yaml
|
|
138
|
+
# _config.yml
|
|
139
|
+
ai_domain_data:
|
|
140
|
+
name: "Acme Corporation"
|
|
141
|
+
description: "Leading provider of innovative solutions"
|
|
142
|
+
website: "https://acme.com"
|
|
143
|
+
contact: "info@acme.com"
|
|
144
|
+
logo: "https://acme.com/logo.png"
|
|
145
|
+
entity_type: "Organization"
|
|
146
|
+
jsonld:
|
|
147
|
+
"@context": "https://schema.org"
|
|
148
|
+
"@type": "Organization"
|
|
149
|
+
"name": "Acme Corporation"
|
|
150
|
+
"url": "https://acme.com"
|
|
151
|
+
"logo": "https://acme.com/logo.png"
|
|
152
|
+
"email": "info@acme.com"
|
|
153
|
+
"description": "Leading provider of innovative solutions"
|
|
154
|
+
"foundingDate": "2020-01-01"
|
|
155
|
+
"numberOfEmployees": "50-100"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Requirements
|
|
159
|
+
|
|
160
|
+
- Jekyll >= 3.8, < 5.0
|
|
161
|
+
- Ruby >= 2.7.0
|
|
162
|
+
|
|
163
|
+
## Development
|
|
164
|
+
|
|
165
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle exec rake spec` to run the tests.
|
|
166
|
+
|
|
167
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
168
|
+
|
|
169
|
+
## Contributing
|
|
170
|
+
|
|
171
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ai-domain-data/jekyll-ai-domain-data.
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
176
|
+
|
|
177
|
+
## Related Projects
|
|
178
|
+
|
|
179
|
+
- [AI Domain Data Standard](https://ai-domain-data.org) - The specification this plugin implements
|
|
180
|
+
- [AI Domain Data CLI](https://github.com/ai-domain-data/spec/tree/main/packages/cli) - Command-line tool for generating and validating domain profiles
|
|
181
|
+
- [AI Domain Data Resolver SDK](https://github.com/ai-domain-data/spec/tree/main/packages/resolver) - TypeScript/Node.js SDK for resolving domain profiles
|
|
182
|
+
|
|
183
|
+
## Support
|
|
184
|
+
|
|
185
|
+
For issues, questions, or contributions, please visit:
|
|
186
|
+
- GitHub Issues: https://github.com/ai-domain-data/jekyll-ai-domain-data/issues
|
|
187
|
+
- AI Domain Data Standard: https://ai-domain-data.org
|
|
188
|
+
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "fileutils"
|
|
5
|
+
require_relative "validator"
|
|
6
|
+
require_relative "schema"
|
|
7
|
+
|
|
8
|
+
module Jekyll
|
|
9
|
+
module AIDomainData
|
|
10
|
+
# Jekyll Generator that creates .well-known/domain-profile.json
|
|
11
|
+
class Generator < Jekyll::Generator
|
|
12
|
+
safe true
|
|
13
|
+
priority :low
|
|
14
|
+
|
|
15
|
+
def generate(site)
|
|
16
|
+
config = site.config["ai_domain_data"] || {}
|
|
17
|
+
|
|
18
|
+
# Skip if disabled
|
|
19
|
+
return if config["enabled"] == false
|
|
20
|
+
|
|
21
|
+
# Build domain profile from config
|
|
22
|
+
profile = build_profile(site, config)
|
|
23
|
+
|
|
24
|
+
# Validate the profile
|
|
25
|
+
validation_result = Validator.validate(profile)
|
|
26
|
+
|
|
27
|
+
if validation_result[:valid]
|
|
28
|
+
# Create the .well-known directory and file
|
|
29
|
+
create_domain_profile(site, profile)
|
|
30
|
+
Jekyll.logger.info "AI Domain Data:", "Generated .well-known/domain-profile.json"
|
|
31
|
+
else
|
|
32
|
+
Jekyll.logger.warn "AI Domain Data:", "Validation failed:"
|
|
33
|
+
validation_result[:errors].each do |error|
|
|
34
|
+
Jekyll.logger.warn "", " - #{error}"
|
|
35
|
+
end
|
|
36
|
+
Jekyll.logger.warn "", "Skipping domain-profile.json generation. Fix configuration errors and rebuild."
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def build_profile(site, config)
|
|
43
|
+
# Get site URL (required)
|
|
44
|
+
website = config["website"] || site.config["url"]
|
|
45
|
+
if website && !website.start_with?("http")
|
|
46
|
+
website = "https://#{website}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Build required fields
|
|
50
|
+
profile = {
|
|
51
|
+
"spec" => "https://ai-domain-data.org/spec/v0.1",
|
|
52
|
+
"name" => config["name"] || site.config["title"] || site.config["name"] || "Untitled Site",
|
|
53
|
+
"description" => config["description"] || site.config["description"] || "",
|
|
54
|
+
"website" => website || "",
|
|
55
|
+
"contact" => config["contact"] || site.config["email"] || ""
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Add optional fields if provided
|
|
59
|
+
profile["logo"] = config["logo"] if config["logo"]
|
|
60
|
+
profile["entity_type"] = config["entity_type"] if config["entity_type"]
|
|
61
|
+
profile["jsonld"] = config["jsonld"] if config["jsonld"]
|
|
62
|
+
|
|
63
|
+
profile
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def create_domain_profile(site, profile)
|
|
67
|
+
# Create .well-known directory in source
|
|
68
|
+
well_known_source = File.join(site.source, ".well-known")
|
|
69
|
+
FileUtils.mkdir_p(well_known_source) unless Dir.exist?(well_known_source)
|
|
70
|
+
|
|
71
|
+
# Write domain-profile.json to source
|
|
72
|
+
output_path = File.join(well_known_source, "domain-profile.json")
|
|
73
|
+
File.write(output_path, JSON.pretty_generate(profile) + "\n")
|
|
74
|
+
|
|
75
|
+
# Register the file with Jekyll so it gets copied to the destination
|
|
76
|
+
# Check if it's already registered to avoid duplicates
|
|
77
|
+
existing = site.static_files.find do |file|
|
|
78
|
+
file.relative_path == "/.well-known/domain-profile.json"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
unless existing
|
|
82
|
+
site.static_files << Jekyll::StaticFile.new(
|
|
83
|
+
site,
|
|
84
|
+
site.source,
|
|
85
|
+
".well-known",
|
|
86
|
+
"domain-profile.json"
|
|
87
|
+
)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jekyll
|
|
4
|
+
module AIDomainData
|
|
5
|
+
# JSON Schema for AI Domain Data Standard v0.1.1
|
|
6
|
+
SCHEMA = {
|
|
7
|
+
"$id" => "https://ai-domain-data.org/spec/schema-v0.1.json",
|
|
8
|
+
"title" => "AI Domain Data v0.1.1",
|
|
9
|
+
"type" => "object",
|
|
10
|
+
"additionalProperties" => false,
|
|
11
|
+
"required" => %w[spec name description website contact],
|
|
12
|
+
"properties" => {
|
|
13
|
+
"spec" => {
|
|
14
|
+
"type" => "string",
|
|
15
|
+
"const" => "https://ai-domain-data.org/spec/v0.1",
|
|
16
|
+
"description" => "Canonical URL for the AI Domain Data specification version."
|
|
17
|
+
},
|
|
18
|
+
"name" => {
|
|
19
|
+
"type" => "string",
|
|
20
|
+
"minLength" => 1,
|
|
21
|
+
"description" => "Public-facing name for the site, organization, or publisher."
|
|
22
|
+
},
|
|
23
|
+
"description" => {
|
|
24
|
+
"type" => "string",
|
|
25
|
+
"minLength" => 1,
|
|
26
|
+
"description" => "Concise description used by AI agents to understand the domain."
|
|
27
|
+
},
|
|
28
|
+
"website" => {
|
|
29
|
+
"type" => "string",
|
|
30
|
+
"format" => "uri",
|
|
31
|
+
"description" => "Primary website URL for the domain."
|
|
32
|
+
},
|
|
33
|
+
"logo" => {
|
|
34
|
+
"type" => "string",
|
|
35
|
+
"format" => "uri",
|
|
36
|
+
"description" => "Optional URL to a logo or representative image."
|
|
37
|
+
},
|
|
38
|
+
"contact" => {
|
|
39
|
+
"type" => "string",
|
|
40
|
+
"minLength" => 1,
|
|
41
|
+
"description" => "Preferred contact point (email or URL)."
|
|
42
|
+
},
|
|
43
|
+
"entity_type" => {
|
|
44
|
+
"type" => "string",
|
|
45
|
+
"enum" => %w[
|
|
46
|
+
Organization
|
|
47
|
+
Person
|
|
48
|
+
Blog
|
|
49
|
+
NGO
|
|
50
|
+
Community
|
|
51
|
+
Project
|
|
52
|
+
CreativeWork
|
|
53
|
+
SoftwareApplication
|
|
54
|
+
Thing
|
|
55
|
+
],
|
|
56
|
+
"description" => "Optional schema.org @type value for entity classification."
|
|
57
|
+
},
|
|
58
|
+
"jsonld" => {
|
|
59
|
+
"type" => "object",
|
|
60
|
+
"description" => "Optional embedded JSON-LD block for schema.org alignment.",
|
|
61
|
+
"properties" => {
|
|
62
|
+
"@context" => {
|
|
63
|
+
"type" => "string",
|
|
64
|
+
"const" => "https://schema.org"
|
|
65
|
+
},
|
|
66
|
+
"@type" => {
|
|
67
|
+
"type" => "string",
|
|
68
|
+
"minLength" => 1
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"required" => %w[@context @type],
|
|
72
|
+
"additionalProperties" => true
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}.freeze
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Jekyll
|
|
6
|
+
module AIDomainData
|
|
7
|
+
# Liquid tag to output domain profile data
|
|
8
|
+
# Usage: {% ai_domain_data name %} or {% ai_domain_data json %}
|
|
9
|
+
class DomainDataTag < Liquid::Tag
|
|
10
|
+
def initialize(tag_name, field, tokens)
|
|
11
|
+
super
|
|
12
|
+
@field = field&.strip
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def render(context)
|
|
16
|
+
site = context.registers[:site]
|
|
17
|
+
config = site.config["ai_domain_data"] || {}
|
|
18
|
+
|
|
19
|
+
# Build profile (same logic as generator)
|
|
20
|
+
profile = build_profile(site, config)
|
|
21
|
+
|
|
22
|
+
case @field
|
|
23
|
+
when "name"
|
|
24
|
+
profile["name"] || ""
|
|
25
|
+
when "description"
|
|
26
|
+
profile["description"] || ""
|
|
27
|
+
when "website"
|
|
28
|
+
profile["website"] || ""
|
|
29
|
+
when "contact"
|
|
30
|
+
profile["contact"] || ""
|
|
31
|
+
when "logo"
|
|
32
|
+
profile["logo"] || ""
|
|
33
|
+
when "entity_type"
|
|
34
|
+
profile["entity_type"] || ""
|
|
35
|
+
when "json"
|
|
36
|
+
JSON.pretty_generate(profile)
|
|
37
|
+
when "json_compact"
|
|
38
|
+
JSON.generate(profile)
|
|
39
|
+
else
|
|
40
|
+
# Return all data as JSON if no field specified
|
|
41
|
+
JSON.pretty_generate(profile)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def build_profile(site, config)
|
|
48
|
+
website = config["website"] || site.config["url"]
|
|
49
|
+
if website && !website.start_with?("http")
|
|
50
|
+
website = "https://#{website}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
profile = {
|
|
54
|
+
"spec" => "https://ai-domain-data.org/spec/v0.1",
|
|
55
|
+
"name" => config["name"] || site.config["title"] || site.config["name"] || "Untitled Site",
|
|
56
|
+
"description" => config["description"] || site.config["description"] || "",
|
|
57
|
+
"website" => website || "",
|
|
58
|
+
"contact" => config["contact"] || site.config["email"] || ""
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
profile["logo"] = config["logo"] if config["logo"]
|
|
62
|
+
profile["entity_type"] = config["entity_type"] if config["entity_type"]
|
|
63
|
+
profile["jsonld"] = config["jsonld"] if config["jsonld"]
|
|
64
|
+
|
|
65
|
+
profile
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
Liquid::Template.register_tag("ai_domain_data", Jekyll::AIDomainData::DomainDataTag)
|
|
72
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json-schema"
|
|
4
|
+
require_relative "schema"
|
|
5
|
+
|
|
6
|
+
module Jekyll
|
|
7
|
+
module AIDomainData
|
|
8
|
+
# Validates domain profile data against the AI Domain Data Standard schema
|
|
9
|
+
class Validator
|
|
10
|
+
def self.validate(data)
|
|
11
|
+
errors = []
|
|
12
|
+
|
|
13
|
+
begin
|
|
14
|
+
JSON::Validator.validate!(SCHEMA, data, strict: false)
|
|
15
|
+
{ valid: true, errors: [] }
|
|
16
|
+
rescue JSON::Schema::ValidationError => e
|
|
17
|
+
errors << e.message
|
|
18
|
+
{ valid: false, errors: errors }
|
|
19
|
+
rescue JSON::Schema::SchemaError => e
|
|
20
|
+
errors << "Schema error: #{e.message}"
|
|
21
|
+
{ valid: false, errors: errors }
|
|
22
|
+
rescue StandardError => e
|
|
23
|
+
errors << "Validation error: #{e.message}"
|
|
24
|
+
{ valid: false, errors: errors }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.validate!(data)
|
|
29
|
+
result = validate(data)
|
|
30
|
+
unless result[:valid]
|
|
31
|
+
raise ValidationError, "Domain profile validation failed:\n #{result[:errors].join("\n ")}"
|
|
32
|
+
end
|
|
33
|
+
result
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Custom error class for validation failures
|
|
38
|
+
class ValidationError < StandardError; end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "jekyll"
|
|
4
|
+
|
|
5
|
+
module Jekyll
|
|
6
|
+
module AIDomainData
|
|
7
|
+
autoload :Generator, "jekyll-ai-domain-data/generator"
|
|
8
|
+
autoload :Validator, "jekyll-ai-domain-data/validator"
|
|
9
|
+
autoload :Schema, "jekyll-ai-domain-data/schema"
|
|
10
|
+
autoload :DomainDataTag, "jekyll-ai-domain-data/tags"
|
|
11
|
+
autoload :VERSION, "jekyll-ai-domain-data/version"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Explicitly require the generator and tags so Jekyll can discover them
|
|
16
|
+
require_relative "jekyll-ai-domain-data/generator"
|
|
17
|
+
require_relative "jekyll-ai-domain-data/tags"
|
|
18
|
+
|
metadata
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jekyll-ai-domain-data
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- AI Domain Data Standard Contributors
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: jekyll
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '3.8'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '5.0'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '3.8'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '5.0'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: json-schema
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - "~>"
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '4.0'
|
|
39
|
+
type: :runtime
|
|
40
|
+
prerelease: false
|
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - "~>"
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '4.0'
|
|
46
|
+
description: |
|
|
47
|
+
A Jekyll plugin that automatically generates and validates domain-profile.json files
|
|
48
|
+
according to the AI Domain Data Standard v0.1.1. The plugin creates the file at
|
|
49
|
+
.well-known/domain-profile.json during site generation and provides Liquid tags
|
|
50
|
+
for accessing domain data in your templates.
|
|
51
|
+
email:
|
|
52
|
+
- info@ascendingwebservices.com
|
|
53
|
+
executables: []
|
|
54
|
+
extensions: []
|
|
55
|
+
extra_rdoc_files: []
|
|
56
|
+
files:
|
|
57
|
+
- CHANGELOG.md
|
|
58
|
+
- LICENSE
|
|
59
|
+
- README.md
|
|
60
|
+
- lib/jekyll-ai-domain-data.rb
|
|
61
|
+
- lib/jekyll-ai-domain-data/generator.rb
|
|
62
|
+
- lib/jekyll-ai-domain-data/schema.rb
|
|
63
|
+
- lib/jekyll-ai-domain-data/tags.rb
|
|
64
|
+
- lib/jekyll-ai-domain-data/validator.rb
|
|
65
|
+
- lib/jekyll-ai-domain-data/version.rb
|
|
66
|
+
homepage: https://github.com/ai-domain-data/jekyll-ai-domain-data
|
|
67
|
+
licenses:
|
|
68
|
+
- MIT
|
|
69
|
+
metadata:
|
|
70
|
+
bug_tracker_uri: https://github.com/ai-domain-data/jekyll-ai-domain-data/issues
|
|
71
|
+
changelog_uri: https://github.com/ai-domain-data/jekyll-ai-domain-data/blob/main/CHANGELOG.md
|
|
72
|
+
documentation_uri: https://github.com/ai-domain-data/jekyll-ai-domain-data#readme
|
|
73
|
+
source_code_uri: https://github.com/ai-domain-data/jekyll-ai-domain-data
|
|
74
|
+
rdoc_options: []
|
|
75
|
+
require_paths:
|
|
76
|
+
- lib
|
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: 2.7.0
|
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '0'
|
|
87
|
+
requirements: []
|
|
88
|
+
rubygems_version: 3.6.9
|
|
89
|
+
specification_version: 4
|
|
90
|
+
summary: Jekyll plugin for generating AI Domain Data Standard domain-profile.json
|
|
91
|
+
files
|
|
92
|
+
test_files: []
|