web services https://drupaladicto.com/ es Enviar datos JSON desde Drupal 8 https://drupaladicto.com/snippet/enviar-datos-json-desde-drupal-8 <span class="field field--name-title field--type-string field--label-hidden">Enviar datos JSON desde Drupal 8</span> <div class="clearfix text-formatted field field--name-field-snippet-descripcion field--type-text-long field--label-above"> <div class="field__label">Descripción</div> <div class="field__item"><p>Este código convierte el contenido de un nodo a formato Json</p> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Dom, 16/04/2023 - 21:51</span> <div class="clearfix text-formatted field field--name-field-instrucciones field--type-text-long field--label-above"> <div class="field__label">Instrucciones</div> <div class="field__item"><ol dir="ltr"><li> <p>Crea el nodo con los campos que te interesa convertir a formato json</p> </li> <li> <p>Instala el módulo Devel para que puedas imprimir los valores de variables en tu twig usando KSM</p> </li> </ol></div> </div> <div class="clearfix text-formatted field field--name-field-codigo field--type-text-long field--label-hidden field__item"><pre> /** * Configura el Json para enviar al server */ $json_array = [ 'data' =&gt; [] ]; $nids = \Drupal::entityQuery('node') -&gt;condition('type', 'review') -&gt;execute(); $nodes = Node::loadMultiple($nids); foreach ($nodes as $node) { $json_array['data'][] = array( 'type' =&gt; $node-&gt;get('type')-&gt;target_id, 'id' =&gt; $node-&gt;get('nid')-&gt;value, 'attributes' =&gt; array( 'Campo 1' =&gt; $node-&gt;get('field_name_1')-&gt;target_id, 'Campo 2' =&gt; $node-&gt;get('field_name_2')-&gt;value, 'Title' =&gt; $node-&gt;get('title')-&gt;value, 'Campo 3' =&gt; $node-&gt;get('field_name_3')-&gt;value, ), ); } //ksm($data_to_server = new JsonResponse($json_array));</pre> </div> <div class="field field--name-field-snippet-paginador field--type-image field--label-above"> <div class="field__label">Paginador</div> <div class="field__item"> <img src="/sites/default/files/imagenes/snippets/snippet-pager_115.png" width="100" height="100" alt="Snippet | www.drupaladicto.com - Consultores especializados en Drupal y Symfony" title="Snippet | www.drupaladicto.com - Consultores especializados en Drupal y Symfony" loading="lazy" typeof="foaf:Image" class="img-fluid" /> </div> </div> <div class="field field--name-field-categoria-snippet field--type-entity-reference field--label-above"> <div class="field__label">Categoría</div> <div class="field__items"> <div class="field__item"><a href="/categoria/json" hreflang="es">json</a></div> <div class="field__item"><a href="/categoria/json-api" hreflang="es">json api</a></div> <div class="field__item"><a href="/categoria/servicios-web" hreflang="es">servicios web</a></div> <div class="field__item"><a href="/categoria/web-services" hreflang="es">web services</a></div> </div> </div> <div class="field field--name-field-portada-snippet field--type-entity-reference field--label-above"> <div class="field__label">Portada</div> <div class="field__item"><article class="media media--type-imagen media--view-mode-default"> </article> </div> </div> Sun, 16 Apr 2023 19:51:14 +0000 webmaster 428 at https://drupaladicto.com Drupal Headless con Nuxt.js | Conectando con Drupal (Parte 2) https://drupaladicto.com/curso/drupal-headless-vuejs/drupal-headless-con-nuxtjs-conectando-con-drupal-parte-2 <span class="field field--name-title field--type-string field--label-hidden">Drupal Headless con Nuxt.js | Conectando con Drupal (Parte 2)</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <style>#video-only-898 .play-btn:hover::after { border-left: 15px solid #1fd7d9; transform: scale(20); border-left: 15px solid #fff; } #video-only-898 .play-btn::before { border: 5px solid #1fd7d9; } #video-only-898 .play-btn { background: radial-gradient(#1fd7d9 50%, rgba(66, 109, 202, 0.4) 52%); }</style> <div class="paragraph paragraph--type--video-only paragraph--view-mode--default" id="vol-898"> <section id="video-only-898" class="about area-padding video-block-wrapper"> <div class="col video-box"> <div class="portada"> <img src="/sites/default/files/styles/diapositiva_1200x650/public/2023-07/portada-gratuito-grande_2.jpg?itok=8dBQYXT7" class="img-fluid" alt=""> <div class="field field--name-vo-youtube-video field--type-entity-reference field--label-visually_hidden"> <div class="field__label visually-hidden">Video de Youtube</div> <div class="field__item"><article class="media media--type-remote-video media--view-mode-diapositiva-1200x650"> <div class="field field--name-field-media-oembed-video field--type-string field--label-visually_hidden"> <div class="field__label visually-hidden">URL de Video remoto</div> <div class="field__item"><div class="modal micromodal-slide" id="modal-media-618-0-field-media-oembed-video" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-media-618-0-field-media-oembed-video-content"> <a class="modal__btn" data-micromodal-close aria-label="Close this dialog window">X</a> <main class="modal__content" id="modal-media-618-0-field-media-oembed-video-content"> <div class="videoWrapper"><iframe src="/media/oembed?url=https%3A//youtu.be/tI8jt0QnVXc&amp;max_width=0&amp;max_height=0&amp;hash=y-ySyKOjg1305z0_VOUg2A2RKCOdmYVgVoM-DQme9xc" frameborder="0" allowtransparency="" class="media-oembed-content" title="Time Value of Money"></iframe></div> </main> </div> </div> </div> <div><a class="myButton" data-micromodal-trigger="modal-media-618-0-field-media-oembed-video"><span class="btn play-btn">.</span></a></div> </div> </div> </article> </div> </div> </div> </div> </section> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1198" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><h2><strong>Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... <a href="https://youtu.be/tI8jt0QnVXc" target="_blank">HAZ CLIC AQUI</a></strong></h2> <p>      Ya que hemos aprendido cómo configurar Contenta CMS de Drupal, para que pueda escuchar nuestra API de Nuxt.js, es el momento de hacer lo mismo desde el otro lado.</p> <h2>   Paso 2 - Configuración de Nuxt.js</h2> <p>     Para obtener datos de la aplicación nuxtapp, usaremos la biblioteca de javascript axios y, específicamente, usaremos la biblioteca axios creada para Nuxt: @nuxt/axios. Si eres desarrollador de PHP, puedes pensar en axios como el Guzzle del mundo de JavaScript. En la <a href="/curso/conectando-nuxtjs-con-drupal-9-parte-1" target="_blank">Parte 1</a> de este artículo, cuando instalamos la aplicación mynuxt, extrajimos la biblioteca axios.</p> <h3>   Configuración Variables de entorno ( .env)</h3> <p>  Si queremos conectar <em><strong>nuxtapp</strong></em> con el backend de <em><strong>contenta-drupal</strong></em>, primero tendremos que informarle acerca de algunas variables de entorno, así sabrá hacia dónde podrá realizar las peticiones de datos que quiere obtener.</p> <p>  Dentro de nuestra aplicación <em><strong>nuxtapp</strong></em>, crearemos un archivo con el nombre <em><strong>.env </strong></em>y dentro pegaremos el siguiente código:</p> <pre> APP_ENV=lando API_URL=http://contenta-drupal.lndo.site/ CONSUMER_ID={{ Copiaremos aquí el ID Consumer de Drupal en //admin/con</pre> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 21.94%;" data-ratio="21.94" data-b-token="b-6125bee8493" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037c9ee4936.jpg?itok=oqZ5RJP4" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="556" height="122" typeof="foaf:Image" /></div></div> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 57.63%;" data-ratio="57.63" data-b-token="b-728dd0a4f78" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037cb756883.jpg?itok=_g86g0Lr" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="472" height="272" typeof="foaf:Image" /></div></div> <p>   Después de agregar este archivo, deberá reconstruir la aplicación nuxtapp,  para cargar las variables de entorno en los contenedores de la aplicación; para ello, colocados en la carpeta de nuestrra aplicación de Nuxt.js, ejecutaremos el siguiente comando:</p> <pre> lando rebuild</pre> <h3>Configuración de axios ( nuxt.config.js )</h3> <p>   A pesar de que hemos seleccionado la opción <em><strong>Axios</strong></em>, en el momento de realizar la descarga de las dependencias para nuxtapp, si abrimos el archivo de configuración, en el apartado de móldulos, sólo vemos <em><strong>bootstrap-vue/nuxt</strong></em>, al igual que si exploramos la carpeta <em><strong>node_modules</strong></em>, por lo tanto tendremos que <a href="https://axios.nuxtjs.org/setup">descargar axios</a> y luego añadirlo en el listado de módulos dentro del archivo <em><strong>nuxt.config.js</strong></em>.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 51.16%;" data-ratio="51.16" data-b-token="b-773f5e9565e" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037cf8f07df.png?itok=Uyb0jhIm" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="559" height="286" typeof="foaf:Image" /></div></div> <p>Para ello, nos aseguraremos de estar en la carpeta <em><strong>nuxtapp</strong></em> y ejecutaremos el siguiente comando para que se descarguen los archivos de axios:</p> <pre cb=""> <code cb="">lando yarn add @nuxtjs/axios</code></pre> <p><code cb=""> </code></p> <p><code cb=""><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 56.15%;" data-ratio="56.15" data-b-token="b-b908a78a34f" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037d1d3d095.png?itok=EYJvGcK-" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="577" height="324" typeof="foaf:Image" /></div></div> </code></p> <p><code cb="">   Una vez descargado, abriremos el archivo de configuración de Nuxt.js llamado <em><strong>nuxt.config.js</strong></em> y en el apartado de módulos, sutituiremos el código actual por el siguiente:</code></p> <pre> <code cb=""> // Modules: https://go.nuxtjs.dev/config-modules modules: [ // Doc: https://axios.nuxtjs.org/usage '@nuxtjs/axios', // https://go.nuxtjs.dev/bootstrap 'bootstrap-vue/nuxt', ], /* ** Axios module configuration */ axios: { // See https://github.com/nuxt-community/axios-module#options debug: process.env.APP_ENV !== "production" },</code></pre> <p><code cb="">   Para ver todas las opciones disponibles puedes leer la URL en el comentario. Para nuestros propósitos, activaremos la depuración con la advertencia de que nuestro APP_ENV no es producción.</code></p> <h3><code cb="">   Configuración de la ( baseURL )</code></h3> <p><code cb="">     También en el archivo <em><strong>nuxt.config.js</strong></em>, agregaremos un bloque de código <em><strong>env</strong></em> para configurar la baseURL que indica a <em><strong>axios</strong></em> dónde realizar las llamadas API a Contenta. En la parte inferior del archivo, después de la sección <em><strong>build</strong></em>, agregue las siguientes líneas:</code></p> <pre> <code cb=""> // Build Configuration: https://go.nuxtjs.dev/config-build build: { }, env: { baseURL: process.env.API_URL, CONSUMER_ID: process.env.CONSUMER_ID }</code></pre> <p><code cb="">      Después de realizar cambios en los archivos <em><strong>.env</strong></em> o <em><strong>nuxt.config.js</strong></em>, deberá reconstruir la aplicación Lando <em><strong>lando rebuild -y</strong></em> para permitir que la aplicación <em><strong>nuxtapp</strong></em> cargue esos cambios.</code></p> <pre> <code cb=""> lando rebuild -y</code></pre> <p><code cb="">   ¡Eso configura nuestra configuración de axios para que ahora podamos realizar solicitudes desde nuestra aplicación mynuxt de regreso a Contenta <em><strong>nuxtapp</strong></em>!</code></p> <h3><code cb="">   Hacer una llamada a la API</code></h3> <p><code cb="">     Hagamos una ruta de página llamada <em><strong>posts</strong></em> con un archivo<em><strong> index.vue</strong></em> para volver a consultar a Contenta en busca de una publicación. Agregué un tipo de contenido a Contenta con el nombre de la máquina <em><strong>post</strong></em> y consultaré el endpoint <em><strong>/api/node/post/{uuid}</strong></em> para los datos json.</code></p> <p><code cb=""><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 90.7%;" data-ratio="90.7" data-b-token="b-17c1f6242bc" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037d3f96191.png?itok=7ybKe9f3" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="559" height="507" typeof="foaf:Image" /></div></div> </code></p> <p><code cb=""><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 88.57%;" data-ratio="88.57" data-b-token="b-af678aaf7be" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037d5c06823.png?itok=lY4jleIn" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="315" height="279" typeof="foaf:Image" /></div></div> </code></p> <p><code cb=""><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 58.4%;" data-ratio="58.4" data-b-token="b-682f716f981" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037d71a0f88.png?itok=8zQl8kfO" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="589" height="344" typeof="foaf:Image" /></div></div> </code></p> <p><code cb=""><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 33.83%;" data-ratio="33.83" data-b-token="b-fb1cb3330c4" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037d85630da.png?itok=MJuBczPQ" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="535" height="181" typeof="foaf:Image" /></div></div> </code></p> <p><code cb="">   En Nuxt hay un directorio <em><strong>pages</strong></em> y todo lo que pongas en él, Nuxt creará automáticamente rutas Vue para nosotros. En este caso, crearemos un directorio <em><strong>posts</strong></em> dentro del directorio de páginas:</code></p> <pre> <code cb=""> sudo mkdir pages/posts</code></pre> <p><code cb="">   Entonces deberías terminar con una estructura de directorios como esta:</code></p> <p><code cb=""><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 94.14%;" data-ratio="94.14" data-b-token="b-b9e651e96f1" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037d9f89ca6.png?itok=_XidhCWs" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="273" height="257" typeof="foaf:Image" /></div></div> </code></p> <p><code cb="">   Observe la estructura del archivo <em><strong>pages/posts/index.vue</strong></em>. Tiene tres secciones: <em><strong>&lt;template&gt;</strong></em>, <em><strong>&lt;script&gt;</strong></em> y <em><strong>&lt;style&gt;</strong></em>. Como probablemente pueda adivinar, la sección <em><strong>&lt;template&gt;</strong></em> contendrá nuestro html, <em><strong>&lt;script&gt;</strong></em> contendrá nuestro javascript y <em><strong>&lt;style&gt;</strong></em> contendrá nuestro css.</code></p> <p><code cb="">   Ahora añadiremos algunos datos para nuestra plantilla. En la sección <em><strong>&lt;script&gt;</strong></em> de <em><strong>pages/posts/index.vue</strong></em>, agreguemos una función <em><strong>data()</strong></em> para que la plantilla sepa qué datos esperamos. En este caso, nuestro tipo de contenido <em><strong>posts</strong></em> consta de los campos <em><strong>title</strong></em> y <em><strong>body. </strong></em>Abriremos <em><strong>pages/posts/index.vue</strong></em> en nuestro editor de código. En la sección <em><strong>&lt;scripts&gt;</strong></em> y a continuación, agregaremos la función <em><strong>data()</strong></em>:</code></p> <pre> <code cb=""> &lt;template&gt; &lt;section class="container"&gt; &lt;/section&gt; &lt;/template&gt; &lt;script&gt; export default { components: {}, data() { return { title: "PLACEHOLDER TITLE", body: "PLACEHOLDER CONTENT ipsumm dolorem de la sol PLACEHOLDER CONTENT" } } } &lt;/script&gt; &lt;style scoped&gt; &lt;/style&gt;</code></pre> <p><code cb="">   Ahora nuestra sección<em><strong>&lt;template&gt;</strong></em> tiene acceso a <em><strong>data()</strong></em> y podemos comenzar a construir nuestra plantilla. Agregue a la sección de su plantilla referencias a los marcadores de posición para el <em><strong>title</strong></em> y el <em><strong>body</strong></em>:</code></p> <pre> <code cb=""> &lt;template&gt; &lt;b-container&gt; &lt;b-row&gt; &lt;b-col xl="12"&gt; &lt;h1&gt;{{ title }}&lt;/h1&gt; &lt;/b-col&gt; &lt;/b-row&gt; &lt;b-row&gt; &lt;b-col&gt; &lt;div class="posts__body" v-html="body" /&gt; &lt;/b-col&gt; &lt;/b-row&gt; &lt;/b-container&gt; &lt;/template&gt; &lt;script&gt; export default { components: {}, data() { return { title: 'PLACEHOLDER TITLE', body: 'PLACEHOLDER CONTENT ipsumm dolorem de la sol PLACEHOLDER CONTENT' } } } &lt;/script&gt; &lt;style scoped&gt; &lt;/style&gt;</code></pre> <p><code cb="">     En la línea 5, hemos hecho referencia a la clave <em><strong>title</strong></em> de nuestra función <em><strong>data()</strong></em> y hemos representado el contenido del marcador de posición predeterminado en nuestra plantilla. De manera similar, en la línea 12 hemos hecho referencia a la propiedad <em><strong>body,</strong></em> esta vez en una directiva vue <em><strong>v-html</strong></em>. Hemos usado <em><strong>v-html</strong></em> para demostrar el paso de datos que pueden contener html. Podríamos haberlo referenciado de la misma manera que hicimos referencia al título.</code></p> <p><code cb="">     Si ahora visitamos la url de nuestra aplicación: <em><strong>http://nuxtapp.lndo.site/posts</strong></em> deberíamos ver un resultado como el siguiente:</code></p> <p><code cb=""><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 32.26%;" data-ratio="32.26" data-b-token="b-d8ff468a515" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037dc06b473.png?itok=OjoaLXNR" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="620" height="200" typeof="foaf:Image" /></div></div> </code></p> <p><code cb="">Ahora reemplacemos los datos del marcador de posición con datos reales de <em><strong>contenta-drupal</strong></em>.</code></p> <p><code cb="">   Dentro de la sección <em><strong>&lt;script&gt;</strong></em> agregaremos una nueva función llamada asyncData que devolverá la llamada a nuestra aplicación <em><strong>contenta-drupal </strong></em>con llamadas <em><strong>asyncData</strong></em> y obtendremos los datos e intercambiará los datos del marcador de posición con datos reales.</code></p> <pre> <code cb=""> &lt;template&gt; &lt;b-container&gt; &lt;b-row&gt; &lt;b-col xl="12"&gt; &lt;h1&gt;{{ title }}&lt;/h1&gt; &lt;/b-col&gt; &lt;/b-row&gt; &lt;b-row&gt; &lt;b-col&gt; &lt;div class="posts__body" v-html="body" /&gt; &lt;/b-col&gt; &lt;/b-row&gt; &lt;/b-container&gt; &lt;/template&gt; &lt;script&gt; export default { components: {}, async asyncData({app}) { const data = await app.$axios .get('/api/node/post/c6b24529-0d69-4cbb-a966-ab2d6ac5a59b', {}) .then(res =&gt; { console.log(res) return { title: res.data.data.attributes.title, body: res.data.data.attributes.body.value } }) .catch(err =&gt; { if (err) { return err } }) return data } } &lt;/script&gt; &lt;style scoped&gt; &lt;/style&gt; </code></pre> <p><code cb="">   Aquí, en la línea 22, hemos cambiado la función <em><strong>data()</strong></em> por <em><strong>asyncData()</strong></em>. La función <em><strong>asyncData</strong></em> se pasa en el contexto de la aplicación que tiene acceso al objeto <em><strong>$axios</strong></em> a través del trabajo que hicimos en los archivos <em><strong>.env</strong></em> y <em><strong>nuxt.config.js</strong></em>. Usamos este objeto <em><strong>$axios</strong></em> para realizar una solicitud GET de regreso a <em><strong>contenta-drupal</strong></em> y obtener el nodo de publicación con uuid=c6b24529-0d69-4cbb-a966-ab2d6ac5a59b en este ejemplo que uuid está codificado para una publicación específica.</code></p> <p><code cb=""><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 48.46%;" data-ratio="48.46" data-b-token="b-985a5c6af38" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037de251d04.png?itok=11Cj8m2E" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="315" typeof="foaf:Image" /></div></div> </code></p> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 16/03/2023 - 12:01</span> Thu, 16 Mar 2023 11:01:56 +0000 webmaster 382 at https://drupaladicto.com Drupal Headless con Nuxt.js | Conectando con Drupal (Parte 1) https://drupaladicto.com/curso/drupal-headless-vuejs/drupal-headless-con-nuxtjs-conectando-con-drupal-parte-1 <span class="field field--name-title field--type-string field--label-hidden">Drupal Headless con Nuxt.js | Conectando con Drupal (Parte 1)</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <style>#video-only-897 .play-btn:hover::after { border-left: 15px solid #1fd7d9; transform: scale(20); border-left: 15px solid #fff; } #video-only-897 .play-btn::before { border: 5px solid #1fd7d9; } #video-only-897 .play-btn { background: radial-gradient(#1fd7d9 50%, rgba(66, 109, 202, 0.4) 52%); }</style> <div class="paragraph paragraph--type--video-only paragraph--view-mode--default" id="vol-897"> <section id="video-only-897" class="about area-padding video-block-wrapper"> <div class="col video-box"> <div class="portada"> <img src="/sites/default/files/styles/diapositiva_1200x650/public/2023-07/portada-gratuito-grande_2.jpg?itok=8dBQYXT7" class="img-fluid" alt=""> <div class="field field--name-vo-youtube-video field--type-entity-reference field--label-visually_hidden"> <div class="field__label visually-hidden">Video de Youtube</div> <div class="field__item"><article class="media media--type-remote-video media--view-mode-diapositiva-1200x650"> <div class="field field--name-field-media-oembed-video field--type-string field--label-visually_hidden"> <div class="field__label visually-hidden">URL de Video remoto</div> <div class="field__item"><div class="modal micromodal-slide" id="modal-media-617-0-field-media-oembed-video" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-media-617-0-field-media-oembed-video-content"> <a class="modal__btn" data-micromodal-close aria-label="Close this dialog window">X</a> <main class="modal__content" id="modal-media-617-0-field-media-oembed-video-content"> <div class="videoWrapper"><iframe src="/media/oembed?url=https%3A//youtu.be/weZZ9rQD1iw&amp;max_width=0&amp;max_height=0&amp;hash=4ooreB33p6wHkH2Zsy1_Qo0KPuGBfW8ftZX1AdUHVCs" frameborder="0" allowtransparency="" class="media-oembed-content" title="Time Value of Money"></iframe></div> </main> </div> </div> </div> <div><a class="myButton" data-micromodal-trigger="modal-media-617-0-field-media-oembed-video"><span class="btn play-btn">.</span></a></div> </div> </div> </article> </div> </div> </div> </div> </section> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1197" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><h2><strong>Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... <a href="https://youtu.be/weZZ9rQD1iw" target="_blank">HAZ CLIC AQUI</a></strong></h2> <p>     Ahora que hemos aprendido a instalar y configurar, utilizando Lando, una aplicación con Nuxt.js y la distribución optimizada para el sistema headless de Drupal 9, llamada Contenta CMS; es el momento de pasar a la siguiente fase, en la que conectaremos ambas aplicaciones para mostrar los datos servidos desde Drupal, en nuestra aplicación de Nuxt.js.</p> <h2>   Paso 1 - Configuración de Contenta CMS</h2> <p>     Como podrás ver en el capítulo sobre <a href="https://www.drupaladicto.com/curso/simple-oauth">Simple OAuth</a>, para que Drupal pueda escuchar las peticiones desde la API; primero tendremos que configurar tres partes, que nos permitirán realizar esa conexión:</p> <ul><li> <h3>Rol para la API:</h3>      La idea es crear un rol, al que le otorgaremos los permisos para relizar las conexiones con la API. Para ello, nos iremos a la url "/admin/people/roles" y allí, añadiremos un nuevo Rol, al que llamaremos <em><strong>vue_role, </strong></em>haciendo clic en el botón de añadir nuevo rol.<br />      Recuerda que Contenta CMS, es un Drupal "vitaminado", por lo que hay ciertas diferencias si queremos acceder a las secciones a través del menú de administración. En este caso, tendríamos que hacer clic en la opción del menú Advanced, luego en People y por último en Role, para encontrar el botón de <strong>Add Rol</strong>.</li> </ul><p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 31.08%;" data-ratio="31.08" data-b-token="b-ca82cf39fb4" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037a39a92d2.jpg?itok=pFXX5_Bt" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="202" typeof="foaf:Image" /></div></div> <h3>Configurar un usuario de API</h3> <p>     Lo siguiente que haremos es, después de haber creado el rol para nuestra API, tendremos que crear un nuevo usuario, al que le añadiremos el  <em><strong>vue_role</strong></em> que<em><strong> </strong></em>acabamos de crear, para esta operación, podremos ir a la url "/admin/people" o si preferimos hacerlo por el menú, al igual que en caso anterior, tendríamos que hacer clic en la opción del menú Advanced, luego en People y por último en Users, para encontrar el botón de <strong>Add user</strong>.<br />      En este caso, una vez hagamos clic en el botón para añadir a nuestro usuario, completaremos los campos necesarios como con cualquier otro usuario, le pondremos el nombre de usuario <strong>vue_user</strong>, y a continuación marcaremos el rol <em><strong>vue_role.</strong></em></p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 96.1%;" data-ratio="96.1" data-b-token="b-7eea740f374" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037a6a8aace.png?itok=nZ3FtLEx" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="282" height="271" typeof="foaf:Image" /></div></div> <h3>Configurar un consumidor</h3> <p>   El último eslabón de esta cadena de requermientos será el <strong>Consumer</strong>, que será quien nos permitirá realizar la conexión entre Contenta CMS y la API de Nuxt.js. Para ello, iremos a la url "<em><strong>/admin/config/services/consumer</strong></em>".<br />    O también podremos acceder a través del menú de administración, esta vez, tal y como lo haríamos desde un Drupal normal y corriente.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 78.76%;" data-ratio="78.76" data-b-token="b-670bec31497" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037a8c395cf.jpg?itok=pgvVSREb" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="466" height="367" typeof="foaf:Image" /></div></div> <p>   Esta vez, al hacer clic en el botón de Add Consumer, nos aseguraremos de rellenar los campos del formulario con el nombre <em><strong>vue_consumer</strong></em>, para el Consumer, el usuario será <em><strong>vue_user</strong></em> y el rol será <em><strong>vue_role</strong></em>. Asegúrate de aprenderte o dejar apuntado el <em><strong>New Secret</strong></em>, porque será la clave que necesitarás en caso de conectarme con el Consumer, en algunos Headless, como por ejemplo, con <em><strong>Gatsby</strong></em>.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 128.11%;" data-ratio="128.11" data-b-token="b-0fe07629c66" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Drupal 9 headless Nuxt.js | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-63037ab10e9a0.jpg?itok=xdq8Q6kA" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="466" height="597" typeof="foaf:Image" /></div></div> <p>Fantástico, una vez rellenado el formulario, haz clic en guardar para concluir la configuración de nuestra API Drupal Contenta CMS.<br /> A continuación, vamos a configurar la otra parte de este proyecto, o sea, nuestra aplicación de Nuxt.js.</p> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 16/03/2023 - 11:57</span> Thu, 16 Mar 2023 10:57:00 +0000 webmaster 381 at https://drupaladicto.com Drupal 9 Headless con Vue.js | Requerimientos https://drupaladicto.com/curso/drupal-headless-vuejs/drupal-9-headless-con-vuejs-requerimientos <span class="field field--name-title field--type-string field--label-hidden">Drupal 9 Headless con Vue.js | Requerimientos</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--bloque-parrafo paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-field-textos-curso field--type-text-long field--label-hidden field__item"><p>     Para poder realizar este curso, será necesario cumplir previamente con varios de los requerimientos de instalación del proyecto; estos son:</p> <ol><li>Tener instalado y funcionando un proyecto Drupal. <a href="/actualidad/instalar-drupal-9-en-ubuntu-2004-con-lando-y-wsl2-en-windows-11" target="_blank">HAZ CLIC AQUI</a><br />  </li> <li>Tener conocimientos básicos de Nuxtjs, para realizar el curso <a href="/curso/curso-intensivo-nuxtjs" target="_blank">HAZ CLIC AQUI</a><br />  </li> <li>Descargar, activar y configurar el módulo de autenticación Simple Oauth. <a href="/curso/webservices/simple-oauth" target="_blank">HAZ CLIC AQUI</a></li> </ol><p>     Una vez hayas completado estos requermientos, podrás continuar con el resto del curso siguiendo los pasos de los siguientes capítulos.</p> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 09/03/2023 - 17:52</span> Thu, 09 Mar 2023 16:52:00 +0000 webmaster 361 at https://drupaladicto.com Drupal 9 Headless con Vue.js | Presentación https://drupaladicto.com/curso/drupal-headless-vuejs/drupal-9-headless-con-vuejs-presentacion <span class="field field--name-title field--type-string field--label-hidden">Drupal 9 Headless con Vue.js | Presentación</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <style>#video-only-886 .play-btn:hover::after { border-left: 15px solid #1fd7d9; transform: scale(20); border-left: 15px solid #fff; } #video-only-886 .play-btn::before { border: 5px solid #1fd7d9; } #video-only-886 .play-btn { background: radial-gradient(#1fd7d9 50%, rgba(66, 109, 202, 0.4) 52%); }</style> <div class="paragraph paragraph--type--video-only paragraph--view-mode--default" id="vol-886"> <section id="video-only-886" class="about area-padding video-block-wrapper"> <div class="col video-box"> <div class="portada"> <img src="/sites/default/files/styles/diapositiva_1200x650/public/2023-07/portada-gratuito-grande_2.jpg?itok=8dBQYXT7" class="img-fluid" alt=""> <div class="field field--name-vo-youtube-video field--type-entity-reference field--label-visually_hidden"> <div class="field__label visually-hidden">Video de Youtube</div> <div class="field__item"><article class="media media--type-remote-video media--view-mode-diapositiva-1200x650"> <div class="field field--name-field-media-oembed-video field--type-string field--label-visually_hidden"> <div class="field__label visually-hidden">URL de Video remoto</div> <div class="field__item"><div class="modal micromodal-slide" id="modal-media-606-0-field-media-oembed-video" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-media-606-0-field-media-oembed-video-content"> <a class="modal__btn" data-micromodal-close aria-label="Close this dialog window">X</a> <main class="modal__content" id="modal-media-606-0-field-media-oembed-video-content"> <div class="videoWrapper"><iframe src="/media/oembed?url=https%3A//youtu.be/qE_mf3mkXNg&amp;max_width=0&amp;max_height=0&amp;hash=iWHGfa2xjq1IYEBqRUSaAzT6o64wDyLHiz2_yCxeupY" frameborder="0" allowtransparency="" class="media-oembed-content" title="Time Value of Money"></iframe></div> </main> </div> </div> </div> <div><a class="myButton" data-micromodal-trigger="modal-media-606-0-field-media-oembed-video"><span class="btn play-btn">.</span></a></div> </div> </div> </article> </div> </div> </div> </div> </section> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--bloque-parrafo paragraph--view-mode--default"> <div class="clearfix text-formatted field field--name-field-textos-curso field--type-text-long field--label-hidden field__item"><h2><strong>Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... <a href="https://youtu.be/qE_mf3mkXNg" target="_blank">HAZ CLIC AQUI</a></strong></h2> <p>     Al final de este curso, tendrás los conocimientos básicos para instalar un proyecto desacoplado (Headless), utilizando Nuxt.js para el frontend o presentación de tus datos, extraídos desde Drupal 9, que se encargará del backend.</p> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 09/03/2023 - 17:39</span> Thu, 09 Mar 2023 16:39:40 +0000 webmaster 359 at https://drupaladicto.com Drupal 9 Headless con Vue.js en Windows 11 https://drupaladicto.com/curso/drupal-9-headless-con-vuejs-en-windows-11-resumen <span class="field field--name-title field--type-string field--label-hidden">Drupal 9 Headless con Vue.js en Windows 11 </span> <div class="field field--name-field-portada-ce field--type-entity-reference field--label-hidden field__item"><article class="media media--type-imagen media--view-mode-default"> <div class="field field--name-field-media-image field--type-image field--label-visually_hidden"> <div class="field__label visually-hidden">Imagen</div> <div class="field__item"><svg xmlns="http://www.w3.org/2000/svg" id="a" viewBox="0 0 650 650"> <rect y="0" width="650" height="650" style="fill:#054065; stroke:#1d1d1b; stroke-miterlimit:10;"></rect> <text transform="translate(183.61 309.27)" style="fill:#fff; font-family:Montserrat-Light, Montserrat; font-size:99.05px; font-weight:300;"> <tspan x="0" y="0" style="letter-spacing:-.02em;">C</tspan> <tspan x="69.04" y="0">u</tspan> <tspan x="135.3" y="0" style="letter-spacing:0em;">r</tspan> <tspan x="174.03" y="0">so</tspan> <tspan x="-58.14" y="90">G</tspan> <tspan x="18.42" y="90" style="letter-spacing:-.05em;">r</tspan> <tspan x="52.69" y="90">atui</tspan> <tspan x="241.97" y="90" style="letter-spacing:-.02em;">t</tspan> <tspan x="279.51" y="90">o</tspan> </text> </svg></div> </div> </article> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 09/03/2023 - 17:34</span> <div class="clearfix text-formatted field field--name-field-descripcion-ce field--type-text-long field--label-hidden field__item"><p>En este curso, explicaremos los conceptos básicos para que puedas instalar en local, un Drupal Headless usando el Framework de javascript Nuxt.js, como de costubre, trabajaremos con LANDO, WSL2 en Windows 11</p> </div> <div class="field field--name-field-tipo-ce field--type-list-string field--label-hidden field__item">Curso Gratuito</div> <div class="field field--name-field-suscribete-youtube field--type-link field--label-hidden field__item"><a href="https://www.youtube.com/drupaladicto">Suscríbete al canal</a></div> <div class="field field--name-field-categoria-ce field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><a href="/categoria/json" hreflang="es">json</a></div> <div class="field__item"><a href="/categoria/api" hreflang="es">api</a></div> <div class="field__item"><a href="/categoria/json-api" hreflang="es">json api</a></div> <div class="field__item"><a href="/categoria/headless" hreflang="es">headless</a></div> <div class="field__item"><a href="/categoria/gatsby" hreflang="es">gatsby</a></div> <div class="field__item"><a href="/categoria/code" hreflang="es">code</a></div> <div class="field__item"><a href="/categoria/codigo" hreflang="es">código</a></div> <div class="field__item"><a href="/categoria/codigos" hreflang="es">códigos</a></div> <div class="field__item"><a href="/categoria/script" hreflang="es">script</a></div> <div class="field__item"><a href="/categoria/servicios-web" hreflang="es">servicios web</a></div> <div class="field__item"><a href="/categoria/web-services" hreflang="es">web services</a></div> <div class="field__item"><a href="/categoria/programacion" hreflang="es">programacion</a></div> <div class="field__item"><a href="/categoria/javascript" hreflang="es">javascript</a></div> <div class="field__item"><a href="/categoria/authentication" hreflang="es">authentication</a></div> <div class="field__item"><a href="/categoria/autenticacion" hreflang="es">autenticación</a></div> <div class="field__item"><a href="/categoria/usuarios" hreflang="es">usuarios</a></div> <div class="field__item"><a href="/categoria/users" hreflang="es">users</a></div> <div class="field__item"><a href="/categoria/frontend" hreflang="es">frontend</a></div> </div> <div class="field field--name-field-comenzar-curso field--type-string field--label-hidden field__item">/drupal-9-headless-con-vuejs-en-windows-11</div> Thu, 09 Mar 2023 16:34:14 +0000 webmaster 357 at https://drupaladicto.com JSON API | Desacoplamiento de Drupal 9 https://drupaladicto.com/curso/webservices/json-api-desacoplamiento-de-drupal-9 <span class="field field--name-title field--type-string field--label-hidden">JSON API | Desacoplamiento de Drupal 9</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <style>#video-only-927 .play-btn:hover::after { border-left: 15px solid #1fd7d9; transform: scale(20); border-left: 15px solid #fff; } #video-only-927 .play-btn::before { border: 5px solid #1fd7d9; } #video-only-927 .play-btn { background: radial-gradient(#1fd7d9 50%, rgba(66, 109, 202, 0.4) 52%); }</style> <div class="paragraph paragraph--type--video-only paragraph--view-mode--default" id="vol-927"> <section id="video-only-927" class="about area-padding video-block-wrapper"> <div class="col video-box"> <div class="portada"> <img src="/sites/default/files/styles/diapositiva_1200x650/public/2023-07/portada-gratuito-grande_2.jpg?itok=8dBQYXT7" class="img-fluid" alt=""> <div class="field field--name-vo-youtube-video field--type-entity-reference field--label-visually_hidden"> <div class="field__label visually-hidden">Video de Youtube</div> <div class="field__item"><article class="media media--type-remote-video media--view-mode-diapositiva-1200x650"> <div class="field field--name-field-media-oembed-video field--type-string field--label-visually_hidden"> <div class="field__label visually-hidden">URL de Video remoto</div> <div class="field__item"><div class="modal micromodal-slide" id="modal-media-647-0-field-media-oembed-video" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-media-647-0-field-media-oembed-video-content"> <a class="modal__btn" data-micromodal-close aria-label="Close this dialog window">X</a> <main class="modal__content" id="modal-media-647-0-field-media-oembed-video-content"> <div class="videoWrapper"><iframe src="/media/oembed?url=https%3A//youtu.be/gP67Mxc7hKY&amp;max_width=0&amp;max_height=0&amp;hash=amGZ81tLEC--N63Vf8depMtFyvjA92nHdmFINZR5b-Y" frameborder="0" allowtransparency="" class="media-oembed-content" title="Time Value of Money"></iframe></div> </main> </div> </div> </div> <div><a class="myButton" data-micromodal-trigger="modal-media-647-0-field-media-oembed-video"><span class="btn play-btn">.</span></a></div> </div> </div> </article> </div> </div> </div> </div> </section> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1213" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><p>       Con la aparición de varias librerías basadas en JavaScript, como Angular, Vue.js, React, etc. y el aumento definitivo del uso de dispositivos móviles, para conectarse a toda clase de servicios basados en plataformas, webs o aplicaciones; ha llegado el momento perfecto, para que todos aquellos que trabajamos con proyectos desarrollados en Drupal, nos planteemos la posibilidad "Descabezar" o "Desacoplar", el Frontend y el Backend, para seguir sacando el mayor partido, a su potente y flexible interfaz de usuario y al mismo tiempo, que nos adentramos poco a poco en el mundo del Frontend usando las nuevas librerías.</p> <p>     Por lo general, el elemento común, con el cual funcionan la mayoría o todas estas nuevas librerías basadas en JavaScript, es la lectura de datos en formato Json, debido a la flexibilidad estructural basada en arreglos o Arrays.</p> <p>     Para ayudarnos con esta transformación o adaptación en Drupal, existen varios módulos contribuidos, algunos incorporados directamente en el núcleo de Drupal, a partir de la versión 8, como el caso de Rest y Json Api, y otros como Json Extras, que nos permitirán ampliar nuestras posibilidades con esta clase de implementaciones.</p> <p>     Hoy vamos a abordar, la implementación de Json Api y Json Extras, para transformar en formato Json, todo el contenido dentro de nuestra web desarrollada con Drupal 9, sin que tengamos que invertir demasiado tiempo ni complicarnos la existencia. </p> <h2>GO HEADLESS! DESACOPLAMIENTO DE DRUPAL 9 CON EL MÓDULO JSON API</h2> <p>     Como ya mencionamos al principio de este artículo, el módulo Json Api, ha sido incluido en el núcleo de Drupal 9, por lo que para comenzar a utilizarlo, sólo necesitaremos activarlo desde la url "/admin/modules", o si tienes instalado el módulo Admin Toolbar, podrás hacerlo a través del menú superior, tal y como te muestro en la imagen:</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 70.9%;" data-ratio="70.9" data-b-token="b-03646f26bf0" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="e36ee1c4-5a2a-4965-a4f5-5d483b5e0227" loading="lazy" alt="Json Api Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/instalar_nuevo_modulo.jpg?itok=b3ao2s-o" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="409" height="290" typeof="foaf:Image" /></div></div> <p>     Ahora sólo nos faltaría descargar e instalar el módulo JSON:API Extras, para mostrarte lo fácil que será convertir en formato Json, todo el contenido que hayamos creado en nuestro Drupal, para poder aplicarle cualquier alternativa en diseño Frontend con la que te sientas más identificado.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 75.85%;" data-ratio="75.85" data-b-token="b-01d7c9f6bdb" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="204f547f-92ba-45c4-8b70-144c1480412d" loading="lazy" alt="Json Api Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/json_api.png?itok=sOAdwerp" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="493" typeof="foaf:Image" /></div></div> <h3>CÓMO INSTALAR Y CONFIGURAR EL MÓDULO:</h3> <p><strong>Paso 1 Descargar el módulo:</strong></p> <p>     Lo primero que tendrás que hacer es descargarlo, para ello, a partir de Drupal 8 se recomienda que utilices el gestor de paquetes <a href="https://getcomposer.org/" target="_blank">Composer</a>, ya que te facilitará tanto la instalación como futuras actualizaciones del tus proyectos. No obstante también podrías descargarlo desde la <a href="https://www.drupal.org/project/jsonapi_extras" target="_blank">Página oficial del módulo</a> y una vez descargado, tendrás que colocarlo en la carpeta "modules" o "modules/contrib", dependiendo de tu instalación y asegurarte de descargar todas sus dependencias o el módulo no funcionará, esta es una de las ventajas con las que cuentas al hacer la instalación usando Composer.</p> <p><strong>Paso 2 Activación del módulo</strong> :</p> <p>     Para activar el módulo JSON:API Extras, al igual que todos los demás módulos contribuidos de Drupal, tendrás la posibilidad de hacerlo, mediante el uso de la herramienta Drush, con el comando <strong>"drush en jsonapi_extras -y"</strong>, que sirve para activar cualquier módulos y todas sus dependencias, o desde la interfaz de Drupal.   </p> <p>     En nuestro ejercicio, antes de activar el módulo Json Api del núcleo de Drupal, vamos a descargar el módulo Json:Api Extras, para ello, como siempre, utilizaremos Composer con el comando que hemos mencionado anteriormente. </p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 36.65%;" data-ratio="36.65" data-b-token="b-7d8fddd22e9" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="e758757a-92e0-4d1c-99bf-f76273c642e2" loading="lazy" alt="Json Api Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/composer.png?itok=pcPO94a8" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="633" height="232" typeof="foaf:Image" /></div></div> <p>     Una vez haya concluido la descarga del módulo, nos iremos a nuestro proyecto, en la url "/admin/modules" y activaremos los siguientes módulos:</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 69.41%;" data-ratio="69.41" data-b-token="b-57cda6369e0" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="e830b6a8-a4d6-4f2b-8ca3-37238a0300f2" loading="lazy" alt="Json Api Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/modulos.png?itok=RnW_WvtW" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="389" height="270" typeof="foaf:Image" /></div></div> <p>     El módulo Serialización se activa automáticamente, como dependencia de Json Api del núcleo de Drupal 9.</p> <p>     Tan pronto como termine la activación de los módulos que hemos seleccionado, si refrescamos caché, podremos acceder desde el menú de administración a los Servicios Web.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 106.85%;" data-ratio="106.85" data-b-token="b-06a72515c57" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img data-entity-uuid="8d581093-3bca-4b13-a2fe-904ee3135176" loading="lazy" alt="Json Api Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/acceso_jsonapi.jpg?itok=GIqIxbTn" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="409" height="437" typeof="foaf:Image" /></div></div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 09/03/2023 - 16:37</span> Thu, 09 Mar 2023 15:37:51 +0000 webmaster 343 at https://drupaladicto.com Drupal::httpClient | Consumo datos externos a Drupal https://drupaladicto.com/curso/webservices/drupalhttpclient-consumo-datos-externos-drupal <span class="field field--name-title field--type-string field--label-hidden">Drupal::httpClient | Consumo datos externos a Drupal</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1208" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 49.38%;" data-ratio="49.38" data-b-token="b-48570d2568d" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Consumo datos externos a Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Consumo datos externos a Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-6373882b5e686.jpg?itok=R5XyK9HX" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="800" height="395" typeof="foaf:Image" /></div></div> <p>   </p> <p> A la mayoría de los que trabajamos con Drupal, en algún momento, nos habrá tocado trabajar en un proyecto, que requería que sirviéramos los datos desde Drupal, para que pudiera ser consumido desde alguna API o herramienta externa, existes múltiples formas de solucionar este problema, mediante el uso de webservices, vistas y varios módulos.</p> <p>     Si quieres aprender más acerca del uso de Servicios Web en Drupal <a href="https://www.drupaladicto.com/webservices-introduccion-y-basicos" target="_blank">HAZ CLIC AQUI</a></p> <p>     Pero en esta ocasión, nos vamos a referir al caso contrario, es decir, a los pasos necesarios para que podamos consumir, dentro de Drupal, la información provenientes desde una API externa. De esta manera, podremos manipular o presentar los datos, dentro de nuestro proyecto Drupal, sin la necesidad de hacernos responsables de tareas como la insercción o actualización de dichos datos.</p> <h2>   Cómo realizar peticiones de datos externos desde Drupal</h2> <p>     A partir de Drupal 8, se pueden realizar todo tipo de peticiones de datos, hacia fuentes external a Drupal, gracias al método <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal.php/function/Drupal%3A%3AhttpClient/10.0.x" target="_blank">Drupal::httpClient</a>, incluido en el núcleo.  Este método es, simplemente, un envoltorio para que podamos trabajar con la librería de php conocida como <a href="https://github.com/guzzle/guzzle" target="_blank">Guzzle</a>, que según su página oficial, "Guzzle es un cliente PHP HTTP y un framework, para crear clientes de servicios web RESTful".</p> <p>     Guzzle utiliza PSR-7 como interfaz de mensajes HTTP. PSR-7 describe interfaces comunes para representar mensajes HTTP. Esto permite que Guzzle funcione con cualquier otra biblioteca que utilice interfaces de mensajes PSR-7.</p> <p>     Para conocer la versión de nuestro proyecto de Drupal, podremos explorar el archivo composer.lock, y encontraremos varios datos, enlaces, definiciones relacionados con Guzzle:</p> <pre> { "name": "guzzlehttp/guzzle", "version": "6.5.8", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981" }, // </pre> <p> </p> <p>     Si quiers conocer más acerca de la versión más reciente de Guzzle, <a href="https://docs.guzzlephp.org/en/latest/" target="_blank">HAZ CLIC AQUI</a></p> <p> </p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 49.38%;" data-ratio="49.38" data-b-token="b-a85fe437e86" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Consumo datos externos a Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Consumo datos externos a Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-6373ac6c96aee.jpg?itok=BZyk46ZH" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="800" height="395" typeof="foaf:Image" /></div></div> <h2>   Drupal::httpClient dentro de un módulo personalizado en Drupal</h2> <p>     <strong>Si quieres aprender a crear un módulo personalizado <a href="https://www.drupaladicto.com/drupal-custom-module" target="_blank">HAZ CLIC AQUI</a></strong></p> <p>     Para disponer de una fuente de datos externa a Drupal, podremos acceder a la web <a href="https://www.data.gov/developers/apis">Data.gov</a>, en la que podremos encontrar un amplio catálogo de informaciones, vía CKAN, con una potente API que nos permitirá realizar, de forma segura, cualquiera de las pruebas relacionadas con nuestras peticiones.</p> <p>     Vamos a echar un vistazo a algunos ejemplos usando la API de CKAN, para ver la documentación completa <strong><a href="http://docs.guzzlephp.org/en/latest/quickstart.html#sending-requests" target="_blank">HAZ CLIC AQUI</a>.</strong></p> <h2>   Pasos para consumir datos externos a Drupal</h2> <h3>     Paso 1 - Inicialización del cliente</h3> <p>       Antes de poder realizar cualquier tipo de petición desde Drupal, vamos a necesitar inicializar el cliente de conexión. Para ello deberíamos incluir la siguiente línea dentro de nuestro Módulo Personalizado:</p> <pre> $client = \Drupal::httpClient();</pre> <h3>     Paso 2 - Definir URL de conexión</h3> <p>       Ahora que ya hemos inicializado el cliente, podremos añadir la url y el método que vamos a utilizar para conectarnos y extraer los datos. Para ello, tendremos que agregar una línea como la siguientes, sustituyendo la URL, en caso de utilizar otra dirección.</p> <pre> $client-&gt;request('GET', 'http://demo.ckan.org/api/3/action/package_list');</pre> <p>     Guzzle también proporciona una lista de métodos sincrónicos para realizar solicitudes, para ver la lista completa <strong><a href="http://docs.guzzlephp.org/en/latest/quickstart.html#sending-requests" target="_blank">HAZ CLIC AQUI</a></strong></p> <h3>     Paso 3 - Obtener los datos del requerimiento</h3> <p>       Una vez definidos el método y la url con la que vamos a realizar nuestr petición (Request), necesitaremos recolectar dicha información y guardarla, para luego procesarla, así que añadiremos la siguiente estructura:</p> <pre> $request = $client-&gt;get('http://demo.ckan.org/api/3/action/package_list'); $response = $request-&gt;getBody();</pre> <h3>     Paso 4 - Envío de datos hacia la API</h3> <p>       Ya que hemos aprendido la forma de conectarnos y de recibir los datos, desde una fuenta externa a Drupal, vamos a realizar la prueba contraria, es decir, enviaremos alguna información, en formato JSON, hacia la fuenta externa.</p> <pre> $client = \Drupal::httpClient(); $request = $client-&gt;post('http://demo.ckan.org/api/3/action/group_list', [   'json' =&gt; [     'id'=&gt; 'data-explorer'   ] ]); $response = json_decode($request-&gt;getBody());</pre> <p>     En el código anterior, hemos cambiado el método GET por el método POST, en <strong>client-&gt;post()</strong>, esto nos ha permitido pasar, además de la url de conexión, un array de nombre "json", compuesto por varias opciones adicionales, entre ellas el formato JSON. Guzzle se encargará de especificar la cabecera de estos datos,  'Content-Type','application/json', así como de añadir el 'json_encoding', para que todo funcione correctamente.</p> <p>     Finalmente, llamaremos al método <strong>json_decode</strong>, para decodificar los datos obtenidos en nuestra respuesta.</p> <p>     Para ver la lista completa de las opciones disponibles, <strong><a href="http://docs.guzzlephp.org/en/latest/request-options.html" target="_blank">HAZ CLIC AQUI</a></strong></p> <h2>   Cómo autenticarnos para la conexión</h2> <p>     En algunos casos, necesitaremos autenticarnos, para poder obtener la información desde la fuente externa, con la que deseamos realizar la conexión. En el siguiente ejemplo, puedes ver cómo sería la autenticación para acceder a la API de GitHub.</p> <pre> $client = \Drupal::httpClient(); $request = $client-&gt;get('https://api.github.com/user', [   'auth' =&gt; ['username','password'] ]); $response = $request-&gt;getBody();</pre> <h2>   Como manipular las Excepciones</h2> <p>     Otro de los casos con lo que podremos encontrarnos, son las excepciones. Siempre que utilicemos Drupal::httpClient, tendremos que envolver las excepciones dentro de un bloque <strong>try/catch</strong>, para poder manejarlas.</p> <p>     En el siguiente ejemplo, podrás ver cómo manejar una excepción, en un caso de login, para que se muestre en la tabla de errores de Drupal.</p> <pre> $client = \Drupal::httpClient(); try {   $response = $client-&gt;get('http://demo.ckan.org/api/3/action/package_list');   $data = $response-&gt;getBody(); } catch (RequestException $e) {   watchdog_exception('my_module', $e-&gt;getMessage()); }</pre> <p>     Puedes verificar la lista completa de las excepciones, explorando en la siguiente ubicación: </p> <pre> <strong>CARPETA_RAIZ/vendor/guzzlehttp/guzzle/src/Exception</strong></pre> <p>     Con esta información, podrás obtener diferentes comportamientos, al momento de trabajar con las excepciones.</p> <p>     El cliente de Guzzle, utiliza un sistema  <a href="http://docs.guzzlephp.org/en/latest/handlers-and-middleware.html" title="Handlers and Middleware">handler and middleware</a>, para enviar sus peticiones HTTP, puedes revisar la documentación oficial, para que te permita un mayor control sobre el manejo de tus datos, conexiones y resultados.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 55.25%;" data-ratio="55.25" data-b-token="b-c509e945b9d" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Consumo datos externos a Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" title="Consumo datos externos a Drupal | www.drupaladicto.com - Consultor y formador especializado en Drupal y Symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-6373c3400b27e.jpg?itok=E-80u4kh" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="800" height="442" typeof="foaf:Image" /></div></div> <form accept-charset="UTF-8" action="/curso/consumo-datos-api-externa-drupal" data-drupal-form-fields="activity-h5p-result,activity-h5p-correct-response,activity-h5p-response,activity-h5p-xapi-data,edit-back,edit-submit" data-drupal-selector="opigno-answer-opigno-h5p-form" data-once="form-updated" id="opigno-answer-opigno-h5p-form" method="post"> </form> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 09/03/2023 - 16:32</span> Thu, 09 Mar 2023 15:32:32 +0000 webmaster 342 at https://drupaladicto.com Simple OAuth | Módulo Drupal https://drupaladicto.com/curso/webservices/simple-oauth-modulo-drupal <span class="field field--name-title field--type-string field--label-hidden">Simple OAuth | Módulo Drupal</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <style>#video-only-969 .play-btn:hover::after { border-left: 15px solid #1fd7d9; transform: scale(20); border-left: 15px solid #fff; } #video-only-969 .play-btn::before { border: 5px solid #1fd7d9; } #video-only-969 .play-btn { background: radial-gradient(#1fd7d9 50%, rgba(66, 109, 202, 0.4) 52%); }</style> <div class="paragraph paragraph--type--video-only paragraph--view-mode--default" id="vol-969"> <section id="video-only-969" class="about area-padding video-block-wrapper"> <div class="col video-box"> <div class="portada"> <img src="/sites/default/files/styles/diapositiva_1200x650/public/2023-07/portada-gratuito-grande_2.jpg?itok=8dBQYXT7" class="img-fluid" alt=""> <div class="field field--name-vo-youtube-video field--type-entity-reference field--label-visually_hidden"> <div class="field__label visually-hidden">Video de Youtube</div> <div class="field__item"><article class="media media--type-remote-video media--view-mode-diapositiva-1200x650"> <div class="field field--name-field-media-oembed-video field--type-string field--label-visually_hidden"> <div class="field__label visually-hidden">URL de Video remoto</div> <div class="field__item"><div class="modal micromodal-slide" id="modal-media-690-0-field-media-oembed-video" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-media-690-0-field-media-oembed-video-content"> <a class="modal__btn" data-micromodal-close aria-label="Close this dialog window">X</a> <main class="modal__content" id="modal-media-690-0-field-media-oembed-video-content"> <div class="videoWrapper"><iframe src="/media/oembed?url=https%3A//youtu.be/8n9fNoWGlqA&amp;max_width=0&amp;max_height=0&amp;hash=MP1v0KgIIzmLojaikZ3EWS2o23Aql_0nokRUfPPCHg4" frameborder="0" allowtransparency="" class="media-oembed-content" title="Time Value of Money"></iframe></div> </main> </div> </div> </div> <div><a class="myButton" data-micromodal-trigger="modal-media-690-0-field-media-oembed-video"><span class="btn play-btn">.</span></a></div> </div> </div> </article> </div> </div> </div> </div> </section> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1212" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><h2><strong>Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... <a href="https://youtu.be/8n9fNoWGlqA" target="_blank">HAZ CLIC AQUI</a></strong></h2> <p>      Con el crecimiento en la popularidad en utilizar Drupal Desacoplado (Headless), combinando un diseño frontend desarrollado en javascript, a partir de frameworks como Angular, React.js o Vue.js, y a su vez, dejando las tareas relacionadas con gestión de usuarios, permisos y otras, relacionadas con bases de datos a cargo de Drupal; hoy aprenderemos a configurar uno de los módulos necesarios para proteger, este tipo de conexiones, entre Drupal 9 y otras aplicaciones. Nos referimos al módulo <a href="https://www.drupal.org/project/simple_oauth">Simple Aouth</a>, que nos permitirá configurar accesos y permisos restrictivos, para el intercambio de datos desde y hacia Drupal, de manera protegida.</p> <h3>Cómo instalar y configurar el módulo:</h3> <h5>Paso 1 - Descargar el módulo:</h5> <p>     Lo primero que tendrás que hacer es descargarlo, para ello, a partir de Drupal 8 se recomienda que utilices el gestor de paquetes <a data-extlink="" href="https://getcomposer.org/" rel="noreferrer">Composer</a>, ya que te facilitará tanto la instalación como futuras actualizaciones del tus proyectos. No obstante también podrías descargarlo desde la <a data-extlink="" href="https://www.drupal.org/project/simple_oauth" rel="noreferrer">Página oficial del módulo</a> y una vez descargado, tendrás que colocarlo en la carpeta "modules" o "modules/contrib", dependiendo de tu instalación.</p> <h5>Paso 2 - Configuración:</h5> <p>     Primero genere un par de claves para que el módulo Simple OAuth las use al cifrar tokens. Estos deben almacenarse fuera de su directorio raíz de Drupal. Recomendamos la siguiente estructura de directorios:</p> <pre> . ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── config ├── keys ├── scripts ├── vendor └── web // &gt; Drupal root directory</pre> <p>Genere las claves necesarias con el siguiente conjunto de comandos:</p> <pre> mkdir keys cd keys openssl genrsa -out private.key 2048 openssl rsa -in private.key -pubout &gt; public.key chmod 600 public.key chmod 600 private.key</pre> <p>     Luego dígale al módulo Simple OAuth dónde encontrarlos. En su sitio de Drupal, en el menú administrativo Administrar, vaya a Configuración &gt; OAuth simple y complete el formulario con las rutas a las claves que acaba de generar.</p> <p>     Para ello, accederemos a la página de configuración del módulo en la url "/admin/config/people/simple_oauth" y a continuación rellenaremos los campos del formulario con los siguientes detalles:</p> <pre> Access token expiration time: 300 Refresh token expiration time 1209600 Public Key: ../keys/public.key Private Key: ../keys/private.key</pre> <p> </p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 138.59%;" data-ratio="138.59" data-b-token="b-c81f7a62708" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe05b50e981.png?itok=2eIQGZiD" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="469" height="650" typeof="foaf:Image" /></div></div> <p>     A continuación, configure un nuevo cliente OAuth. Primero agregue un nuevo rol de Drupal. Vaya a Personas &gt; Roles (/admin/people/roles/add) y agregue un nuevo rol llamado "Cliente Gatsby".</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 52.77%;" data-ratio="52.77" data-b-token="b-269d981198a" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe0605a17cb.png?itok=ENOFFGnx" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="578" height="305" typeof="foaf:Image" /></div></div> <p>     Luego, crearemos un usuario y le asignaremos el rol que hemos creado cuando lo agregemos como consumidor en simple OAuth</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 132.92%;" data-ratio="132.92" data-b-token="b-b0eb0e1e62c" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe063a884e6.png?itok=ss85ISYO" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="489" height="650" typeof="foaf:Image" /></div></div> <p>     Luego, en el menú Administrar administración, vaya a Configuración &gt; Simple OAuth &gt; Clientes y haga clic en el botón Agregar consumidor. Complete el formulario y recuerde el valor que ingresa para el campo Nuevo secreto, ya que lo necesitará nuevamente más adelante. En Ámbitos, elija el <strong>rol de cliente de Gatsby</strong> que acabamos de crear. Finalmente, haga clic en Guardar para agregar el nuevo consumidor.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 111.13%;" data-ratio="111.13" data-b-token="b-b8e6df20641" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe0662b6729.png?itok=AILNGZ4S" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="575" height="639" typeof="foaf:Image" /></div></div> <p>     En la página resultante, debería ver su nueva lista de consumidores junto con un UUID. Tome nota de este UUID. Combinados con el secreto de arriba, serán su ID de consumidor y clave, que se usarán para las solicitudes de OAuth más adelante</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 22.77%;" data-ratio="22.77" data-b-token="b-4fb96a35872" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe06f23f535.jpg?itok=NwfnnH2l" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="148" typeof="foaf:Image" /></div></div> <p>     Finalmente, otorgue permiso a los usuarios autenticados para otorgar códigos OAuth 2. En el menú Gestionar administración, vaya a Personas &gt; Permisos (/admin/people/permissions). Marque la casilla "Grant OAuth2 codes" para otorgar al usuario autenticado los códigos de permisos OAuth 2. Luego, desplácese hasta la parte inferior de la página y haga clic en Guardar permisos.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 70.77%;" data-ratio="70.77" data-b-token="b-557e8944be8" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Simple OAuth Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe07c7dba64.jpg?itok=a2M3cXWI" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="460" typeof="foaf:Image" /></div></div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 09/03/2023 - 16:30</span> Thu, 09 Mar 2023 15:30:13 +0000 webmaster 341 at https://drupaladicto.com Rest Services en Drupal 9 (Parte 2) https://drupaladicto.com/curso/webservices/rest-services-en-drupal-9-parte-2 <span class="field field--name-title field--type-string field--label-hidden">Rest Services en Drupal 9 (Parte 2)</span> <div class="field field--name-field-contenidos-cap-gratis field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <style>#video-only-968 .play-btn:hover::after { border-left: 15px solid #1fd7d9; transform: scale(20); border-left: 15px solid #fff; } #video-only-968 .play-btn::before { border: 5px solid #1fd7d9; } #video-only-968 .play-btn { background: radial-gradient(#1fd7d9 50%, rgba(66, 109, 202, 0.4) 52%); }</style> <div class="paragraph paragraph--type--video-only paragraph--view-mode--default" id="vol-968"> <section id="video-only-968" class="about area-padding video-block-wrapper"> <div class="col video-box"> <div class="portada"> <img src="/sites/default/files/styles/diapositiva_1200x650/public/2023-07/portada-gratuito-grande_2.jpg?itok=8dBQYXT7" class="img-fluid" alt=""> <div class="field field--name-vo-youtube-video field--type-entity-reference field--label-visually_hidden"> <div class="field__label visually-hidden">Video de Youtube</div> <div class="field__item"><article class="media media--type-remote-video media--view-mode-diapositiva-1200x650"> <div class="field field--name-field-media-oembed-video field--type-string field--label-visually_hidden"> <div class="field__label visually-hidden">URL de Video remoto</div> <div class="field__item"><div class="modal micromodal-slide" id="modal-media-689-0-field-media-oembed-video" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-media-689-0-field-media-oembed-video-content"> <a class="modal__btn" data-micromodal-close aria-label="Close this dialog window">X</a> <main class="modal__content" id="modal-media-689-0-field-media-oembed-video-content"> <div class="videoWrapper"><iframe src="/media/oembed?url=https%3A//youtu.be/IhpiN1r9RtE&amp;max_width=0&amp;max_height=0&amp;hash=Exoivw3od31RscqkGARfuPzb-Bqvmuh99xtOXHUI5qU" frameborder="0" allowtransparency="" class="media-oembed-content" title="Time Value of Money"></iframe></div> </main> </div> </div> </div> <div><a class="myButton" data-micromodal-trigger="modal-media-689-0-field-media-oembed-video"><span class="btn play-btn">.</span></a></div> </div> </div> </article> </div> </div> </div> </div> </section> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--text-only paragraph--view-mode--default" id="txonly-1211" style="background-color: ;border: solid px;border-color: #096ba0;border-radius: 5px;padding: 10px;"> <div class="clearfix text-formatted field field--name-to-text field--type-text-long field--label-visually_hidden"> <div class="field__label visually-hidden">Texto</div> <div class="field__item"><h2><strong>Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... <a href="https://youtu.be/IhpiN1r9RtE" target="_blank">HAZ CLIC AQUI</a></strong></h2> <p>      Siempre que trabajemos con proyectos en los que tengamos que testear la funcionalidad de API Rest, es recomendable que utilicemos las herramientas que facilitarán nuestras tareas de testeo, de manera que resulte más simple, el proceso de identificación de posibles errores, aplicar nuevas funcionalidades o crear documentación relacionada con el proceso.</p> <p>     En nuestro caso, como estaremos trabajando con servicios del tipo REST en Drupal, vamos a tener que realizar varias comprobaciones, sobre las llamadas hacia nuestra API, utilizando GET, POST, PATCH y DELETE, con los cuales obtendremos información desde Drupal, como hemos explicado en el artículo anterior, <a href="/actualidad/como-trabajar-con-rest-en-drupal-9-parte-1" target="_blank">Cómo trabajar con Rest en Drupal 9 (Parte 1)</a>, además de realizar otras operaciones como Añadir, Actualizar o borrar contenidos, por medio de estos métodos.</p> <p>     En las siguientes líneas trataré de explicar, de la manera resumida, los principios fundamentales para entender, cómo aplicar llamadas a la API Rest que nos permitan la ejecución de las principales operaciones, al emplear esta clase de sistema, con Drupal 9.</p> <p>     Una de estas herramientas de desarrollo es <a href="https://www.postman.com/">Postman</a>, que nos ofrece una interfaz gráfica, en la que podremos realizar varios tipos de operaciones relacionadas con API Rest, para facilitarnos el proceso de testeo para nuestros proyectos. Puedes descargar <a href="https://www.postman.com/downloads/" target="_blank">Postman desde su página oficial</a>.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 59.92%;" data-ratio="59.92" data-b-token="b-213f7fc13c5" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fdf812c8916.jpg?itok=NzG8F1FU" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="519" height="311" typeof="foaf:Image" /></div></div> <p>     Ahora que ya hemos configurado los servicios dentro de Drupal, para autorizar las consultas, mediante el uso de GET, y obtener así el contenido de varios nodos, vamos a realizar la misma comprobación ejecutando la llamada en Postaman, para ello, una vez descargada la aplicación Postman,  copiaremos la url o "endpoint", que nos devolverá el listado de los nodos de nuestra página de inicio, tal y como los expliqué en el artículo anterior <a href="/actualidad/como-trabajar-con-rest-en-drupal-9-parte-1" target="_blank">Cómo trabajar con Rest en Drupal 9 (Parte 1)</a>, y deberíamos obtener exactamente el mismo resultado.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 68.46%;" data-ratio="68.46" data-b-token="b-92bdfc95550" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fdffa0433f8.jpg?itok=W3nR_8I1" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="837" height="573" typeof="foaf:Image" /></div></div> <h2>    Métodos de autenticación:</h2> <p>          Cuando realizamos llamadas a un API Rest, necesitaremos al menos un método de autenticación, de esa forma, estaremos diciéndole a nuestra aplicación, que tenemos los permisos necesarios para acceder a la información con la que vamos a trabajar.</p> <p>          Existen varias formas de autenticarnos, a la hora de trabajar con las llamadas al API REST, una de ellas, es el uso de cookies; y aunque generalmente, el uso del método Get para obtener información mediante API REST, no debería necesitar ningún tipo de autenticación, ya que sólo estamos accediendo a información pública, expuesta a cualquier usuario desde nuestro servidor web, al trabajar con los servicios REST en Drupal, nos exige que al menos activemos un método de autenticación.</p> <p>         Es por esta razón, por la cual lo hicimos en el artículo anterior, al momento de activar nuestro primer servicio con el Método Get, para leer la información sobre los nodos desde nuestro Drupal.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 54.34%;" data-ratio="54.34" data-b-token="b-80ab9d59497" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe001c02c49.jpg?itok=SG6t3Nok" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="519" height="282" typeof="foaf:Image" /></div></div> <p>          Por defecto, Drupal utiliza el sistema de Cookies para informarse sobre los datos de nuestro usuario, es por esta razón que al loguearnos en cualquier web de Drupal, la interfaz nos permitirá ver los contenidos para los que tengamos acceso, si somos los administradores, veremos la interfaz del administrador y si somos usuarios de cualquier otro tipo, nos presentará la interfaz de usuario correspondiente.</p> <p>          Si quieres comprobar las cookies que genera Drupal automáticamente cuando estás logueado como usuario, puedes hacer <strong>clic derecho</strong> y seleccionar <strong>inspeccionar elemento</strong> o presionar la <strong>tecla F12</strong>, en mi caso utilizo <strong>Google Chorme</strong>, si tu también lo hacer, deberías ver algo como lo que te presento en la siguiente imagen, He seleccionado la pestaña <strong>Network </strong>y tengo marcada la opción <strong>Preserve log</strong>, al hacer clic sobre Headers verás la información que estamos enviando a nuestro servidor, donde está alojada la web de Drupal y dentro de estas informaciones podrás comprobar la existencia de las cookies.</p> <p>          Aunque el uso de Cookies es un método que funciona para que Drupal nos devuelva información, en el caso de una aplicación externa, ubicada en otro servidor, por ejemplo, que quisiera obtener información mediante API REST, necesitaremos un método de autenticación más robusto, porque para Drupal, como cualquier otra aplicación a la que accedamos por servicios web, quien acceda usando este tipo de autenticación, podrá operar con todos los permisos concedidos para ese usuario.</p> <p>         Otra forma de identificarnos como usuario con permisos frente a Drupal, utilizando API REST, es el uso del TOKEN DE SESIÓN, con el que le diremos a Drupal todo lo que necesita saber acerca de nuestro usuario, para que pueda ofrecernos lo que vamos a necesitar al conectarnos con él.</p> <p>         Hasta las primeras versiones de Drupal 8, para obtener el TOKEN DE SESIÓN, bastaba con añadir a la url de nuestra web, una vez activado el módulo rest "http//miweb.com<strong>/rest/session/token</strong>", esto nos imprimía en la pantalla el valor correspondiente, que tendríamos que copiar dentro de los parámetros de configuración, para nuestra API rest.</p> <p>         Esta opción fue eliminada a partir de las últimas actualizaciones de Drupal 8, por lo que ya no existe en Drupal 9 ni versiones posteriores. En su lugar se añadió un módulo contribuido llamado <a href="https://www.drupal.org/project/rest_api_access_token">REST API Access Token</a>, con el cual, según la página oficial:</p> <p>     "El módulo REST API Access Token proporciona un proveedor de autenticación Drupal que utiliza tokens (en encabezados) como factor principal de autenticación.<br /> Además, el módulo proporciona verificación de firmas para solicitudes y caché de respuestas."</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 54.38%;" data-ratio="54.38" data-b-token="b-fa76395b591" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe00e7d4746.png?itok=7rf9CYGt" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="971" height="528" typeof="foaf:Image" /></div></div> <p>        Necesitaremos descargar e instalar este módulo, para realizar las pruebas con las llamadas a la API REST, cuando trabajemos con los métodos POST, PATCH y DELETE, que explicaremos en el siguiente artículo, pero antes de terminar, vamos a hablar de una última herramienta que necesitaremos para testear nuestros servicios web...     </p> <h2>     CURL</h2> <p>          <strong>Según la página oficial de PHP:</strong> PHP soporta libcurl, una biblioteca creada por Daniel Stenberg que permite conectarse y comunicarse con diferentes tipos de servidores y diferentes tipos de protocolos. Actualmente, libcurl admite los protocolos http, https, ftp, gopher, telnet, dict, file y ldap. libcurl también admite certificados HTTPS, HTTP, POST, HTTP PUT, subidas mediante FTP (también se puede hacer con la extensión FTP de PHP), subidas basadas en formularios HTTP, proxies, cookies, y autenticación usuario+contraseña.</p> <p>         Dependiendo del sistema operativo con el que estés trabajando, y de la versión de PHP que tengas instalada, la manera en que se configura CURL variará, por lo tanto, sería recomendable que compruebes si la tienes configurada correctamente en tu servidor antes de comenzar con la siguiente fase de estos ejercicios.</p> <h2>    Cómo comprobar si tengo instalado CURL en Drupal 9</h2> <p>          En todas las instalaciones de Drupal, podremos acceder a una página que nos detallará las informaciones principales, relacionadas con las informaciones más relevantes sobre nuestro servidor, Mysql, Php, además de otras relacionadas directamente con la configuración interna de Drupal. </p> <p>          Obviamente, para acceder a estos datos necesitarás tener permisos de administrador, y estar logueado dentro de tu web. La url es "<strong>/admin/reports/status</strong>". Una vez hayas accedido a esta pantalla, podrás hacer clic en el apartado MAS INFORMACIÓN de PHP, donde podrás ver el phpinfo, y comfirmar si ya tienes habilitada esta librería en tu entorno.</p> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 42.31%;" data-ratio="42.31" data-b-token="b-fb1570989fe" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe026f6b8e7.jpg?itok=yUr80aGS" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="275" typeof="foaf:Image" /></div></div> <p></p><div class="media-wrapper media-wrapper--blazy media-wrapper--image"> <div style="padding-bottom: 42.31%;" data-ratio="42.31" data-b-token="b-a9b1c583cfb" class="media media--blazy media--image media--ratio media--ratio--fluid is-b-loading"><img alt="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" title="Rest Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony" decoding="async" class="media__element b-lazy b-filter img-fluid" loading="lazy" data-src="/sites/default/files/styles/max_1300x1300/public/inline-images/file-62fe028172a8a.jpg?itok=iuc4bkGd" src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%201%201'%2F%3E" width="650" height="275" typeof="foaf:Image" /></div></div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/luis-alberto-mejia" typeof="schema:Person" property="schema:name" datatype="">webmaster</span></span> <span class="field field--name-created field--type-created field--label-hidden">Jue, 09/03/2023 - 16:23</span> Thu, 09 Mar 2023 15:23:14 +0000 webmaster 339 at https://drupaladicto.com