mixerapi / json-ld-view
CakePHP 的 JSON-LD 视图
Requires
- php: ^8.1
- cakephp/cakephp: ^5.0
- mixerapi/core: ^2.0
Requires (Dev)
- josegonzalez/dotenv: ^3.2
- phpunit/phpunit: ^10.0
README
CakePHP 的 JSON-LD 视图。更多信息请访问 MixerAPI.com。
安装
!!! info "" 如果已安装 MixerAPI,则可以跳过此步骤。
composer require mixerapi/json-ld-view bin/cake plugin load MixerApi/JsonLdView
或者,在 composer 安装后,您可以手动在您的应用程序中加载此插件。
# src/Application.php public function bootstrap(): void { // other logic... $this->addPlugin('MixerApi/JsonLdView'); }
设置
此插件的设置非常简单。只需加载 RequestHandler 组件并创建一个用于上下文和词汇的路由。然后创建一个 config/jsonld_config.php
配置文件(推荐)并在您的实体上实现 JsonLdDataInterface。
配置(推荐)
创建一个 config/jsonld_config。如果跳过此步骤,则将使用示例配置中列出的默认值。
RequestHandler
您的控制器必须使用 RequestHandler
组件。这通常在您的 AppController
中加载。在大多数情况下,这已经加载。
# src/Controller/AppController.php public function initialize(): void { parent::initialize(); $this->loadComponent('RequestHandler'); // other logic... }
路由
上下文路由显示实体的 JSON-LD 架构,而词汇路由将显示所有实体和附加元数据。
# config/routes.php $routes->scope('/', function (RouteBuilder $builder) { $builder->connect('/contexts/*', [ 'plugin' => 'MixerApi/JsonLdView', 'controller' => 'JsonLd', 'action' => 'contexts' ]); $builder->connect('/vocab', [ 'plugin' => 'MixerApi/JsonLdView', 'controller' => 'JsonLd', 'action' => 'vocab' ]); // ... other code });
现在您应该能够通过浏览到 /contexts/{entity-name}
来查看实体的 JSON-LD 架构。对于进一步定制,您可以复制 JsonLdController 到您的项目中。
路由扩展(可选)
如果您希望通过扩展请求 JSON-LD(例如,/index.jsonld
),则需要设置您的 config/routes.php
中的扩展,例如
# config/routes.php $routes->scope('/', function (RouteBuilder $builder) { $builder->setExtensions(['jsonld']); // ... other code });
使用
设置完成后,application/ld+json
类型的请求将自动渲染为 JSON-LD。
实体架构
此插件将基本类型(int、string、decimal 等)映射到其对应的 schema.org 值。例如,int
映射到 https://schema.org/Number
。您可以通过在 Table 类上定义适当的验证来改进映射。例如,具有 email
规则的字段将映射到 https://schema.org/email
。有关默认映射的完整列表,请参阅 MixerApi\JsonLdView\SchemaMapper
。
您还可以通过在您的应用程序实体上实现 MixerApi\JsonLdView\JsonLdDataInterface
来进一步自定义架构映射。
# App/Model/Entity/Film.php class Film extends Entity implements JsonLdDataInterface { // ...other code /** * This is the context URL that you defined in your routes during Setup. This is used to browse the schema * definitions and appears as `@context` when displaying collection or item results * * @return string */ public function getJsonLdContext(): string { return '/contexts/Film'; } /** * This is the Entities schema description and appears as `@type` when displaying collection or item results * * @return string */ public function getJsonLdType(): string { return 'https://schema.org/movie'; } /** * This is the Entities URL and appears as `@id` when displaying collection or item results * * @param EntityInterface $entity * @return string */ public function getJsonLdIdentifier(EntityInterface $entity): string { return '/films/' . $entity->get('id'); } /** * You can define custom schemas here. These definitions take precedence and will appear when browsing to the * entities context URL. You can simply return an empty array if you don't care to define a schema. * * @return \MixerApi\JsonLdView\JsonLdSchema[] */ public function getJsonLdSchemas(): array { return [ new JsonLdSchema('title','https://schema.org/name', 'optional description') new JsonLdSchema('description','https://schema.org/about') new JsonLdSchema('length','https://schema.org/duration') new JsonLdSchema('rating','https://schema.org/contentRating') new JsonLdSchema('release_year','https://schema.org/copyrightYear') ]; } }
集合
我们获取 @id
和 @context
属性,因为这些实体实现了 JsonLdDataInterface
。当然,此接口是可选的,并且在没有它的情况下数据将返回,但缺少上述属性。分页数据根据 Hydra PartialCollectionView 规范添加到 view
属性中。
#src/Controller/FilmsController.php public function index() { $this->request->allowMethod('get'); $actors = $this->paginate($this->Films, [ 'contain' => ['Languages'], ]); $this->set(compact('films')); $this->viewBuilder()->setOption('serialize', 'films'); }
示例
{ "@context": "/context/Film", "@id": "/films", "@type": "Collection", "pageItems": 20, "totalItems": 1, "view": { "@id": "/films", "@type": "PartialCollectionView", "next": "/films?page=2", "prev": "", "first": "", "last": "/films?page=50" }, "member": [ { "id": 1, "title": "ACADEMY DINOSAUR", "description": "A Epic Drama of a Feminist And a Mad Scientist who must Battle a Teacher in The Canadian Rockies", "modified": "2006-02-15T05:03:42+00:00", "language": { "id": 1, "name": "English", "@id": "/languages/1", "@type": "https://schema.org/Language", "@context": "/context/Language" }, "@id": "/films/1", "@type": "https://schema.org/Movie", "@context": "/context/Film" } ] }
项目
#src/Controller/LanguagesController.php public function view($id = null) { $this->request->allowMethod('get'); $languages = $this->Languages->get($id); $this->set('languages', $languages); $this->viewBuilder()->setOption('serialize', 'languages'); }
输出
{ "@id": "/languages/1", "@type": "https://schema.org/Language", "@context": "/context/Language", "id": 1, "name": "English" }
上下文
浏览到上下文路由将显示有关该实体的信息。要精细调整数据,您需要实现 JsonLdDataInterface。以 Film 实体为例,当浏览到 /contexts/Film
时,上下文看起来像这样
{ "@context": { "@vocab": "/vocab", "hydra": "http://www.w3.org/ns/hydra/core#", "title": "https://schema.org/name", "description": "https://schema.org/about", "length": "https://schema.org/duration", "rating": "https://schema.org/contentRating", "release_year": "https://schema.org/copyrightYear", "id": "https://schema.org/identifier", "language_id": "https://schema.org/Number", "rental_duration": "https://schema.org/Number", "rental_rate": "https://schema.org/Float", "replacement_cost": "https://schema.org/Float", "special_features": "https://schema.org/Text", "modified": "https://schema.org/DateTime" } }
词汇
实现 JsonLdDataInterface 的任何实体都将出现在您为词汇创建的路由中(例如,/vocab)
样本
{ "@contexts": { "@vocab": "/vocab", "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "xmls": "http://www.w3.org/2001/XMLSchema#", "owl": "http://www.w3.org/2002/07/owl#", "schema": "http://schema.org" }, "@id": "/vocab", "@type": "ApiDocumentation", "title": "API Documentation", "description": "", "supportedClass": [ { "@id": "https://schema.org/Language", "@type": "Class", "title": "Language", "supportedProperty": [ { "@type": "supportedProperty", "property": { "@id": "https://schema.org/name", "@type": "rdf:Property", "rdfs:label": "name", "domain": "https://schema.org/Language", "range": "xmls:char" }, "title": "name", "required": false, "readable": true, "writeable": true, "description": "" } ] } // ...and other items ] }
序列化
可选地,您可以使用 JsonSerializer
手动将数据序列化为 JSON-LD。示例
use MixerApi\JsonLdView\JsonSerializer; # json $json = (new JsonSerializer($data))->asJson(JSON_PRETTY_PRINT); // argument is optional # array $json = (new JsonSerializer($data))->getData(); # json-ld with pagination meta data use Cake\Http\ServerRequest; use Cake\View\Helper\PaginatorHelper; $json = (new JsonSerializer($data, new ServerRequest(), new PaginatorHelper()))->asJson();