9.10. Drupal Fields API. Drupal-velden in de database.
In dit artikel zullen we begrijpen hoe velden in Drupal werken, waarom ze nodig zijn en hoe velden helpen om snel sites te ontwikkelen in Drupal.
We hebben al eerder met velden gewerkt in de volgende artikelen:
7.5. Typen van het services-block met bootstrap kolommen
7.6. Isotope Gallery voor Drupal
7.7. Block met YouTube-video in Drupal
Nu gaan we begrijpen hoe het werkt. Laten we naar de bewerking van de velden van het Artikel-type inhoud gaan en een nieuw Link-veld toevoegen:
/admin/structure/types/manage/article/fields
Wanneer je een nieuw artikel maakt, heb je twee invoervelden voor URL's en tekstlinks:
Elke keer dat je een nieuw veld maakt via de beheerder, worden er twee tabellen in de database aangemaakt:
{entity_type}___field_name}
{entity_type}_revision___field_name}
Drupal ondersteunt revisies, dus alle gegevens worden ten minste één keer gedupliceerd, omdat de enige revisie de huidige revisie van je artikel is. Zo vereenvoudigen de velden en de hele Drupal Fields API het werken met de database. We maken gewoon velden via de beheerder, en Drupal maakt automatisch tabellen aan in de database.
Uit de naam van de MySQL-tabellen zou het duidelijk moeten zijn dat hetzelfde veld voor één type entiteit kan worden gebruikt. Zo kunnen we bijvoorbeeld nu het Link-veld gebruiken in de inhoud van het Basic Page-type als al bestaand:
/admin/structure/types/manage/page/fields/add-field
Maar als je een Link-veld in een blok wilt maken, moet je een nieuw veld aanmaken. Het is niet mogelijk om hetzelfde veld in entiteiten van verschillende typen te gebruiken. Laten we een Link-veld maken voor het Basic Block-type:
/admin/structure/block/block-content/manage/basic/fields/add-field
Zoals je kunt zien, is bij het aanmaken van een veld de keuze voor het Link-veld uit de bestaande velden niet beschikbaar, omdat Block en Node verschillende typen entiteiten zijn.
En net zoals bij knooppunten, zullen we twee tabellen hebben om de gegevens in het Link-veld voor blokken op te slaan:
block_content_revision__field_link en block_content__field_link.
Laten we nu begrijpen hoe Drupal gegevens van hetzelfde veld opslaat voor verschillende bundel-knooppunten. We hebben het Link-veld aangemaakt voor het Artikel-knooppunt-type, maar daarna hergebruiken we dit veld in het Basic Page-knooppunt-type. Voor het gemak is het het beste om de siteconfiguratie naar een map te uploaden en de bestanden te bekijken, maar je kunt de benodigde configuratie ook vinden via Adminer of PhpMyAdmin in de config-tabel:
Als je zoekt naar alle configuraties die het woord link bevatten:
SELECT * FROM `config` WHERE CONVERT(`name` USING utf8mb4) LIKE '%link%' LIMIT 50
Vinden we de volgende configuraties voor ons field_link veld:
field.field.block.block_content.basic.field_link
field.field.node.article.field_link
field.field.node.page.field_link
field.storage.block_content.field_link
field.storage.node.field_link
Voor elk entiteitstype maakt elk veld zijn eigen Field Storage-configuratie aan. Deze configuratie bepaalt hoe de gegevens in de tabellen {entity_type}__{field_name}, {entity_type}_revision__{field_name} worden opgeslagen. In ons geval zijn dit de tabellen block_content_field_link, block_content_revision_field_link, node__field_link, node_revision__field_link. Laten we nu kijken hoe de Link-module de gegevens opslaat. Laten we de Field Storage-configuratie voor het Link-veld openen:
uuid: dba847ef-f4d6-4462-a2ee-f642a007fca6
langcode: en
status: true
dependencies:
module:
- block_content
- link
id: block_content.field_link
field_name: field_link
entity_type: block_content
type: link
settings: { }
module: link
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
Laten we elke regel bekijken zodat duidelijk is wat er precies wordt opgeslagen in de Field Storage-configuratie.
uuid: dba847ef-f4d6-4462-a2ee-f642a007fca6
Dit is waar de Config ID wordt opgeslagen, uniek voor elke configuratie. Het is niet nodig om het veld handmatig aan te maken op staging als je het veld lokaal hebt aangemaakt en de configuratie hebt geüpload. Het veld wordt automatisch aangemaakt. Als je het veld verwijdert en de configuratie lokaal verwijdert, worden ook alle gegevens verwijderd na het importeren naar staging. Daarom, als je een veld op staging hebt aangemaakt, upload de configuraties en voeg ze toe aan git zodat je geen wijzigingen verliest.
langcode: en
Op meertalige sites worden voor verschillende versies van knooppunten voor verschillende talen in de velden-tabel alle gegevens voor alle talen opgeslagen, waarbij wordt aangegeven welke taal bepaalde gegevens gebruikt:
Ik heb dezelfde taal, dus de standaardtaal in de configuratie is dezelfde.
status: true
Een algemeen veld in alle configuratie-entiteiten is het statusveld dat aangeeft of deze entiteit is ingeschakeld of uitgeschakeld. De Field Storage-configuratie gebruikt de gemaakte configuratie-entiteit in Drupal, zie de FieldStorageConfig-klasse, die is afgeleid van ConfigEntityBase:
https://api.drupal.org/api/drupal/core!modules!field!src!Entity!
dependencies:
module:
- block_content
- link
Afhankelijkheden van toegevoegde modules. Aangezien we het Link-veld in blokken hebben gebruikt, hebben we de verplichte Block content-module.
id: block_content.field_link
De unieke naam van onze configuratie.
field_name: field_link
De machine-naam van het veld dat we hebben gemaakt, gebruikt door Drupal, zodat deze machine-naam bijvoorbeeld kan worden gebruikt bij het toegang krijgen tot het knooppuntobject $node->field_link->uri. Hoe we naar het veld van de entiteit verwijzen, zullen we in de volgende artikelen in detail begrijpen.
Entity_type: block_content
Welk type entiteit onze Field Storage-configuratie is.
type: link
Het veldtype van Drupal. We zullen ons eigen veldtype maken, maar nu moeten we alleen weten dat dit veldtype link is, gemaakt door de Link-module. Je kunt de klasse bekijken:
core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
Die wordt gebruikt in onze configuratie.
settings: { }
Hier slaan we de instellingen voor het veldtype op. Nu zijn ze leeg, maar bijvoorbeeld voor het body-veld is er een instelling om de teaser al dan niet weer te geven:
config/sync/field.field.block_content.basic.body.yml
settings:
display_summary: false
module: link
Een module die een link-veldtype heeft. Nu hebben we dezelfde module naam en veldtype link, maar ze kunnen verschillend zijn, bijvoorbeeld kan in één module meerdere veldtypen worden geïmplementeerd, zoals het geval is in de module DateTime:
core/modules/datetime/src/Plugin/Field/FieldType/DateTimeFieldItemList.php
core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php
locked: false
Geeft aan of het veld beschikbaar is voor bewerking. Dit betekent dat het veld kan worden ingesteld. Enige tijd geleden was bijvoorbeeld het Billing Information- en Shipping Information-veld in de Commerce-module vergrendeld, omdat het bestaan van dit veld verplicht was bij het gebruik van levering en belastingberekening.
cardinality: 1
Het aantal waarden dat voor één entiteit kan worden ingevoerd voor dit veld. We hebben één waarde geselecteerd, maar hier kan ook een ander nummer zijn zoals 2, 3, 5, enz. Voor een onbeperkt aantal waarden wordt cardinaliteit: -1 gebruikt.
translatable: true
Is dit veld vertaalbaar naar andere talen?
indexes: { }
Aanvullende SQL-indexen voor een betere zoekfunctie in dit veld. Dit is meestal nodig voor het configureren en optimaliseren van databasequery's.
persist_with_no_fields: false
Geeft aan of de Field Storage moet worden verwijderd als de velden uit alle entiteiten zijn verwijderd. Bijvoorbeeld, als we het veld uit Artikel en Basic Page verwijderen, wordt de Field Storage niet verwijderd.
custom_storage: false
Aangepaste opslag betekent dat we een speciale tabel hebben voor het opslaan van veldgegevens, niet {entity_type}__{field_name}. We zullen niets dergelijks gebruiken, maar soms is het handig voor integratie met andere systemen.
Laten we nu het bestand voor het link-veldtype openen:
core/modules/link/src/Plugin/Field/FieldType/LinkItem.php
En laten we kijken welke gegevens dit veld in de database opslaat. Dit kan worden gezien in de methode propertyDefinitions():
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties['uri'] = DataDefinition::create('uri')
->setLabel(t('URI'));
$properties['title'] = DataDefinition::create('string')
->setLabel(t('Link text'));
$properties['options'] = MapDataDefinition::create()
->setLabel(t('Options'));
return $properties;
}
Zoals je kunt zien, slaan we URI, Title, Options-gegevens op. Als je de node__field_link-tabel opent, zie je dezelfde velden:
Nu zijn we aangekomen bij het onderwerp van de Fields API in Drupal. We maken een veldtype via een module in een PHP-bestand met de LinkItem-klasse. Dit stelt ons in staat om een veld voor een entiteit te maken en vervolgens kunnen we het gebruiken om gegevens in te voeren en deze gegevens in de database op te slaan. Dit is het geval bij gegevensinvoer. De Fields API configureert ook het formulier voor gegevensinvoer en output voor onze velden.
Laten we teruggaan naar het moment waarop we de velden voor de Article- en Basic Page-inhoudstypen maken. We hebben één configuratiebestand voor de Field Storage in de Node: field.storage.node.field_link.yml, maar ook bij het maken van het veld maken we nog een configuratiebestand voor elke bundel in de Entiteit, dus we hebben nu drie configuratiebestanden voor het veld:
field.field.node.article.field_link.yml
field.field.node.page.field_link.yml
field.field.block.block_content.basic.field_link.yml
Deze configuraties slaan de gegevens op van het veldinstellingenformulier:
Op deze manier kunnen we het formulier voor gegevensinvoer voor het veld op verschillende manieren aanpassen voor verschillende Bundles. Elke afzonderlijke veldconfiguratie in een Bundle wordt een Field Instance genoemd in Drupal, dus we maken eerst een Field Storage-veld aan dat in Field Instance afzonderlijk in elke bundel kan worden gebruikt. In Drupal 8, in tegenstelling tot Drupal 7, zijn er geen functies meer voor het werken met Field Instances, en de functionaliteit voor het werken met instanties is gemigreerd naar de CRUD API:
https://www.drupal.org/node/2054619
Voorbeelden van het werken met velden via de code kun je zien in de officiële documentatie:
https://www.drupal.org/node/2012896
We hebben alleen het deel van de Fields API bekeken dat betrekking heeft op de opslag van veldgegevens in de database. In de volgende lessen zullen we bekijken hoe de Fields API werkt met gegevensinvoer en de uitvoer van veldgegevens, en ook ons eigen volledig veldtype maken.