laravel-jsonld maintained by asmi046
Laravel JSON-LD
Пакет для Laravel, который рендерит schema-сущности JSON-LD через fluent API фасада. Поддерживает типы Person, Organization, Article, Product, WebSite, LocalBusiness, TravelAgency и TouristTrip, а также строгую валидацию и интеграцию с Blade.
Installation
composer require asmi046/laravel-jsonld
Configuration
Опубликуйте конфигурационный файл:
php artisan vendor:publish --tag=jsonld-config
Configuration Options
// config/jsonld.php
return [
// Включить строгую валидацию (обязательные поля должны быть заполнены)
'strict' => true,
// Красивое форматирование JSON
'pretty_print' => false,
// Режим экранирования HTML: 'none', 'json_encode', 'htmlspecialchars'
'escape_mode' => 'json_encode',
// Флаги json_encode
'json_flags' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE,
];
Usage
Fluent Builder API
use Asmi\JsonLd\Facades\JsonLd;
// Person
$person = JsonLd::person()
->name('John Doe')
->jobTitle('Software Developer')
->email('john@example.com')
->url('https://johndoe.com')
->render();
// Organization
$org = JsonLd::organization()
->name('Acme Corporation')
->url('https://acme.com')
->logo('https://acme.com/logo.png')
->email('contact@acme.com')
->telephone('+1-555-0100')
->render();
// Article
$article = JsonLd::article()
->headline('Understanding JSON-LD')
->description('Learn how to use JSON-LD for structured data...')
->datePublished('2026-04-09')
->dateModified('2026-04-10')
->image('https://example.com/image.jpg')
->author(JsonLd::person()->name('Jane Smith'))
->render();
// Product
$product = JsonLd::product()
->name('Awesome Product')
->description('The best product ever')
->price(99.99)
->priceCurrency('USD')
->image('https://example.com/product.jpg')
->brand(JsonLd::organization()->name('Brand Inc'))
->url('https://example.com/product')
->render();
// WebSite
$website = JsonLd::website()
->name('My Website')
->url('https://example.com')
->description('Welcome to my website')
->logo('https://example.com/logo.png')
->render();
// LocalBusiness
$localBusiness = JsonLd::localBusiness()
->name('Кофейня на Арбате')
->url('https://coffeeshop.ru')
->telephone('+7-495-000-0000')
->address('Арбат, 10, Москва')
->openingHours('Mo-Fr 08:00-22:00')
->priceRange('$$')
->geo(['@type' => 'GeoCoordinates', 'latitude' => 55.7522, 'longitude' => 37.5722])
->paymentAccepted(['Cash', 'Credit Card'])
->render();
// TravelAgency
$travelAgency = JsonLd::travelAgency()
->name('Путешествия мечты')
->url('https://dream-travel.ru')
->telephone('+7-800-000-0000')
->email('info@dream-travel.ru')
->openingHours('Mo-Su 09:00-21:00')
->areaServed(['Россия', 'Европа', 'Азия'])
->serviceType('Туристические туры')
->render();
// TouristTrip
$trip = JsonLd::touristTrip()
->name('Золотое кольцо на выходные')
->description('Культурный тур по древним городам России')
->startDate('2026-06-01')
->endDate('2026-06-03')
->touristType(['Семьи', 'Пары'])
->itinerary(['Москва', 'Сергиев Посад', 'Суздаль'])
->provider(JsonLd::travelAgency()->name('Путешествия мечты'))
->render();
Factory API
// Создание сущности через метод make
$person = JsonLd::make('Person', [
'name' => 'John Doe',
'jobTitle' => 'Developer',
'email' => 'john@example.com',
])->render();
$org = JsonLd::make('Organization', [
'name' => 'Acme Corp',
'url' => 'https://acme.com',
])->render();
$localBusiness = JsonLd::make('LocalBusiness', [
'name' => 'Кофейня на Арбате',
'telephone' => '+7-495-000-0000',
'openingHours' => 'Mo-Fr 08:00-22:00',
])->render();
$travelAgency = JsonLd::make('TravelAgency', [
'name' => 'Путешествия мечты',
'areaServed' => ['Россия', 'Европа'],
'serviceType' => 'Туристические туры',
])->render();
$trip = JsonLd::make('TouristTrip', [
'name' => 'Золотое кольцо на выходные',
'startDate' => '2026-06-01',
'endDate' => '2026-06-03',
'touristType' => ['Семьи', 'Пары'],
])->render();
Using Helper Functions
// Fluent helper-функции
$person = jsonld_person()
->name('John Doe')
->jobTitle('Developer')
->render();
$org = jsonld_organization()->name('Acme Corp')->render();
$article = jsonld_article()->headline('My Post')->datePublished('2026-04-09')->render();
$product = jsonld_product()->name('Product')->price(99.99)->render();
$website = jsonld_website()->name('Site')->url('https://example.com')->render();
$localBusiness = jsonld_local_business()->name('Кофейня')->openingHours('Mo-Fr 08:00-22:00')->render();
$travelAgency = jsonld_travel_agency()->name('Агентство')->areaServed('Россия')->render();
$trip = jsonld_tourist_trip()->name('Тур')->startDate('2026-06-01')->render();
// Factory helper
$person = jsonld_make('Person', ['name' => 'John']);
$localBusiness = jsonld_make('LocalBusiness', ['name' => 'Кофейня']);
$travelAgency = jsonld_make('TravelAgency', ['name' => 'Агентство']);
$trip = jsonld_make('TouristTrip', ['name' => 'Тур']);
In Blade Templates
<!-- Использование Blade-директивы -->
@jsonld($person)
<!-- Использование helper в выражении -->
{{ $article->render() }}
<!-- Построение inline -->
{{ JsonLd::person()->name('John')->render() }}
Getting Different Output Formats
$person = JsonLd::person()->name('John Doe');
// Рендер как HTML script tag (по умолчанию)
echo $person->render();
// Получить как JSON-строку
$json = $person->toJson();
// Получить как PHP-массив
$array = $person->toArray();
Entity Types
Person
Обязательные поля: name
Основные поля:
name- Полное имяemail- Email-адресjobTitle- Должностьurl- URL сайтаimage- URL изображения профиляtelephone- Телефонdescription- Биография или описаниеaffiliation- Связанная организацияaddress- Физический адрес
Organization
Обязательные поля: name
Основные поля:
name- Название организацииurl- URL сайтаlogo- URL логотипаdescription- Описание организацииemail- Контактный emailtelephone- Контактный телефонaddress- Физический адресlocation- Информация о местоположенииsameAs- Массив ссылок на соцсетиcontactPoint- Данные контактной точки
Article
Обязательные поля: headline, datePublished
Основные поля:
headline- Заголовок статьиdescription- Описание/анонс статьиimage- URL главного изображенияauthor- Person или Organization (см. Person/Organization)datePublished- Дата публикации (ISO 8601)dateModified- Дата последнего измененияurl- URL статьиarticleBody- Полный текст статьиkeywords- Ключевые словаpublisher- Организация-издательarticleSection- Раздел/категория статьи
Product
Обязательные поля: name
Основные поля:
name- Название товараdescription- Описание товараimage- URL изображения товараbrand- Бренд (Organization)price- ЦенаpriceCurrency- Код валюты (USD, EUR и т.д.)url- URL товараavailability- Статус наличияrating- Объект рейтингаreview- Объект отзываmanufacturer- Производитель (Organization)sku- Артикул товара
WebSite
Обязательные поля: name, url
Основные поля:
name- Название сайтаurl- URL сайтаdescription- Описание сайтаimage- Изображение сайтаlogo- URL логотипаlanguage- Код языкаpotentialAction- Действия (например SearchAction)copyrightHolder- Правообладательauthor- Автор сайта
LocalBusiness
Наследует все поля Organization. Представляет физическое местное заведение.
Обязательные поля: name
Основные поля (унаследованы от Organization):
name- Название заведенияurl- URL сайтаtelephone- Телефонemail- Emailaddress- Физический адресlogo- URL логотипаdescription- ОписаниеsameAs- Ссылки на соцсети
Специфичные поля:
openingHours- Часы работы (напримерMo-Fr 08:00-22:00)priceRange- Ценовой диапазон ($,$$,$$$и т.д.)geo- Географические координаты (@type: GeoCoordinates,latitude,longitude)paymentAccepted- Принимаемые способы оплаты (строка или массив)
TravelAgency
Наследует все поля LocalBusiness. Представляет туристическое агентство.
Обязательные поля: name
Специфичные поля:
areaServed- Обслуживаемые регионы (строка или массив)serviceType- Тип туристических услуг
TouristTrip
Представляет туристическую поездку/тур.
Обязательные поля: name
Основные поля:
name- Название тураdescription- Описание тураstartDate- Дата начала (ISO 8601)endDate- Дата окончания (ISO 8601)itinerary- Маршрут или программа тура (строка или массив)offers- Коммерческое предложение (напримерOffer)touristType- Целевая аудитория туристов (строка или массив)provider- Организатор тура (Organization,TravelAgencyили массив)
Validation
Пакет проверяет обязательные поля в строгом режиме (включен по умолчанию). При ошибках валидации выбрасывается ValidationException с детализацией по полям:
use Asmi\JsonLd\Exceptions\ValidationException;
try {
$person = JsonLd::person()->render(); // Отсутствует обязательное поле 'name'
} catch (ValidationException $e) {
$errors = $e->getErrors();
// ['name' => "Required field 'name' is missing."]
}
Отключить строгую валидацию:
// In config/jsonld.php
'strict' => false,
// Или временно
config(['jsonld.strict' => false]);
$person = JsonLd::person()->render(); // Исключение выброшено не будет
Пример вывода
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "John Doe",
"jobTitle": "Developer",
"email": "john@example.com"
}
</script>
С включенным pretty_print:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Person",
"name": "John Doe",
"jobTitle": "Developer",
"email": "john@example.com"
}
</script>
Testing
php vendor/bin/phpunit
# С coverage
php vendor/bin/phpunit --coverage-html coverage
Contributing
Подробности смотрите в CONTRIBUTING.md.
License
Лицензия MIT. Подробности в LICENSE.