Il campo di testo su più righe è un tipo di dati Frammenti di contenuto che consente agli autori di creare contenuto in formato Rich Text. I riferimenti ad altri contenuti, come immagini o altri frammenti di contenuto, possono essere inseriti dinamicamente in linea all’interno del flusso del testo. Il campo di testo a riga singola è un altro tipo di dati Frammenti di contenuto che deve essere utilizzato per elementi di testo semplici.
L’API GraphQL dell’AEM offre una solida funzionalità per restituire il testo RTF come HTML, testo normale o come JSON puro. La rappresentazione JSON è potente in quanto offre all’applicazione client il controllo completo su come eseguire il rendering del contenuto.
Nell’Editor frammento di contenuto, la barra dei menu del campo di testo su più righe fornisce agli autori funzionalità di formattazione RTF standard, ad esempio grassetto, corsivo e sottolineano. L’apertura del campo su più righe in modalità a schermo intero consente di strumenti di formattazione aggiuntivi come Tipo di paragrafo, Trova e sostituisci, Controllo ortografico e altro ancora.
I plug-in Rich Text nell’editor multiriga non possono essere personalizzati.
Utilizza il Testo su più righe tipo di dati durante la definizione del modello per frammenti di contenuto per abilitare l’authoring di testo RTF.
È possibile configurare diverse proprietà del campo su più righe.
Il Rendering come può essere impostata su:
Il Tipo predefinito può essere impostato su:
Il Tipo predefinito influisce direttamente sull’esperienza di modifica e determina se sono presenti gli strumenti rich text.
È inoltre possibile abilita riferimenti in linea ad altri frammenti di contenuto selezionando la Consenti riferimento frammento e la configurazione Modelli per frammenti di contenuto consentiti.
Controlla la Traducibile , se il contenuto deve essere localizzato. È possibile localizzare solo testo formattato e testo normale. Consulta utilizzo dei contenuti localizzati per ulteriori dettagli.
Durante la creazione di una query GraphQL, gli sviluppatori possono scegliere tipi di risposta diversi da html
, plaintext
, markdown
, e json
da un campo con più righe.
Gli sviluppatori possono utilizzare Anteprima JSON nell’editor dei frammenti di contenuto per mostrare tutti i valori del frammento di contenuto corrente che possono essere restituiti utilizzando l’API GraphQL.
Selezione del json
il formato di risposta per il campo su più righe offre la massima flessibilità quando si lavora con contenuti rich text. Il contenuto Rich Text viene distribuito come array di tipi di nodo JSON che possono essere elaborati in modo univoco in base alla piattaforma client.
Di seguito è riportato un tipo di risposta JSON di un campo con più righe denominato main
che contiene un paragrafo: "Questo paragrafo include importantecontenuto." dove "importante" è contrassegnato come grassetto.
query ($path: String!) {
articleByPath(_path: $path)
{
item {
_path
main {
json
}
}
}
}
Il $path
variabile utilizzata nel _path
il filtro richiede il percorso completo del frammento di contenuto (ad esempio /content/dam/wknd/en/magazine/sample-article
).
Risposta GraphQL:
{
"data": {
"articleByPath": {
"item": {
"_path": "/content/dam/wknd/en/magazine/sample-article",
"main": {
"json": [
{
"nodeType": "paragraph",
"content": [
{
"nodeType": "text",
"value": "This is a paragraph that includes "
},
{
"nodeType": "text",
"value": "important",
"format": {
"variants": [
"bold"
]
}
},
{
"nodeType": "text",
"value": " content. "
}
]
}
]
}
}
}
}
}
Di seguito sono riportati diversi esempi di tipi di risposta di un campo con più righe denominato main
che contiene un paragrafo: "Questo è un paragrafo che include importante contenuti." dove "importante" è contrassegnato come grassetto.
Query persistente GraphQL:
query ($path: String!) {
articleByPath(_path: $path)
{
item {
_path
main {
html
}
}
}
}
Risposta GraphQL:
{
"data": {
"articleByPath": {
"item": {
"_path": "/content/dam/wknd/en/magazine/sample-article",
"main": {
"html": "<p>This is a paragraph that includes <b>important</b> content. </p>\n"
}
}
}
}
}
Query persistente GraphQL:
query ($path: String!) {
articleByPath(_path: $path)
{
item {
_path
main {
markdown
}
}
}
}
Risposta GraphQL:
{
"data": {
"articleByPath": {
"item": {
"_path": "/content/dam/wknd/en/magazine/sample-article",
"main": {
"markdown": "This is a paragraph that includes **important** content. \n\n ",
}
}
}
}
}
Query persistente GraphQL:
query ($path: String!) {
articleByPath(_path: $path)
{
item {
_path
main {
plaintext
}
}
}
}
Risposta GraphQL:
{
"data": {
"articleByPath": {
"item": {
"_path": "/content/dam/wknd/en/magazine/sample-article",
"main": {
"plaintext": "This is a paragraph that includes important content. ",
}
}
}
}
}
Il plaintext
l’opzione di rendering elimina la formattazione.
La risposta JSON Rich Text del campo su più righe è strutturata come una struttura gerarchica. Ogni oggetto o nodo rappresenta un diverso blocco HTML del testo RTF.
Di seguito è riportato un esempio di risposta JSON di un campo di testo su più righe. Ogni oggetto o nodo include un nodeType
che rappresenta il blocco HTML dal testo RTF come paragraph
, link
, e text
. Ogni nodo contiene facoltativamente content
che è un sottoarray contenente qualsiasi elemento secondario del nodo corrente.
"json": [// root "content" or child nodes
{
"nodeType": "paragraph", // node for a paragraph
"content": [ // children of current node
{
"nodeType": "text", // node for a text
"value": "This is the first paragraph. "
},
{
"nodeType": "link",
"data": {
"href": "http://www.adobe.com"
},
"value": "An external link"
}
],
},
{
"nodeType": "paragraph",
"content": [
{
"nodeType": "text",
"value": "This is the second paragraph."
},
],
},
]
Il modo più semplice per eseguire il rendering di più righe json
la risposta consiste nell'elaborare ogni oggetto, o nodo, nella risposta e quindi gli eventuali elementi secondari del nodo corrente. È possibile utilizzare una funzione ricorsiva per scorrere la struttura JSON.
Di seguito è riportato un codice di esempio che illustra un approccio trasversale ricorsivo. Gli esempi sono basati su JavaScript e utilizzano React JSXTuttavia, i concetti di programmazione possono essere applicati a qualsiasi linguaggio.
// renderNodeList - renders a list of nodes
function renderNodeList(childNodes) {
if(!childNodes) {
// null check
return null;
}
return childNodes.map(node, index) => {
return renderNode(node);
}
}
renderNodeList
è una funzione ricorsiva che accetta un array di childNodes
. Ogni nodo nell’array viene quindi passato a una funzione renderNode
, che a sua volta chiama renderNodeList
se il nodo ha elementi secondari.
// renderNode - renders an individual node
function renderNode(node) {
// if the current node has children, recursively process them
const children = node.content ? renderNodeList(node.content) : null;
// use a map to render the current node based on its nodeType
return nodeMap[node.nodeType]?.(node, children);
}
Il renderNode
La funzione prevede un singolo oggetto denominato node
. Un nodo può avere elementi secondari elaborati in modo ricorsivo utilizzando renderNodeList
funzione descritta in precedenza. Infine, un’ nodeMap
viene utilizzato per eseguire il rendering del contenuto del nodo in base ai nodeType
.
// nodeMap - object literal that maps a JSX response based on a given key (nodeType)
const nodeMap = {
'paragraph': (node, children) => <p>{children}</p>,
'link': node => <a href={node.data.href} target={node.data.target}>{node.value}</a>,
'text': node => node.value,
'unordered-list': (node, children) => <ul>{children}</ul>,
'ordered-list': (node, children) => <ol>{children}</ol>,
'list-item': (node, children) => <li>{children}</li>,
...
}
Il nodeMap
è un valore letterale di oggetto JavaScript utilizzato come mappa. Ognuna delle "chiavi" rappresenta una nodeType
. Parametri di node
e children
può essere trasmesso alle funzioni risultanti che eseguono il rendering del nodo. Il tipo restituito utilizzato in questo esempio è JSX, tuttavia l’approccio potrebbe essere adattato per creare una stringa letterale che rappresenta il contenuto HTML.
Un'utilità di rendering Rich Text riutilizzabile è disponibile nel Esempio di reazione WKND GraphQL.
mapJsonRichText
. Questa utility può essere utilizzata dai componenti che desiderano eseguire il rendering di una risposta JSON Rich Text come React JSX.mapJsonRichText
per il rendering del testo RTF e di tutti i riferimenti.Il campo Multiriga consente agli autori di inserire immagini o altre risorse digitali da AEM Assets nel flusso del testo RTF.
La schermata precedente rappresenta un’immagine inserita nel campo su più righe utilizzando Inserisci risorsa pulsante.
È inoltre possibile collegare o inserire nel campo su più righe riferimenti ad altri frammenti di contenuto utilizzando Inserisci frammento di contenuto pulsante.
La schermata precedente mostra un altro frammento di contenuto, Ultimate Guide to LA Skate Parks, inserito nel campo su più righe. I tipi di frammenti di contenuto che possono essere inseriti nel campo sono controllati da Modelli per frammenti di contenuto consentiti configurazione in tipo di dati su più righe nel modello per frammenti di contenuto.
L’API di GraphQL consente agli sviluppatori di creare una query che include proprietà aggiuntive su eventuali riferimenti inseriti in un campo su più righe. La risposta JSON include un _references
oggetto che elenca queste proprietà aggiuntive. La risposta JSON offre agli sviluppatori il controllo completo su come eseguire il rendering dei riferimenti o dei collegamenti invece di dover trattare con HTML categorici.
Ad esempio, potrebbe essere utile:
src
valore.Utilizza il json
tipo restituito e include _references
durante la costruzione di una query GraphQL:
Query persistente GraphQL:
query ($path: String!) {
articleByPath(_path: $path, _assetTransform: { format: JPG, preferWebp: true })
{
item {
_path
main {
json
}
}
_references {
...on ImageRef {
_dynamicUrl
__typename
}
...on ArticleModel {
_path
author
__typename
}
}
}
}
Nella query precedente, il main
viene restituito come JSON. Il _references
L'oggetto include frammenti per la gestione di riferimenti di tipo ImageRef
o di tipo ArticleModel
.
Risposta JSON:
{
"data": {
"articleByPath": {
"item": {
"_path": "/content/dam/wknd/en/magazine/sample-article",
"main": {
"json": [
{
"nodeType": "paragraph",
"content": [
{
"nodeType": "text",
"value": "This is a paragraph that includes "
},
{
"nodeType": "text",
"value": "important",
"format": {
"variants": [
"bold"
]
}
},
{
"nodeType": "text",
"value": " content. "
}
]
},
{
"nodeType": "paragraph",
"content": [
{
"nodeType": "reference",
"data": {
"path": "/content/dam/wknd/en/activities/climbing/sport-climbing.jpg",
"mimetype": "image/jpeg"
}
}
]
},
{
"nodeType": "paragraph",
"content": [
{
"nodeType": "text",
"value": "Reference another Content Fragment: "
},
{
"nodeType": "reference",
"data": {
"href": "/content/dam/wknd/en/magazine/la-skateparks/ultimate-guide-to-la-skateparks",
"type": "fragment"
},
"value": "Ultimate Guide to LA Skateparks"
}
]
}
]
}
},
"_references": [
{
"_dynamicUrl": "/adobe/dynamicmedia/deliver/dm-aid--dd42d814-88ec-4c4d-b5ef-e3dc4bc0cb42/sport-climbing.jpg?preferwebp=true",
"__typename": "ImageRef"
},
{
"_path": "/content/dam/wknd/en/magazine/la-skateparks/ultimate-guide-to-la-skateparks",
"author": "Stacey Roswells",
"__typename": "ArticleModel"
}
]
}
}
}
La risposta JSON include dove è stato inserito il riferimento nel testo RTF con "nodeType": "reference"
. Il _references
L’oggetto include quindi ogni riferimento.
Per eseguire il rendering dei riferimenti in linea, l'approccio ricorsivo illustrato nella Rendering di una risposta JSON su più righe può essere espanso.
Dove nodeMap
è la mappa che esegue il rendering dei nodi JSON.
const nodeMap = {
'reference': (node, children) => {
// variable for reference in _references object
let reference;
// asset reference
if (node.data.path) {
// find reference based on path
reference = references.find( ref => ref._path === node.data.path);
}
// Fragment Reference
if (node.data.href) {
// find in-line reference within _references array based on href and _path properties
reference = references.find( ref => ref._path === node.data.href);
}
// if reference found, merge properties of reference and current node, then return render method of it using __typename property
return reference ? renderReference[reference.__typename]({...reference, ...node}) : null;
}
}
L'approccio di alto livello consiste nell'ispezionare ogni nodeType
è uguale a reference
nella risposta JSON a più righe. È quindi possibile chiamare una funzione di rendering personalizzata che include _references
oggetto restituito nella risposta di GraphQL.
Il percorso di riferimento in linea può quindi essere confrontato con la voce corrispondente nella _references
oggetto e un'altra mappa personalizzata renderReference
può essere chiamato.
const renderReference = {
// node contains merged properties of the in-line reference and _references object
'ImageRef': (node) => {
// when __typename === ImageRef
return <img src={node._dynamicUrl} alt={'in-line reference'} />
},
'ArticleModel': (node) => {
// when __typename === ArticleModel
return <Link to={`/article:${node._path}`}>{`${node.value}`}</Link>;
}
...
}
Il __typename
del _references
L’oggetto può essere utilizzato per mappare diversi tipi di riferimento a diverse funzioni di rendering.
Un esempio completo di scrittura di un renderer di riferimenti personalizzato è disponibile in AdventureDetail.js nell'ambito del Esempio di reazione WKND GraphQL.
Il video precedente utilizza _publishUrl
per eseguire il rendering del riferimento immagine. Preferisci invece _dynamicUrl
come spiegato nella procedure per le immagini ottimizzate per il web;
Il video precedente mostra un esempio end-to-end:
_references
utilizzato.