Drupal https://planet.communia.org/en en Git wiki documentation in native drupal help pages https://planet.communia.org/en/content/git-wiki-documentation-native-drupal-help-pages <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--blog--rss.html.twig * field--node--title--blog.html.twig x field--node--title.html.twig * field--node--blog.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>Git wiki documentation in native drupal help pages</span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--blog--rss.html.twig * field--node--uid--blog.html.twig x field--node--uid.html.twig * field--node--blog.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/1" class="visually-hidden p-author h-card" rel="author" title="kinta">kinta <img src="" alt="kinta" /> </a> <a title="View user profile." href="/en/users/kinta">kinta</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--blog--rss.html.twig * field--node--created--blog.html.twig x field--node--created.html.twig * field--node--blog.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2024-02-27T18:03:27+01:00" title="Tuesday, February 27, 2024 - 18:03">Tue, 02/27/2024 - 18:03</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--blog--rss.html.twig * field--node--body--blog.html.twig * field--node--body.html.twig * field--node--blog.html.twig * field--body.html.twig * field--text-with-summary.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="body field field--node-body field--name-body field--type-text-with-summary field--label-hidden field__item"><p>In last projects, here in communia we are using more and more the gitlab suite tools that are offering many free software projects. Calling projects for their own name: kde with its <a href="https://invent.kde.org">https://invent.kde.org</a> , freedesktop with its <a href="https://gitlab.freedesktop.org">https://gitlab.freedesktop.org</a> , and where we are more active; <a href="https://gitlab.com">https://gitlab.com</a>  and drupalcode.org <a href="https://git.drupalcode.org">https://git.drupalcode.org</a> .</p><p>The schema that we are using is a broader group that includes the drupal recommended project and also where we are including the custom modules, themes, issues, and the wiki documentation. This way we can attach project references to each page, and also the wiki is part of the whole project system.</p><p>We found that when we are providing the project to the group(being a customer, and association or a social project), the content editor or the collaborator is a different person than the one who is reporting issues and has access to gitlab. So this person hasn't access to the forged wiki documentation. Of course that the wiki could be exported to pdf, hosted as mark-down with nextcloud, or served using ruby with gollum. But it will be detached of your final shiny drupal product.</p><p>So here comes this simple module: <a href="https://www.drupal.org/project/git_wiki_help">https://www.drupal.org/project/git_wiki_help</a> . With it, you could add the exported or cloned git wiki to a directory in (private) files path. And then it will be accessible in native drupal administrator help pages, giving the person who administrates the web the general project documentation. </p><p>Take note that wiki is not updated in real-time as if there's an update in git wiki it needs to manually pulled (or If using git you could hang to git hooks to update automatically).</p></div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--blog--rss.html.twig * field--node--field-tags--blog.html.twig * field--node--field-tags.html.twig * field--node--blog.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-inline clearfix"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> <div class="field__item"><a href="/ca/etiquetes/documentacio" hreflang="ca">documentació</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> Tue, 27 Feb 2024 17:03:27 +0000 kinta 6570 at https://planet.communia.org https://planet.communia.org/en/content/git-wiki-documentation-native-drupal-help-pages#comments Actualitzem jazzterrassa.org https://planet.communia.org/en/content/actualitzem-jazzterrassaorg <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--blog--rss.html.twig * field--node--title--blog.html.twig x field--node--title.html.twig * field--node--blog.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>Actualitzem jazzterrassa.org</span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-image--blog--rss.html.twig * field--node--field-image--blog.html.twig * field--node--field-image.html.twig * field--node--blog.html.twig * field--field-image.html.twig * field--image.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="image field field--node-field-image field--name-field-image field--type-image field--label-hidden field__items"> <div class="field__item"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'responsive_image_formatter' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/responsive-image-formatter.html.twig' --> <a href="/sites/default/files/Screenshot_20240116_153600.png"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'responsive_image' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/responsive-image.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'image' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/image.html.twig' --> <img loading="eager" srcset="/sites/default/files/styles/max_325x325/public/Screenshot_20240116_153600.png?itok=KT-nWqPv 325w, /sites/default/files/styles/max_650x650/public/Screenshot_20240116_153600.png?itok=FELMXmuI 650w, /sites/default/files/styles/max_1300x1300/public/Screenshot_20240116_153600.png?itok=5w4ieGM7 1300w" sizes="(min-width: 1290px) 325px, (min-width: 851px) 25vw, (min-width: 560px) 50vw, 100vw" width="325" height="277" src="/sites/default/files/styles/max_325x325/public/Screenshot_20240116_153600.png?itok=KT-nWqPv" alt="" /> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/image.html.twig' --> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/responsive-image.html.twig' --> </a> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/responsive-image-formatter.html.twig' --> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--blog--rss.html.twig * field--node--uid--blog.html.twig x field--node--uid.html.twig * field--node--blog.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/801" class="visually-hidden p-author h-card" rel="author" title="victor">victor <img src="" alt="victor" /> </a> <a title="View user profile." href="/en/user/801">victor</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--blog--rss.html.twig * field--node--created--blog.html.twig x field--node--created.html.twig * field--node--blog.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2024-01-16T15:00:07+01:00" title="Tuesday, January 16, 2024 - 15:00">Tue, 01/16/2024 - 15:00</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--blog--rss.html.twig * field--node--body--blog.html.twig * field--node--body.html.twig * field--node--blog.html.twig * field--body.html.twig * field--text-with-summary.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="body field field--node-body field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Ens complau presentar i rellançar de nou la web de Jazz Terrassa. Fa 10 anys communia ja es va ocupar de crear la web de <a href="https://jazzterrassa.org">https://jazzterrassa.org</a> i passat aquest temps calia fer una actualització al nivell de l'activitat de l'entitat. </p><p>Expliquem a continuació com hem cuinat la web.</p><h2>Introducció</h2><p>Projecte web desenvolupat sobre l'arquitectura del CMS <a href="https://www.drupal.org/">Drupal</a>, en la seva última versió amb un tema personalitzat basat en <a href="https://git.drupalcode.org/project/radix">Radix</a>. Un tema de Drupal amb una arquitectura MVC basada en components de <a href="https://symfony.com/what-is-symfony">Symfony</a>. Un desenvolupament complex que incorpora diverses funcionalitats, a destacar, un sistema de comerç i tiqueting per la venda d'entrades, sistema de butlletins i un arxiu documental amb més de seixanta anys d'antiguitat.</p><p>Pensar una web com la de jazzterrassa.org sense la potència del programari lliure seria com pensar el jazz sense la <a href="https://lincolnjazzcafe.co.uk/2023/03/28/jazz-standards-and-improvisation-a-perfect-match/">potència dels estandards</a>. Aquella terra comú que permet crear originalitat, adaptació i nous escenaris i llenguatges. </p><p>Per nosaltres Drupal és la base sobre la qual, a espatlles de gegants, hem pogut oferir una web de primer nivell a l'entitat Jazz Terrassa. Drupal és el nostre estàndard de jazz. I com a reconeixement d'aquells que han fet créixer aquest comunal de codi, en retornarem de nou creat perquè algú  altre com nosaltres pugui fer-lo servir. Potser un altre petit club de jazz a Melbourne, a Tokyo o Johannesburg.</p><p>A Communia creiem que el coneixement ha de ser lliure, obert, horitzontal i accessible a totes les persones... solucions que facilitin les activitats en xarxa de les diferents comunitats d’investigació i recerca en les pràctiques <a href="https://ca.wikipedia.org/wiki/D%27igual_a_igual">P2P</a>, amb tecnologies lliures que vinculen les eines amb la construcció de processos de cooperació social.</p><p>D'acord amb això treballem en plataformes de <a href="https://ca.wikipedia.org/wiki/Programari_lliure">software lliure</a> basades en estàndards, els projectes que implementem ofereixen una gran capacitat escalar: Com en una construcció de LEGO, pots afegir funcionalitats i aplicacions en forma de mòduls i connectors, sense perjudici de la feina feta fins al moment. </p><p>Per dur a terme les diverses fases del projecte, hem hagut de crear diversos mòduls propis per desenvolupar les funcionalitats requerides per la web. Que anirem alliberant a mesura que tinguin suficient qualitat per ser usada de manera genèrica.</p><h2>Context del Projecte</h2><h3>Antecedents i objectius del projecte</h3><p>A finals de l'any 2013 s'encarrega a Communia realitzar la migració de l'antiga web de Jazz Terrassa a un sistema Drupal 7. A la primera versió de la nova web bàsicament hi ha tot l'arxiu històric i un nou aspecte adaptatiu entre moltes altres qüestions més menors. Més endavant, s'implementen noves funcionalitats importants com la venda d'entrades amb un sistema propi i el sistema de gestió de butlletins, entre altres millores menors. A causa del pròxim tancament del cicle de vida de Drupal 7, es va plantejar una actualització del projecte web mantenint tot el contingut històric afegit.</p><p>Després de deu anys s'ha fet una migració general del projecte mantenint tot el contingut de la web actual. El procés es va plantejar en diverses migracions incrementals de contingut i algunes configuracions actuals (nodes, usuaris, taxonomies… i algunes configuracions) a una nova web en Drupal 9, que posteriorment va passar a Drupal 10, amb un tema gràfic reescrit de nou.</p><p>Enumeració dels objectius tècnics del projecte:</p><ol><li><strong>Disseny Responsiu:</strong> Assegurar que el lloc web sigui accessible i funcioni de manera òptima en una varietat de dispositius i mides de pantalla.</li><li><strong>Optimització del Rendiment:</strong> Aconseguir temps de càrrega ràpids i un rendiment eficient del lloc web per millorar l'experiència de l'usuari.</li><li><strong>Seguretat del Lloc:</strong> Implementar mesures de seguretat robustes per protegir-se contra possibles amenaces i vulnerabilitats.</li><li><strong>Compatibilitat amb Navegadors:</strong> Assegurar que el lloc funcioni correctament en diferents navegadors web, com Chrome, Firefox, Safari i Edge.</li><li><strong>Gestió de Continguts Eficient:</strong> Desenvolupar un sistema de gestió de continguts (CMS) efectiu per facilitar l'actualització i administració del contingut del lloc.</li><li><strong>Integració de Funcionalitats Específiques:</strong> Implementar característiques específiques segons els requisits del client, com formularis interactius, funcionalitats de comerç electrònic, etc.</li><li><strong>Optimització SEO:</strong> Incorporar bones pràctiques de SEO per millorar la visibilitat del lloc web als motors de cerca.</li><li><strong>Compliment d'Estandards Web:</strong> Assegurar que el lloc web compleix amb els estàndards i directrius web actuals per a l'accessibilitat i la usabilitat.</li><li><strong>Escalabilitat:</strong> Dissenyar l'arquitectura del sistema de manera que pugui créixer i adaptar-se fàcilment a mesura que s'afegeixen més usuaris o funcionalitats.</li><li><strong>Documentació del Codi:</strong> Crear documentació tècnica exhaustiva per facilitar la comprensió i el manteniment del codi font.</li><li><strong>Proves Rigoroses:</strong> Realitzar proves exhaustives per garantir l'estabilitat i el correcte funcionament del lloc web en diverses situacions.</li></ol><h3>Importància programari lliure</h3><p><a href="https://www.drupal.org/about/licensing#drupal-license" target="_blank" rel="nofollow noreferrer noopener">Drupal té llicències GPL</a>, pel qual podem utilitzar, estudiar, compartir i modificar el codi segons ens convingui, el fa ideal per poder-lo adaptar a les necessitats de l'entitat. Com hem dit abans no volem sols extreure el codi, intentem en la mesura que el codi tingui qualitat donar un retorn a drupal.org i oferir-ne millores i solucions d'incidències que ens anem trobant.</p><p> </p><h2>Fases del projecte</h2><p>Per dur a terme les diverses fases del projecte, hem hagut de crear diversos mòduls propis per desenvolupar les funcionalitats requerides per la web. Aquí un llistat dels mòduls desenvolupats per <a href="https://communia.org/" target="_blank" rel="nofollow noreferrer noopener">Communia</a> i les <a href="https://www.drupal.org/communia" target="_blank" rel="nofollow noreferrer noopener">seves contribucions</a> cap a la comunitat de Drupal.</p><ul><li>Aplicació de control d'entrades (<a href="https://gitlab.com/communia/barcode-checkr">Barcode checkr</a>)</li><li>Disseny de les entrades (<a href="https://www.drupal.org/project/commerce_ticketing" target="_blank" rel="nofollow noreferrer noopener">commerce_ticketing</a>)</li><li>Restricció d'entrades per soci (<a href="https://gitlab.com/communia/jazz-d10/-/tree/main/web/modules/custom/commerce_role_product_variation?ref_type=heads">commerce_role_product_variation</a>)</li><li>Subpàgines que mostren un contingut concret / vistes amb llistats de continguts (<a href="https://gitlab.com/communia/views_validate_tabs">validate_tabs</a>)</li><li>Migració field collections</li><li>Comptador Arxiu Històric</li></ul><h3>Desplegament i construcció del site</h3><p>Desplegament i construcció del site totalment optimitzat per un entorn de Drupal, que ens assegura una optimització de rendiment i seguretat en el nostre lloc web.</p><h3>Migració de continguts</h3><p>Migració de continguts, usuaris, fitxers, categories... Funcionalitat flexible i sistematitzada per tal que el salt d'un sistema a un altre sigui viable i no perdre continguts existents.</p><h3>Fase de desenvolupament</h3><p>Disseny i implementació del nou tema basat en Drupal radix, incorporant un disseny responsiu i que respecti els estàndards web.</p><h3>Fase de proves i desplegament</h3><p>Fase de proves per assegurar-nos del correcte funcionament i detectar possibles errors abans del seu desplegament. Aquesta fase inclou proves de funcionalitat, rendiment, seguretat i usabilitat. El funcionament es basa a executar escenaris de proves realistes per identificar i corregir possibles errors, d'aquesta manera garantim un producte final fiable i de qualitat. Una vegada conclou aquesta fase amb resultats positius, es desplega la web en els servidors interns de communia.</p><h3>Fase de manteniment</h3><p>Finalment, quan el projecte ha sigut desplegat correctament i es troba online passa a una fase interna de motorització i manteniment de web, on el nostre equip gestiona l'status report del site i s'encarrega de mantenir-lo actualitzat a la última versió funcional.</p><h2>Visió General del Sistema</h2><h3>Arquitectura General</h3><p>La arquitectura general d'un projecte Drupal es basa en un enfocament modular i escalable. Es composa d'un nucli, uns mòduls, i uns temes que conformen l'aparença. </p><p>Aquesta arquitectura modular i flexible fa que Drupal sigui adequat per a una àmplia varietat de projectes, des de llocs web senzills fins a aplicacions web complexes i personalitzades.</p><h3>Tecnologies Utilitzades</h3><p>Les tecnologies utilitzades en un projecte web Drupal abasten tant les relacionades amb el nucli del CMS com aquelles que s'empleen per personalitzar i estendre les seves funcionalitats. A continuació, es descriuen les tecnologies clau:</p><ol><li><strong>PHP (Hypertext Preprocessor):</strong><ul><li>Drupal està construït principalment en PHP, un llenguatge de programació del costat del servidor.</li><li>PHP s'utilitza per processar el codi al servidor i generar l'HTML que s'envia al navegador de l'usuari.</li></ul></li><li><strong>MySQL o PostgreSQL (Sistemes de Gestió de Bases de Dades):</strong><ul><li>Drupal emmagatzema el seu contingut i configuració en una base de dades. Pot ser compatible tant amb MySQL com amb PostgreSQL, permetent la flexibilitat en la elecció del sistema de gestió de bases de dades.</li></ul></li><li><strong>Symfony (Framework PHP):</strong><ul><li>Symfony és un framework PHP que proporciona components reutilitzables per al desenvolupament web.</li><li>Drupal 8 i versions posteriors incorporen components de Symfony per millorar l'estructura del codi i la modularitat.</li></ul></li><li><strong>Twig (Motor de Plantilles):</strong><ul><li>Twig és el motor de plantilles utilitzat per Drupal per definir l'estructura de l'HTML en els temes.</li><li>Proporciona una sintaxi clara i llegible per facilitar la creació de plantilles.</li></ul></li><li><strong>JavaScript (per a la Interactivitat del Client):</strong><ul><li>Drupal utilitza JavaScript per millorar la interactivitat del costat del client a les interfícies d'usuari.</li><li>Es poden utilitzar biblioteques i frameworks com jQuery per simplificar el desenvolupament.</li></ul></li><li><strong>CSS (Fulls d'Estil en Cascada):</strong><ul><li>S'utilitzen fulls d'estil CSS per definir el disseny i la presentació visual de les pàgines web.</li><li>Drupal permet la integració de sistemes de disseny responsiu utilitzant tècniques CSS.</li></ul></li><li><strong>HTML5 (Llenguatge de Marcatge):</strong><ul><li>Drupal genera HTML5, l'última versió del llenguatge de marcatge, per garantir la compatibilitat amb els estàndards web moderns.</li></ul></li><li><strong>Composer (Gestor de Dependències de PHP):</strong><ul><li>Composer s'emplea per gestionar les dependències i llibreries de tercers utilitzades en un projecte Drupal.</li><li>Facilita la instal·lació i actualització de paquets i llibreries.</li></ul></li><li><strong>Git (Control de Versions):</strong><ul><li>Git s'utilitza per al control de versions del codi font de Drupal i les seves personalitzacions.</li><li>Permet el seguiment de canvis, la col·laboració entre desenvolupadors i la gestió de branques.</li></ul></li><li><strong>Drush (Interfície de Línia de Comandes):</strong><ul><li>Drush és una interfície de línia de comandes que simplifica tasques administratives i de desenvolupament a Drupal.</li><li>Facilita l'execució de comandes per a la gestió de mòduls, temes, actualitzacions, entre altres.</li></ul></li><li><strong>Servidors Web (Apache, Nginx):</strong><ul><li>Drupal pot ser desplegat en servidors web com Apache o Nginx per gestionar les sol·licituds HTTP.</li></ul></li><li><strong>Sistema de Gestió de Configuració:</strong><ul><li>Drupal 8 i versions posteriors inclouen un sistema de gestió de configuració que permet exportar i importar configuracions del lloc, facilitant el seu desplegament i manteniment.</li></ul></li></ol><p>Aquestes tecnologies treballen conjuntament per oferir un entorn de desenvolupament robust i flexible en projectes basats en Drupal.</p><p><em>Aqui un exemple de funcionalitats creades amb aquestes eines:</em></p><h4>Subtema creat a partir de Radix</h4><p>Un tema dissenyat amb fortes conviccions estilístiques i tècniques. El seu enfocament distintiu s'enfoca a proporcionar una estructura sòlida i modular, posant èmfasi en la simplicitat i el rendiment. Basat en l'experiència acumulada al llarg dels anys, Radix serveix com a punt de partida sòlid per al desenvolupament de temes personalitzats a Drupal. La seva arquitectura ben organitzada i la seva flexibilitat han portat a la creació de nombrosos temes i projectes derivats al llarg del temps. En adoptar Radix com a base del projecte personalitzat, es busca aprofitar aquests avantatges, incorporant les millors pràctiques establertes en el desenvolupament de temes dins de l'ecosistema de Drupal.</p><p>Com altres tecnologies a destacar en la creació del tema són: HTML, CSS, SASS i JS.</p><h4>Disseny de les entrades</h4><p>Les entrades es realitzen amb el mòdul <a href="https://www.drupal.org/project/commerce_ticketing">https://www.drupal.org/project/commerce_ticketing</a> , el qual fa servir <a href="https://www.drupal.org/project/entity_print">https://www.drupal.org/project/entity_print</a> per fer els pdfs.</p><h4>Aplicació de control d'entrades</h4><p>Barcode checkr: <a href="https://gitlab.com/communia/barcode-checkr">https://gitlab.com/communia/barcode-checkr</a> , una aplicació html en vue feta per communia.org, serà la que podrà controlar si una entrada és vàlida o no.  </p><p>El funcionament està explicat a <a href="https://gitlab.com/communia/barcode-checkr">https://gitlab.com/communia/barcode-checkr</a> .</p><p>Plan ref: <a href="https://gitlab.com/communia/barcode-checkr/-/releases">https://gitlab.com/communia/barcode-checkr/-/releases</a></p><h4>Restricció d'entrades per soci</h4><p>Amb el mòdul <a href="https://gitlab.com/communia/jazz-d10/-/tree/main/web/modules/custom/commerce_role_product_variation?ref_type=heads">commerce_role_product_variation</a> Es restringeix la disponibilitat de productes a determinats usuaris.</p><h4>Subpàgines que mostren un contingut concret:</h4><p>Mitjançant mòduls propis podem fer "subsites" com les de cada festival de jazz.</p><h4> </h4><h3>Funcionalitats i caracteristiques implementades</h3><h4>Migració de continguts D7 -&gt; D10</h4><p>Importació de continguts, usuaris, fitxers, categories... amb els seus camps i rutes, així com les relacions entre ells, a entitats de Drupal segons s'hagi acordat en un estudi previ. Sobre els continguts cal tenir en compte la relació entre instrument, artista, banda, concert i esdeveniment, així com la relació d’aquests continguts amb tota la resta de continguts i altres entitats relacionades (àmbits, espais, multimèdia, taxonomies, entrades...).</p><p>És un dels processos més entretingut i laboriós on s’han de definir els mapejos, escollir que s'importa, especificar els camins per dur-ho a terme i definir estratègies per les importacions incrementals. Es realitzarà una primera gran migració i posteriorment algunes migracions incrementals, fins a l'última migració incremental abans de realitzar el canvi.</p><h4>Drupal tema</h4><p>Estendre la imatge corporativa a tot el lloc web. Disseny responsiu i que respecti els estàndards web.  El nou tema es farà a partir del desplegament d’un subtema basat en Drupal Radix (que utilitza Bootstrap 5), el qual està orientat a components de plantilles + scss + js.</p><p>El tema s’ha de re-escriure de nou, per tant, si no s’incorpora una nova proposta de disseny gràfic, es desplegarà el disseny actual, tenint en compte que algunes qüestions es poden resoldre de forma similar, però amb marge de millora i/o modificació. </p><h4>Sistema de traduccions</h4><p>Instal·lació i configuració del motor de traduccions. Implementació d’un sistema de traduccions que permeti gestionar i traduir els continguts del web així com definir la navegació de les usuàries per aquests.</p><h4>Drupal Commerce</h4><p>Disseny i implementació de les funcionalitats bàsiques d'una tenda online amb Drupal Commerce. Inclou passarel·la de pagament amb stripe, control de stock, gestor de productes i variacions de productes, categories de productes, cistell de compra, sistema d'usuaris simplificat amb perfils de localització (dades de facturació i enviament, gestió de comandes, gestió de taxes... funcionalitats bàsiques d'una tenda.</p><p>Inclou el sistema d’entrades per diferents tipologies de socis/es, tiquets en pdf i integració amb el sistema de control d’entrades a la taquilla física. També permetrà la venta de merchandising.</p><h4>Sistema de Newsletters</h4><p>Sistema de subscripció, enviament i plantilles per butlletins, integrat amb el contingut de Drupal.</p><p>Aquest sistema serà plantejat una mica diferent al actual. Es maquetaran els butlletins amb Drupal Layout Builder i s'emmagatzemarà de forma estàtica per tenir major control sobre el contingut auto-construït i enviat. El sistema seguirà basat en Drupal SimpleNews.</p><h4>Cerca avançada</h4><p>Sistema de cerca mitjançant facets i productes relacionats. Fa referència a la gestió del arxiu històric.</p><h4>Notícies i blog</h4><p>Un espai d’actualitat on mostrar continguts de tipus notícies amb suport audiovisual (fotos, vídeos, finestres externes...) classificat per seccions. Disponibilitat d’eines per destacar o modificar l’ordre, així com l’aspecte en resums i targetes en portades de seccions. Tot això sobre una interfície d’administració per poder gestionar continguts publicats, amb la capacitat d’afegir, editar o eliminar continguts. També poder establir fluxos de treball adaptats per realitzar tasques de redacció, moderació i publicació.</p><h4>Layout Builder</h4><p>Mitjançant sistemes de Drupal paragraph i/o Drupal Layout Builder, o Drupal Panells, habilitar usuàries avançades personalitzar composicions d'alguns apartats del web.</p><p>Layout Builder serà implementat per els sistema de butlletins i s’utilitzarà també per maquetar portada, pàgines bàsiques i àmbits.</p><p>Proporcionarà major llibertat de maquetació als usuaris amb rols de permisos del tipus «content managers» i possibilitat de fer pagines intermedies més treballades de forma autònoma.</p><h4>Arxiu Documental</h4><p>Gestió de col·leccions amable, actualitzable, i extremadament potent. Opcions flexibles ja sigui per vídeos, àudios, documents, esdeveniments, fotografies…</p><h4>Pack de SEO</h4><p>SEO i web semàntica, web crawler, API's tercers. Assegurar que el contingut de la web compartit a les xarxes socials que més s'utilitzen, agregadors de contingut i indexadors de contingut més populars accedeixin i ofereixen de la millor manera possible el contingut o el resum que en mostren implementant les recomanacions i directius d'algunes API's d'aquests llocs.</p><p>Bàsicament assegurarem un bona implementació d’OpenGraph, Schema.org, Twitter Cards, així com bones pràctiques en quan a coherència en l’arbre DOM, urls netes i canonicals, semàntica en les urls, sitemaps...</p><h4>Gestió multimèdia</h4><p>Un gestor dedicat per l’organització, la cerca i per poder compartir fitxers multimèdia utilitzant com a font diferents proveïdors.</p><h4>Sistema de formularis</h4><p>Sistema de formularis de contacte, subscripció i creació dels continguts a través de formularis editables per l’administrador.</p><h4>Integració de Xarxes socials</h4><p>Integració xarxes socials.</p><h4>Atribució i llicència</h4><p>Sistema d'autoria / llicencies pels continguts de tipus media. Permet implementar autoria/llicencies en els mitjans multimèdia.</p><h2>Desenvolupament i Codificació</h2><h3>Metodologia de Desenvolupament</h3><p>La nostra metodologia de desenvolupaments emprada durant els desenvolupaments és un mix entre les dues de les més conegudes com a <strong>SCRUM</strong> i <strong>Kanban</strong> encara que no sigui estrictament una metodologia àgil, ens serveix per donar un enfocament visual per gestionar les fases i tasques del projecte.</p><p>La combinació de les dues metodologies ens permet desenvolupar projectes de diferents escales de manera efectiva, segmentant les fases del projecte per tenir una combinació equilibrada entre estructura i flexibilitat en el desenvolupament. La nostra tècnica fusiona els elements clau de les dues metodologies incorporant un enfocament àgil, estructurant les fases del projecte amb iteracions fixes de SCRUM, amb la flexibilitat visual i continua del metode Kanban. Fent servir rols i esdeveniments de SCRUM, però amb una duració dels sprints més flexible amb la possibilitat de treballar de manera contínua.</p><h3>Codi Font</h3><p>Drupal utilitza una estructura de carpetes específica per organitzar els arxius i recursos del projecte.</p><p>El tema empleat és Radix, basat en plantilles de Twig per definir l'estructura de l'HTML del tema. La personalització dels elements webs està definit de manera que cada element és un component associat a la seva plantilla, on tots aquests components van acompanyats dels seus fitxers CSS i JS per funcionalitats addicionals.</p><p>Treballar amb un sistema estructurat de carpetes, plantilles i components de Twig a Drupal ofereix organització, separació de responsabilitats i facilitat de manteniment. Permet la reutilització eficient de codi, facilita la personalització del tema i fomenta la col·laboració entre desenvolupadors i dissenyadors. La sintaxi clara de Twig i l'organització modular contribueixen al compliment d'estàndards i bones pràctiques en el desenvolupament web.</p><h3>Control de Versions</h3><p>El codi del projecte està gestionat amb l'eina de control Gitlab, un sistema essencial pel control de versions, proporcionant un historial detallat de canvis i facilitant la col·laboració. Permet la ramificació i fusió eficient, etiquetar versions, treballar en paral·lel i gestionar conflictes. Amb repositoris remots, facilita la col·laboració a equips distribuïts. És personalitzable i compatible amb la integració contínua. La flexibilitat de Git permet un control precís del codi, gestió de canvis experimentals i revertir ajustos, contribuint a un desenvolupament de programari eficient i eficaç.</p></div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--blog--rss.html.twig * field--node--field-tags--blog.html.twig * field--node--field-tags.html.twig * field--node--blog.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-inline clearfix"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> <div class="field__item"><a href="/ca/etiquetes/jazzterrassaorg" hreflang="ca">jazzterrassa.org</a></div> <div class="field__item"><a href="/en/etiquetes/communia" hreflang="en">communia</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> Tue, 16 Jan 2024 14:00:07 +0000 victor 6569 at https://planet.communia.org https://planet.communia.org/en/content/actualitzem-jazzterrassaorg#comments Recipe to migrate Drupal 7 Organic Groups to Drupal 9 Group https://planet.communia.org/en/content/recipe-migrate-drupal-7-organic-groups-drupal-9-group <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--blog--rss.html.twig * field--node--title--blog.html.twig x field--node--title.html.twig * field--node--blog.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>Recipe to migrate Drupal 7 Organic Groups to Drupal 9 Group</span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--blog--rss.html.twig * field--node--uid--blog.html.twig x field--node--uid.html.twig * field--node--blog.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/1" class="visually-hidden p-author h-card" rel="author" title="kinta">kinta <img src="" alt="kinta" /> </a> <a title="View user profile." href="/en/users/kinta">kinta</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--blog--rss.html.twig * field--node--created--blog.html.twig x field--node--created.html.twig * field--node--blog.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2021-10-03T22:43:19+02:00" title="Sunday, October 3, 2021 - 22:43">Sun, 10/03/2021 - 22:43</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--blog--rss.html.twig * field--node--body--blog.html.twig * field--node--body.html.twig * field--node--blog.html.twig * field--body.html.twig * field--text-with-summary.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="body field field--node-body field--name-body field--type-text-with-summary field--label-hidden field__item"><p data-sourcepos="3:1-3:511" dir="auto">Despite there are some guides about migrating from OG to Group, as the well written <a href="https://thinktandem.io/blog/2018/03/30/migrating-drupal-7-organic-groups-to-drupal-8-group/" rel="nofollow noreferrer noopener" target="_blank">https://thinktandem.io/blog/2018/03/30/migrating-drupal-7-organic-groups-to-drupal-8-group/</a> , and other guidelines such as <a href="https://www.drupal.org/project/group/issues/2826544" rel="nofollow noreferrer noopener" target="_blank">https://www.drupal.org/project/group/issues/2826544</a> companion of <a href="https://gitlab.com/geeks4change/hubs4change/h4c/-/tree/608842e73cc02c45deede42556693a9db2a7fc37/modules_dev/h4c_migrate/config/install">https://gitlab.com/geeks4change/hubs4change/h4c/-/tree/608842e73cc02c45deede42556693a9db2a7fc37/modules_dev/h4c_migrate/config/install</a> or <a href="https://www.drupal.org/node/2797845" rel="nofollow noreferrer noopener" target="_blank">https://www.drupal.org/node/2797845</a> . It's really adapted to your environment how you gonna carry on.</p> <p data-sourcepos="5:1-5:295" dir="auto">This is a short and crash guide that we at communia have done to complete the migrations. When Carrying on this migration must be estimated if the effort of writing code, in a form of migrate plugin classes or yml's, is worth enough than cooking csv's using spreadsheet skills. We've done both.</p> <p data-sourcepos="7:1-8:334" dir="auto">After importing everything from a standard drupal migration from 7 to 8(with what core offers), the groups types must be created, also their group roles and their group content types in a manual way. The site to be recreated is a news portal that takes headlines from several sites, and each blog or external blog is administrated in group, so being a group can be useful to add dynamic members or authors. So in the example I need to create two group types ( for each node enabled as organic group in d7), bundles are (machine)named:</p> <ul data-sourcepos="10:1-13:0" dir="auto"><li data-sourcepos="10:1-11:148"><code>blog</code>(it was wrongly named previously bloc). I want also to add a role for each group type as admin to add granularity in permissions. So is needed to create the role admin for each type named:</li> <li data-sourcepos="12:1-13:0"><code>blog_group-admin</code> for <code>blog</code> group types.</li> </ul><p data-sourcepos="14:1-14:385" dir="auto">I also marked the automatic role assignment for creators as admin role. It carries on a little of complexity in membership migrations as we must take care that memberships aren't duplicated (hence the plugin created below), as one membership will be created when groups are created on groups migration step, and another one when we import the memberships on memberships migration step.</p> <p data-sourcepos="16:1-16:190" dir="auto">So we need a simple module to add the migration configurations in yml, and it will aid us to create some extra plugins and hang on some hooks as <code>hook_migrate_prepare_row</code>. The module tree:</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="18:1-41:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">.</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">├── group-content-export.csv.template</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">├── group-memberships.csv.template</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">├── migrations</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">│   ├── d7_node_complete_og_to_canal_blog_extern.yml</span> <span class="line" id="LC6" lang="plaintext" xml:lang="plaintext">│   ├── d7_node_complete_og_to_canal_proposta_externa.yml</span> <span class="line" id="LC7" lang="plaintext" xml:lang="plaintext">│   ├── rename_d7_node_complete_blog_post.yml</span> <span class="line" id="LC8" lang="plaintext" xml:lang="plaintext">│   ├── rename_d7_node_complete_podcast.yml</span> <span class="line" id="LC9" lang="plaintext" xml:lang="plaintext">│   ├── upgrade_d7_node_og_blog_content.yml</span> <span class="line" id="LC10" lang="plaintext" xml:lang="plaintext">│   ├── upgrade_d7_node_og_blog_translation.yml</span> <span class="line" id="LC11" lang="plaintext" xml:lang="plaintext">│   ├── upgrade_d7_node_og_blog.yml</span> <span class="line" id="LC12" lang="plaintext" xml:lang="plaintext">│   └── upgrade_d7_user_og_blog_memberships.yml</span> <span class="line" id="LC13" lang="plaintext" xml:lang="plaintext">├── og_migrate_group.info.yml</span> <span class="line" id="LC14" lang="plaintext" xml:lang="plaintext">├── og_migrate_group.module</span> <span class="line" id="LC15" lang="plaintext" xml:lang="plaintext">├── README.md</span> <span class="line" id="LC16" lang="plaintext" xml:lang="plaintext">└── src</span> <span class="line" id="LC17" lang="plaintext" xml:lang="plaintext"> └── Plugin</span> <span class="line" id="LC18" lang="plaintext" xml:lang="plaintext"> └── migrate</span> <span class="line" id="LC19" lang="plaintext" xml:lang="plaintext"> ├── process</span> <span class="line" id="LC20" lang="plaintext" xml:lang="plaintext">    ├── GroupCreator.php</span> <span class="line" id="LC21" lang="plaintext" xml:lang="plaintext">    ├── SkipCreator.php</span> <span class="line" id="LC22" lang="plaintext" xml:lang="plaintext">    └── SkipOnNotEmpty.php</span></code></pre><p data-sourcepos="43:1-43:54" dir="auto">Go to gitlab.com to get the actual code for each file: <a href="https://gitlab.com/communia/og_migrate_group">https://gitlab.com/communia/og_migrate_group</a></p> <p data-sourcepos="45:1-45:21" dir="auto">So now let's yamling.</p> <h2 data-sourcepos="47:1-47:9" dir="auto">Groups</h2> <p data-sourcepos="49:1-49:184" dir="auto">As Organic groups usually was assigned to nodes (if that's not the case cook it as you need), you 'll see it will be based in <code>d7_node</code> migration, so <code>d7_node</code> must be migrated before.</p> <p data-sourcepos="51:1-51:41" dir="auto"><code>migrations/upgrade_d7_node_og_blog.yml</code>:</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="53:1-109:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">langcode: en</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">status: true</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">dependencies: { }</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">id: upgrade_d7_node_og_blog</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">class: Drupal\migrate\Plugin\Migration</span> <span class="line" id="LC6" lang="plaintext" xml:lang="plaintext">field_plugin_method: null</span> <span class="line" id="LC7" lang="plaintext" xml:lang="plaintext">cck_plugin_method: null</span> <span class="line" id="LC8" lang="plaintext" xml:lang="plaintext">migration_tags:</span> <span class="line" id="LC9" lang="plaintext" xml:lang="plaintext"> - 'Drupal 7'</span> <span class="line" id="LC10" lang="plaintext" xml:lang="plaintext">migration_group: insert_group</span> <span class="line" id="LC11" lang="plaintext" xml:lang="plaintext">label: 'Insert OG Bloc group'</span> <span class="line" id="LC12" lang="plaintext" xml:lang="plaintext">source:</span> <span class="line" id="LC13" lang="plaintext" xml:lang="plaintext"> plugin: d7_node</span> <span class="line" id="LC14" lang="plaintext" xml:lang="plaintext"> # The node bundle that must be get from source</span> <span class="line" id="LC15" lang="plaintext" xml:lang="plaintext"> node_type: bloc</span> <span class="line" id="LC16" lang="plaintext" xml:lang="plaintext">process:</span> <span class="line" id="LC17" lang="plaintext" xml:lang="plaintext"> type:</span> <span class="line" id="LC18" lang="plaintext" xml:lang="plaintext"> plugin: default_value</span> <span class="line" id="LC19" lang="plaintext" xml:lang="plaintext"> # put blog as group type (it can be simple mapped here but this is to show how default values work)</span> <span class="line" id="LC20" lang="plaintext" xml:lang="plaintext"> default_value: blog</span> <span class="line" id="LC21" lang="plaintext" xml:lang="plaintext"> id: nid</span> <span class="line" id="LC22" lang="plaintext" xml:lang="plaintext"> # The next uid will be the creator, if default role is marked it will be assigned to this user in group realm</span> <span class="line" id="LC23" lang="plaintext" xml:lang="plaintext"> uid: node_uid</span> <span class="line" id="LC24" lang="plaintext" xml:lang="plaintext"> label: title</span> <span class="line" id="LC25" lang="plaintext" xml:lang="plaintext"> path: alias</span> <span class="line" id="LC26" lang="plaintext" xml:lang="plaintext"> field_description: body</span> <span class="line" id="LC27" lang="plaintext" xml:lang="plaintext"> # An illustration of how an image in a group could be used, images must be migrated before as usual (in this example it is not using media module).</span> <span class="line" id="LC28" lang="plaintext" xml:lang="plaintext"> field_imatge_blogextern:</span> <span class="line" id="LC29" lang="plaintext" xml:lang="plaintext"> plugin: sub_process</span> <span class="line" id="LC30" lang="plaintext" xml:lang="plaintext"> source: field_imatge_blogextern</span> <span class="line" id="LC31" lang="plaintext" xml:lang="plaintext"> process:</span> <span class="line" id="LC32" lang="plaintext" xml:lang="plaintext"> target_id: fid</span> <span class="line" id="LC33" lang="plaintext" xml:lang="plaintext"> alt: alt</span> <span class="line" id="LC34" lang="plaintext" xml:lang="plaintext"> title: title</span> <span class="line" id="LC35" lang="plaintext" xml:lang="plaintext"> width: width</span> <span class="line" id="LC36" lang="plaintext" xml:lang="plaintext"> height: height</span> <span class="line" id="LC37" lang="plaintext" xml:lang="plaintext"> # Here an illustration of how a term could be assigned, once again terms must exist before migrating this.</span> <span class="line" id="LC38" lang="plaintext" xml:lang="plaintext"> field_tipus_bloc:</span> <span class="line" id="LC39" lang="plaintext" xml:lang="plaintext"> plugin: sub_process</span> <span class="line" id="LC40" lang="plaintext" xml:lang="plaintext"> source: taxonomy_vocabulary_7</span> <span class="line" id="LC41" lang="plaintext" xml:lang="plaintext"> process:</span> <span class="line" id="LC42" lang="plaintext" xml:lang="plaintext"> target_id:</span> <span class="line" id="LC43" lang="plaintext" xml:lang="plaintext"> plugin: entity_lookup</span> <span class="line" id="LC44" lang="plaintext" xml:lang="plaintext"> source: tid</span> <span class="line" id="LC45" lang="plaintext" xml:lang="plaintext"> value_key: tid</span> <span class="line" id="LC46" lang="plaintext" xml:lang="plaintext"> bundle_key: vid</span> <span class="line" id="LC47" lang="plaintext" xml:lang="plaintext"> bundle: vocabulary_7</span> <span class="line" id="LC48" lang="plaintext" xml:lang="plaintext"> entity_type: taxonomy_term</span> <span class="line" id="LC49" lang="plaintext" xml:lang="plaintext"> revision_uid: revision_uid</span> <span class="line" id="LC50" lang="plaintext" xml:lang="plaintext"> revision_log: log</span> <span class="line" id="LC51" lang="plaintext" xml:lang="plaintext"> revision_timestamp: timestamp</span> <span class="line" id="LC52" lang="plaintext" xml:lang="plaintext">destination:</span> <span class="line" id="LC53" lang="plaintext" xml:lang="plaintext"> # It's a group</span> <span class="line" id="LC54" lang="plaintext" xml:lang="plaintext"> plugin: 'entity:group'</span> <span class="line" id="LC55" lang="plaintext" xml:lang="plaintext">migration_dependencies: null</span></code></pre><p data-sourcepos="111:1-111:61" dir="auto">Once module is installed this migration can be imported with:</p> <p data-sourcepos="113:1-113:54" dir="auto"><code>vendor/drush/drush/drush mim upgrade_d7_node_og_blog</code></p> <p data-sourcepos="115:1-115:21" dir="auto">and rolled back with:</p> <p data-sourcepos="117:1-117:67" dir="auto"><code>vendor/drush/drush/drush migrate:rollback upgrade_d7_node_og_blog</code></p> <p data-sourcepos="119:1-119:102" dir="auto">if error locks any migration state saying it's currently importing (when is not) it can be fixed with:</p> <p data-sourcepos="121:1-121:52" dir="auto"><code>drush migrate:reset-status upgrade_d7_node_og_blog</code></p> <p data-sourcepos="124:1-124:513" dir="auto">It's common that sometimes a crufty translation exists, in this example we found two extra fields that covered the translation, instead of using entity_translate or node_translate so <code>field_titolbloces</code> means <code>title</code> field in spanish and <code>field_descripciobloces</code> means <code>field_description</code> in spanish . This configuration will update existing groups translating it. Must be noted that group type must be marked as translatable editing the group type settings. <code>migrations/upgrade_d7_node_og_blog_translation.yml</code>:</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="126:1-166:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">langcode: en</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">status: true</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">dependencies: { }</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">id: upgrade_d7_node_og_blog_translation</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">class: Drupal\migrate\Plugin\Migration</span> <span class="line" id="LC6" lang="plaintext" xml:lang="plaintext">migration_tags:</span> <span class="line" id="LC7" lang="plaintext" xml:lang="plaintext"> - 'Drupal 7'</span> <span class="line" id="LC8" lang="plaintext" xml:lang="plaintext">migration_group: insert_group</span> <span class="line" id="LC9" lang="plaintext" xml:lang="plaintext">label: 'Insert OG blog group translation'</span> <span class="line" id="LC10" lang="plaintext" xml:lang="plaintext">migration_dependencies:</span> <span class="line" id="LC11" lang="plaintext" xml:lang="plaintext"> required:</span> <span class="line" id="LC12" lang="plaintext" xml:lang="plaintext"> - upgrade_d7_node_og_blog</span> <span class="line" id="LC13" lang="plaintext" xml:lang="plaintext">source:</span> <span class="line" id="LC14" lang="plaintext" xml:lang="plaintext"> plugin: d7_node</span> <span class="line" id="LC15" lang="plaintext" xml:lang="plaintext"> node_type: 'bloc'</span> <span class="line" id="LC16" lang="plaintext" xml:lang="plaintext">process:</span> <span class="line" id="LC17" lang="plaintext" xml:lang="plaintext"> # Will update the previously imported groups</span> <span class="line" id="LC18" lang="plaintext" xml:lang="plaintext"> id:</span> <span class="line" id="LC19" lang="plaintext" xml:lang="plaintext"> plugin: migration_lookup</span> <span class="line" id="LC20" lang="plaintext" xml:lang="plaintext"> source: nid</span> <span class="line" id="LC21" lang="plaintext" xml:lang="plaintext"> migration: upgrade_d7_node_og_blog</span> <span class="line" id="LC22" lang="plaintext" xml:lang="plaintext"> # Where can be found the label in spanish</span> <span class="line" id="LC23" lang="plaintext" xml:lang="plaintext"> label:</span> <span class="line" id="LC24" lang="plaintext" xml:lang="plaintext"> plugin: get</span> <span class="line" id="LC25" lang="plaintext" xml:lang="plaintext"> source: field_titolbloces</span> <span class="line" id="LC26" lang="plaintext" xml:lang="plaintext"> # Where can be found the description in spanish</span> <span class="line" id="LC27" lang="plaintext" xml:lang="plaintext"> field_description:</span> <span class="line" id="LC28" lang="plaintext" xml:lang="plaintext"> plugin: get</span> <span class="line" id="LC29" lang="plaintext" xml:lang="plaintext"> source: field_descripciobloces</span> <span class="line" id="LC30" lang="plaintext" xml:lang="plaintext"> # default value of langcode</span> <span class="line" id="LC31" lang="plaintext" xml:lang="plaintext"> langcode:</span> <span class="line" id="LC32" lang="plaintext" xml:lang="plaintext"> plugin: default_value</span> <span class="line" id="LC33" lang="plaintext" xml:lang="plaintext"> default_value: es</span> <span class="line" id="LC34" lang="plaintext" xml:lang="plaintext"> type:</span> <span class="line" id="LC35" lang="plaintext" xml:lang="plaintext"> plugin: default_value</span> <span class="line" id="LC36" lang="plaintext" xml:lang="plaintext"> default_value: blog</span> <span class="line" id="LC37" lang="plaintext" xml:lang="plaintext">destination:</span> <span class="line" id="LC38" lang="plaintext" xml:lang="plaintext"> plugin: 'entity:group'</span> <span class="line" id="LC39" lang="plaintext" xml:lang="plaintext"> translations: true</span></code></pre><p data-sourcepos="168:1-168:36" dir="auto">This migration can be imported with:</p> <p data-sourcepos="170:1-170:66" dir="auto"><code>vendor/drush/drush/drush mim upgrade_d7_node_og_blog_translation</code></p> <p data-sourcepos="172:1-172:21" dir="auto">and rolled back with:</p> <p data-sourcepos="174:1-174:79" dir="auto"><code>vendor/drush/drush/drush migrate:rollback upgrade_d7_node_og_blog_translation</code></p> <p data-sourcepos="176:1-176:102" dir="auto">if error locks any migration state saying it's currently importing (when is not) it can be fixed with:</p> <p data-sourcepos="178:1-178:64" dir="auto"><code>drush migrate:reset-status upgrade_d7_node_og_blog_translation</code></p> <h1 data-sourcepos="180:1-180:13" dir="auto">Memberships</h1> <p data-sourcepos="182:1-182:196" dir="auto">As Organic groups memberships usually was assigned to users (if that's not the case cook it as you need), you 'll see it will be based in <code>d7_user</code> migration, so <code>d7_user</code> must be migrated before.</p> <p data-sourcepos="184:1-184:192" dir="auto">I found that here is easier to use csv, than to carry on too much code to take from here and there, so I have created a view of og memberships with data export in source site. View fields are:</p> <ul data-sourcepos="186:1-190:0" dir="auto"><li data-sourcepos="186:1-186:38">OG membership: Og membership ID (id)</li> <li data-sourcepos="187:1-187:32">OG membership: Entity id (uid)</li> <li data-sourcepos="188:1-188:31">OG membership: Group ID (gid)</li> <li data-sourcepos="189:1-190:0">(Content entity referenced from og_user_node) Content: Identificator (UID) of the author (gid_uid)</li> </ul><p data-sourcepos="191:1-191:23" dir="auto">View relationships are:</p> <ul data-sourcepos="193:1-196:0" dir="auto"><li data-sourcepos="193:1-193:140">OG user node target id. (Content entity referenced from og_user_node) : A bridge to the Content entity that is referenced via og_user_node</li> <li data-sourcepos="194:1-196:0">OG membership: User from OG membership (REQUIRED)</li> </ul><p data-sourcepos="197:1-197:39" dir="auto">If you prefer the sql of that view was:</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="198:1-210:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">SELECT og_membership.id AS id, og_membership.etid AS og_membership_etid, og_membership.gid AS og_membership_gid, node_og_membership.uid AS node_og_membership_uid, 'membership_export:page' AS view_name</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">FROM</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">{og_membership} og_membership</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">LEFT JOIN {node} node_og_membership ON og_membership.gid = node_og_membership.nid</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">LEFT JOIN {field_data_og_user_node} node_og_membership__field_data_og_user_node ON node_og_membership.nid = node_og_membership__field_data_og_user_node.og_user_node_target_id AND (node_og_membership__field_data_og_user_node.entity_type = 'user' AND node_og_membership__field_data_og_user_node.deleted = '0')</span> <span class="line" id="LC6" lang="plaintext" xml:lang="plaintext">LEFT JOIN {users} og_user_node_node ON node_og_membership__field_data_og_user_node.entity_id = og_user_node_node.uid</span> <span class="line" id="LC7" lang="plaintext" xml:lang="plaintext">LEFT JOIN {field_data_og_group_ref} node_og_membership__field_data_og_group_ref ON node_og_membership.nid = node_og_membership__field_data_og_group_ref.og_group_ref_target_id AND (node_og_membership__field_data_og_group_ref.entity_type = 'user' AND node_og_membership__field_data_og_group_ref.deleted = '0')</span> <span class="line" id="LC8" lang="plaintext" xml:lang="plaintext">LEFT JOIN {users} og_group_ref_node ON node_og_membership__field_data_og_group_ref.entity_id = og_group_ref_node.uid</span> <span class="line" id="LC9" lang="plaintext" xml:lang="plaintext">INNER JOIN {users} users_og_membership ON og_membership.etid = users_og_membership.uid AND (og_membership.entity_type = 'user')</span> <span class="line" id="LC10" lang="plaintext" xml:lang="plaintext">LEFT JOIN {profile} profile_users ON users_og_membership.uid = profile_users.uid</span> </code></pre><p data-sourcepos="212:1-212:83" dir="auto">Anyway it must output what's in group-memberships.csv.template. Here the csv fields</p> <ul data-sourcepos="214:1-218:0" dir="auto"><li data-sourcepos="214:1-214:59"><code>id</code> The id of the membership(rarely used, but preserved)</li> <li data-sourcepos="215:1-215:55"><code>uid</code>, The user id of the membership (so the member).</li> <li data-sourcepos="216:1-216:49"><code>gid</code>, The id of the group that user is member.</li> <li data-sourcepos="217:1-218:0"><code>gid_uid</code>, The creator of the group (not used in migration as we take it with a dedicated migration plugin).</li> </ul><pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="219:1-224:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">"id","uid","gid","gid_uid"</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">"46","1","14829","1"</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">"50","4","14814","4"</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">"52","12","14834","1"</span></code></pre><p data-sourcepos="226:1-226:39" dir="auto">And here the migration that carries on:</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="228:1-314:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">langcode: en</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">status: true</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">dependencies: { }</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">id: upgrade_d7_user_og_blog_memberships</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">class: Drupal\migrate\Plugin\Migration</span> <span class="line" id="LC6" lang="plaintext" xml:lang="plaintext">field_plugin_method: null</span> <span class="line" id="LC7" lang="plaintext" xml:lang="plaintext">cck_plugin_method: null</span> <span class="line" id="LC8" lang="plaintext" xml:lang="plaintext">migration_tags:</span> <span class="line" id="LC9" lang="plaintext" xml:lang="plaintext"> - 'Drupal 7 og'</span> <span class="line" id="LC10" lang="plaintext" xml:lang="plaintext">migration_group: insert_group</span> <span class="line" id="LC11" lang="plaintext" xml:lang="plaintext">label: 'Insert Group Membership'</span> <span class="line" id="LC12" lang="plaintext" xml:lang="plaintext">source:</span> <span class="line" id="LC13" lang="plaintext" xml:lang="plaintext"> plugin: csv</span> <span class="line" id="LC14" lang="plaintext" xml:lang="plaintext"> # Must be obtained from source with some exporter (e.g. views data export) and placed in this path</span> <span class="line" id="LC15" lang="plaintext" xml:lang="plaintext"> path: 'public://imports/group-export.csv'</span> <span class="line" id="LC16" lang="plaintext" xml:lang="plaintext"> header_row_count: 1</span> <span class="line" id="LC17" lang="plaintext" xml:lang="plaintext"> ids:</span> <span class="line" id="LC18" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC19" lang="plaintext" xml:lang="plaintext"> id</span> <span class="line" id="LC20" lang="plaintext" xml:lang="plaintext"> column_names:</span> <span class="line" id="LC21" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC22" lang="plaintext" xml:lang="plaintext"> id: Identifier</span> <span class="line" id="LC23" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC24" lang="plaintext" xml:lang="plaintext"> uid: UserID</span> <span class="line" id="LC25" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC26" lang="plaintext" xml:lang="plaintext"> gid: Group</span> <span class="line" id="LC27" lang="plaintext" xml:lang="plaintext"> delimiter: ','</span> <span class="line" id="LC28" lang="plaintext" xml:lang="plaintext"> enclosure: '"'</span> <span class="line" id="LC29" lang="plaintext" xml:lang="plaintext">process:</span> <span class="line" id="LC30" lang="plaintext" xml:lang="plaintext"> label: uid</span> <span class="line" id="LC31" lang="plaintext" xml:lang="plaintext"> group_creator:</span> <span class="line" id="LC32" lang="plaintext" xml:lang="plaintext"> # TO illustrate a plugin (not useful in the process), that transforms from a group id to the uid of the group author.</span> <span class="line" id="LC33" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC34" lang="plaintext" xml:lang="plaintext"> plugin: group_creator</span> <span class="line" id="LC35" lang="plaintext" xml:lang="plaintext"> source: gid</span> <span class="line" id="LC36" lang="plaintext" xml:lang="plaintext"># -</span> <span class="line" id="LC37" lang="plaintext" xml:lang="plaintext"># plugin: callback</span> <span class="line" id="LC38" lang="plaintext" xml:lang="plaintext"># callable: var_dump</span> <span class="line" id="LC39" lang="plaintext" xml:lang="plaintext"> # Now will check that group is there via previous migration lookup (the first one we did):</span> <span class="line" id="LC40" lang="plaintext" xml:lang="plaintext"> gid:</span> <span class="line" id="LC41" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC42" lang="plaintext" xml:lang="plaintext"> plugin: migration_lookup</span> <span class="line" id="LC43" lang="plaintext" xml:lang="plaintext"> migration: upgrade_d7_node_og_blog</span> <span class="line" id="LC44" lang="plaintext" xml:lang="plaintext"> no_stub: true</span> <span class="line" id="LC45" lang="plaintext" xml:lang="plaintext"> source: gid</span> <span class="line" id="LC46" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC47" lang="plaintext" xml:lang="plaintext"> plugin: skip_on_empty</span> <span class="line" id="LC48" lang="plaintext" xml:lang="plaintext"> method: row</span> <span class="line" id="LC49" lang="plaintext" xml:lang="plaintext"> message: 'gid is missing'</span> <span class="line" id="LC50" lang="plaintext" xml:lang="plaintext"> entity_id:</span> <span class="line" id="LC51" lang="plaintext" xml:lang="plaintext"> # To illustrate how the previous `group_creator` could be injected here( not useful):</span> <span class="line" id="LC52" lang="plaintext" xml:lang="plaintext"> #-</span> <span class="line" id="LC53" lang="plaintext" xml:lang="plaintext"> # plugin: callback</span> <span class="line" id="LC54" lang="plaintext" xml:lang="plaintext"> # callable: var_dump</span> <span class="line" id="LC55" lang="plaintext" xml:lang="plaintext"> # source: "@group_creator"</span> <span class="line" id="LC56" lang="plaintext" xml:lang="plaintext"> # The plugin created to stop creating membership if current row user uid is the same as the group creator, to prevent duplicated members:</span> <span class="line" id="LC57" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC58" lang="plaintext" xml:lang="plaintext"> plugin: skip_creator</span> <span class="line" id="LC59" lang="plaintext" xml:lang="plaintext"> user_key: uid</span> <span class="line" id="LC60" lang="plaintext" xml:lang="plaintext"> gid_key: gid</span> <span class="line" id="LC61" lang="plaintext" xml:lang="plaintext"> method: row</span> <span class="line" id="LC62" lang="plaintext" xml:lang="plaintext"> # Finally check if user uid exists (probably if we are in this process point):</span> <span class="line" id="LC63" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC64" lang="plaintext" xml:lang="plaintext"> plugin: migration_lookup</span> <span class="line" id="LC65" lang="plaintext" xml:lang="plaintext"> migration: upgrade_d7_user</span> <span class="line" id="LC66" lang="plaintext" xml:lang="plaintext"> no_stub: true</span> <span class="line" id="LC67" lang="plaintext" xml:lang="plaintext"> source: uid</span> <span class="line" id="LC68" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC69" lang="plaintext" xml:lang="plaintext"> plugin: skip_on_empty</span> <span class="line" id="LC70" lang="plaintext" xml:lang="plaintext"> method: row</span> <span class="line" id="LC71" lang="plaintext" xml:lang="plaintext"> message: 'uid is missing'</span> <span class="line" id="LC72" lang="plaintext" xml:lang="plaintext"> # We hard code the role for all the migrated members:</span> <span class="line" id="LC73" lang="plaintext" xml:lang="plaintext"> group_roles:</span> <span class="line" id="LC74" lang="plaintext" xml:lang="plaintext"> plugin: default_value</span> <span class="line" id="LC75" lang="plaintext" xml:lang="plaintext"> default_value: blog-group_admin</span> <span class="line" id="LC76" lang="plaintext" xml:lang="plaintext"> type:</span> <span class="line" id="LC77" lang="plaintext" xml:lang="plaintext"> plugin: default_value</span> <span class="line" id="LC78" lang="plaintext" xml:lang="plaintext"> default_value: blog-group_membership</span> <span class="line" id="LC79" lang="plaintext" xml:lang="plaintext">destination:</span> <span class="line" id="LC80" lang="plaintext" xml:lang="plaintext"> # Memberships are considerated group_content also.</span> <span class="line" id="LC81" lang="plaintext" xml:lang="plaintext"> plugin: 'entity:group_content'</span> <span class="line" id="LC82" lang="plaintext" xml:lang="plaintext">migration_dependencies:</span> <span class="line" id="LC83" lang="plaintext" xml:lang="plaintext"> optional:</span> <span class="line" id="LC84" lang="plaintext" xml:lang="plaintext"> - upgrade_d7_node_og_blog</span> <span class="line" id="LC85" lang="plaintext" xml:lang="plaintext"> - d7_user</span></code></pre><p data-sourcepos="316:1-316:215" dir="auto">Note the use of <code>skip_creator</code> plugin to stop creating membership if current row user uid is the same as the group creator, to prevent duplicated members. The code of <code>src/Plugin/migrate/process/SkipCreator.php</code> is:</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="318:1-417:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">&lt;?php</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">namespace Drupal\og_migrate_group\Plugin\migrate\process;</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">use Drupal\migrate\MigrateExecutableInterface;</span> <span class="line" id="LC6" lang="plaintext" xml:lang="plaintext">use Drupal\migrate\ProcessPluginBase;</span> <span class="line" id="LC7" lang="plaintext" xml:lang="plaintext">use Drupal\migrate\MigrateException;</span> <span class="line" id="LC8" lang="plaintext" xml:lang="plaintext">use Drupal\migrate\MigrateSkipRowException;</span> <span class="line" id="LC9" lang="plaintext" xml:lang="plaintext">use Drupal\migrate\MigrateSkipProcessException;</span> <span class="line" id="LC10" lang="plaintext" xml:lang="plaintext">use Drupal\migrate\Row;</span> <span class="line" id="LC12" lang="plaintext" xml:lang="plaintext">/**</span> <span class="line" id="LC13" lang="plaintext" xml:lang="plaintext"> * Skip if user_key as uid is the creator of group with gid as in gid_key.</span> <span class="line" id="LC14" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC15" lang="plaintext" xml:lang="plaintext"> * @MigrateProcessPlugin(</span> <span class="line" id="LC16" lang="plaintext" xml:lang="plaintext"> * id = "skip_creator"</span> <span class="line" id="LC17" lang="plaintext" xml:lang="plaintext"> * )</span> <span class="line" id="LC18" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC19" lang="plaintext" xml:lang="plaintext"> * To skip if creator use the following:</span> <span class="line" id="LC20" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC21" lang="plaintext" xml:lang="plaintext"> * @code</span> <span class="line" id="LC22" lang="plaintext" xml:lang="plaintext"> * field_creator:</span> <span class="line" id="LC23" lang="plaintext" xml:lang="plaintext"> * plugin: skip_creator</span> <span class="line" id="LC24" lang="plaintext" xml:lang="plaintext"> * user_key: uid</span> <span class="line" id="LC25" lang="plaintext" xml:lang="plaintext"> * gid_key: gid</span> <span class="line" id="LC26" lang="plaintext" xml:lang="plaintext"> * method: row</span> <span class="line" id="LC27" lang="plaintext" xml:lang="plaintext"> * @endcode</span> <span class="line" id="LC28" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC29" lang="plaintext" xml:lang="plaintext"> */</span> <span class="line" id="LC30" lang="plaintext" xml:lang="plaintext">class SkipCreator extends ProcessPluginBase {</span> <span class="line" id="LC32" lang="plaintext" xml:lang="plaintext"> /**</span> <span class="line" id="LC33" lang="plaintext" xml:lang="plaintext"> * Stops processing the current property when user_key as uid is the creator of group with gid as in gid_key.</span> <span class="line" id="LC34" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC35" lang="plaintext" xml:lang="plaintext"> * @param mixed $value</span> <span class="line" id="LC36" lang="plaintext" xml:lang="plaintext"> * The input value.</span> <span class="line" id="LC37" lang="plaintext" xml:lang="plaintext"> * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable</span> <span class="line" id="LC38" lang="plaintext" xml:lang="plaintext"> * The migration in which this process is being executed.</span> <span class="line" id="LC39" lang="plaintext" xml:lang="plaintext"> * @param \Drupal\migrate\Row $row</span> <span class="line" id="LC40" lang="plaintext" xml:lang="plaintext"> * The row from the source to process.</span> <span class="line" id="LC41" lang="plaintext" xml:lang="plaintext"> * @param string $destination_property</span> <span class="line" id="LC42" lang="plaintext" xml:lang="plaintext"> * The destination property currently worked on. This is only used together</span> <span class="line" id="LC43" lang="plaintext" xml:lang="plaintext"> * with the $row above.</span> <span class="line" id="LC44" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC45" lang="plaintext" xml:lang="plaintext"> * @return mixed</span> <span class="line" id="LC46" lang="plaintext" xml:lang="plaintext"> * The input value, $value, if it is not empty.</span> <span class="line" id="LC47" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC48" lang="plaintext" xml:lang="plaintext"> * @throws \Drupal\migrate\MigrateSkipProcessException</span> <span class="line" id="LC49" lang="plaintext" xml:lang="plaintext"> * Thrown if the source property is not set and rest of the process should</span> <span class="line" id="LC50" lang="plaintext" xml:lang="plaintext"> * be skipped.</span> <span class="line" id="LC51" lang="plaintext" xml:lang="plaintext"> */</span> <span class="line" id="LC52" lang="plaintext" xml:lang="plaintext"> public function process($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {</span> <span class="line" id="LC53" lang="plaintext" xml:lang="plaintext"> $group = \Drupal::entityTypeManager()</span> <span class="line" id="LC54" lang="plaintext" xml:lang="plaintext"> -&gt;getStorage('group')</span> <span class="line" id="LC55" lang="plaintext" xml:lang="plaintext"> -&gt;load($row-&gt;getSource()[$this-&gt;configuration["gid_key"]]);</span> <span class="line" id="LC56" lang="plaintext" xml:lang="plaintext"> if (!$group) {</span> <span class="line" id="LC57" lang="plaintext" xml:lang="plaintext"> throw new MigrateException('gid not found.');</span> <span class="line" id="LC58" lang="plaintext" xml:lang="plaintext"> }</span> <span class="line" id="LC59" lang="plaintext" xml:lang="plaintext"> if ($group-&gt;getOwner()-&gt;id() == $row-&gt;getSource()[$this-&gt;configuration["user_key"]]) {</span> <span class="line" id="LC60" lang="plaintext" xml:lang="plaintext"> throw new MigrateSkipRowException("Creator is the same uid, so it exists");</span> <span class="line" id="LC61" lang="plaintext" xml:lang="plaintext"> }</span> <span class="line" id="LC62" lang="plaintext" xml:lang="plaintext"> return $value;</span> <span class="line" id="LC63" lang="plaintext" xml:lang="plaintext"> }</span> <span class="line" id="LC65" lang="plaintext" xml:lang="plaintext"> /**</span> <span class="line" id="LC66" lang="plaintext" xml:lang="plaintext"> * Skips the current row when user_key as uid is the creator of group with gid as in gid_key.</span> <span class="line" id="LC67" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC68" lang="plaintext" xml:lang="plaintext"> * @param mixed $value</span> <span class="line" id="LC69" lang="plaintext" xml:lang="plaintext"> * The input value.</span> <span class="line" id="LC70" lang="plaintext" xml:lang="plaintext"> * @param \Drupal\migrate\MigrateExecutableInterface $migrate_executable</span> <span class="line" id="LC71" lang="plaintext" xml:lang="plaintext"> * The migration in which this process is being executed.</span> <span class="line" id="LC72" lang="plaintext" xml:lang="plaintext"> * @param \Drupal\migrate\Row $row</span> <span class="line" id="LC73" lang="plaintext" xml:lang="plaintext"> * The row from the source to process.</span> <span class="line" id="LC74" lang="plaintext" xml:lang="plaintext"> * @param string $destination_property</span> <span class="line" id="LC75" lang="plaintext" xml:lang="plaintext"> * The destination property currently worked on. This is only used together</span> <span class="line" id="LC76" lang="plaintext" xml:lang="plaintext"> * with the $row above.</span> <span class="line" id="LC77" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC78" lang="plaintext" xml:lang="plaintext"> * @return mixed</span> <span class="line" id="LC79" lang="plaintext" xml:lang="plaintext"> * The input value, $value, if it is not empty.</span> <span class="line" id="LC80" lang="plaintext" xml:lang="plaintext"> *</span> <span class="line" id="LC81" lang="plaintext" xml:lang="plaintext"> * @throws \Drupal\migrate\MigrateSkipRowException</span> <span class="line" id="LC82" lang="plaintext" xml:lang="plaintext"> * Thrown if the source property is not set and the row should be skipped,</span> <span class="line" id="LC83" lang="plaintext" xml:lang="plaintext"> * records with STATUS_IGNORED status in the map.</span> <span class="line" id="LC84" lang="plaintext" xml:lang="plaintext"> */</span> <span class="line" id="LC85" lang="plaintext" xml:lang="plaintext"> public function row($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {</span> <span class="line" id="LC86" lang="plaintext" xml:lang="plaintext"> $group = \Drupal::entityTypeManager()</span> <span class="line" id="LC87" lang="plaintext" xml:lang="plaintext"> -&gt;getStorage('group')</span> <span class="line" id="LC88" lang="plaintext" xml:lang="plaintext"> -&gt;load($row-&gt;getSource()[$this-&gt;configuration["gid_key"]]);</span> <span class="line" id="LC89" lang="plaintext" xml:lang="plaintext"> if (!$group) {</span> <span class="line" id="LC90" lang="plaintext" xml:lang="plaintext"> throw new MigrateException('gid not found.');</span> <span class="line" id="LC91" lang="plaintext" xml:lang="plaintext"> }</span> <span class="line" id="LC92" lang="plaintext" xml:lang="plaintext"> if ($group-&gt;getOwner()-&gt;id() == $row-&gt;getSource()[$this-&gt;configuration["user_key"]]) {</span> <span class="line" id="LC93" lang="plaintext" xml:lang="plaintext"> throw new MigrateSkipRowException("Creator is the same uid, so it exists");</span> <span class="line" id="LC94" lang="plaintext" xml:lang="plaintext"> }</span> <span class="line" id="LC95" lang="plaintext" xml:lang="plaintext"> return $value;</span> <span class="line" id="LC96" lang="plaintext" xml:lang="plaintext"> }</span> <span class="line" id="LC98" lang="plaintext" xml:lang="plaintext">}</span></code></pre><p data-sourcepos="420:1-420:85" dir="auto">So now we have groups and their members. Now we can start thinking about the content.</p> <h1 data-sourcepos="422:1-422:9" dir="auto">Content</h1> <p data-sourcepos="424:1-424:315" dir="auto">Here instead of doing everything at once (create nodes and add as content to groups) as in <a href="https://thinktandem.io/blog/2018/03/30/migrating-drupal-7-organic-groups-to-drupal-8-group/" rel="nofollow noreferrer noopener" target="_blank">https://thinktandem.io/blog/2018/03/30/migrating-drupal-7-organic-groups-to-drupal-8-group/</a> , it will be based in a previously migrated node set, as it was did in previous step where from users it created group memberships.</p> <p data-sourcepos="426:1-427:223" dir="auto">Let's create the group content first setting that content as available in <code>group type settings/content</code>, in this example <code>blog</code> group available content will be <code>proposta</code>, <code>blog_post</code>(as blog entry), <code>podcast_episode</code>(as audio entry).</p> <p data-sourcepos="429:1-429:211" dir="auto">The next step starting from commit <a class="gfm gfm-commit has-tooltip" data-commit="9b9c731e6192ef596b49228686b3114857cc4fb8" data-container="body" data-link="false" data-link-reference="true" data-original="https://gitlab.com/communia/og_migrate_group/-/commit/9b9c731e6192ef596b49228686b3114857cc4fb8" data-placement="top" data-project="30138286" data-reference-type="commit" href="https://gitlab.com/communia/og_migrate_group/-/commit/9b9c731e6192ef596b49228686b3114857cc4fb8" title="Add Plugins to process directly form sql instead of csv">9b9c731e</a> it's easier than csv import, so it can be used with the plugin <code>d7_og_content</code> .</p> <h2 data-sourcepos="431:1-431:23" dir="auto">Via direct sql query</h2> <p data-sourcepos="434:1-434:44" dir="auto">for group content imports (relation maker):</p> <p data-sourcepos="436:1-437:31" dir="auto"><code>drush mim rename_d7_node_complete_blog,rename_d7_node_complete_podcast</code> <code>drush mim d7_og_blog_content</code></p> <p data-sourcepos="439:1-439:94" dir="auto">It will do the same as it's done in next csv import but using sql to previous import as source</p> <h2 data-sourcepos="441:1-441:22" dir="auto">Via view csv import</h2> <p data-sourcepos="426:1-427:223" dir="auto">Despite we could create a new plugin which transforms from <code>nid</code> to <code>title</code> or <code>uid</code>, may be useful  to do it in source view group_content csv, so including these properties. Relevant view used to obtain source data will be:</p> <p data-sourcepos="429:1-429:10" dir="auto">Relations:</p> <ul data-sourcepos="431:1-433:0" dir="auto"><li data-sourcepos="431:1-431:83">OG membership: Content from OG membership: 'og_membership_related_node'; REQUIRED</li> <li data-sourcepos="432:1-433:0">Entity Reference : Referenced Entity: 'og_group_ref_target_id';</li> </ul><p data-sourcepos="434:1-434:7" dir="auto">Fields:</p> <ul data-sourcepos="436:1-443:0" dir="auto"><li data-sourcepos="436:1-436:31">id, label: 'og_membership_id'</li> <li data-sourcepos="437:1-437:71">(relationship: og_membership_related_node_1)-&gt;nid , label:content_nid</li> <li data-sourcepos="438:1-438:75">(relationship: og_membership_related_node_1)-&gt;type, label: content_bundle</li> <li data-sourcepos="439:1-439:71">(relationship: og_membership_related_node_1)-&gt;uid, label: content_uid</li> <li data-sourcepos="440:1-440:75">(relationship: og_membership_related_node_1)-&gt;title, label: content_title</li> <li data-sourcepos="441:1-441:19">gid, label: 'gid'</li> <li data-sourcepos="442:1-443:0">(relationship:og_group_ref_target_id)-&gt;type, label: group_type</li> </ul><p data-sourcepos="444:1-444:92" dir="auto">(With the filters and sorts adapted to your case, to prevent listing non-migratable content)</p> <p data-sourcepos="446:1-446:16" dir="auto">This will output</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="448:1-454:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">"og_membership_id","content_nid","content_bundle","content_uid","content_title","gid","group_type"</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">"13397","59546","blog","438","Good news","22477","bloc"</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">"13426","77","podcast","6","El sistema universitari","22447","bloc"</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">"13427","86","proposta","16","Estrobaca","22455","bloc"</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">"13428","87","blog","8","ssl","22449","bloc"</span></code></pre><p data-sourcepos="457:1-457:40" dir="auto">Here the yml that will process this csv:</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="459:1-535:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">langcode: en</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">status: true</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">dependencies: { }</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">id: upgrade_d7_node_og_blog_content</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">class: null</span> <span class="line" id="LC6" lang="plaintext" xml:lang="plaintext">field_plugin_method: null</span> <span class="line" id="LC7" lang="plaintext" xml:lang="plaintext">cck_plugin_method: null</span> <span class="line" id="LC8" lang="plaintext" xml:lang="plaintext">migration_tags:</span> <span class="line" id="LC9" lang="plaintext" xml:lang="plaintext"> - CSV</span> <span class="line" id="LC10" lang="plaintext" xml:lang="plaintext">migration_group: insert_group</span> <span class="line" id="LC11" lang="plaintext" xml:lang="plaintext">label: 'blog Group Content Migration from CSV'</span> <span class="line" id="LC12" lang="plaintext" xml:lang="plaintext">source:</span> <span class="line" id="LC13" lang="plaintext" xml:lang="plaintext"> plugin: csv</span> <span class="line" id="LC14" lang="plaintext" xml:lang="plaintext"> # Must be obtained from source with some exporter (e.g. views data export) and placed in this path</span> <span class="line" id="LC15" lang="plaintext" xml:lang="plaintext"> path: 'public://imports/group-content-export.csv'</span> <span class="line" id="LC16" lang="plaintext" xml:lang="plaintext"> header_row_count: 1</span> <span class="line" id="LC17" lang="plaintext" xml:lang="plaintext"> ids:</span> <span class="line" id="LC18" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC19" lang="plaintext" xml:lang="plaintext"> og_membership_id</span> <span class="line" id="LC20" lang="plaintext" xml:lang="plaintext"> column_names:</span> <span class="line" id="LC21" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC22" lang="plaintext" xml:lang="plaintext"> og_membership_id: Identifier</span> <span class="line" id="LC23" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC24" lang="plaintext" xml:lang="plaintext"> content_nid: NodeID</span> <span class="line" id="LC25" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC26" lang="plaintext" xml:lang="plaintext"> content_bundle: bundle</span> <span class="line" id="LC27" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC28" lang="plaintext" xml:lang="plaintext"> content_uid: uid</span> <span class="line" id="LC29" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC30" lang="plaintext" xml:lang="plaintext"> content_title: title</span> <span class="line" id="LC31" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC32" lang="plaintext" xml:lang="plaintext"> gid: group</span> <span class="line" id="LC33" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC34" lang="plaintext" xml:lang="plaintext"> group_type: GroupType</span> <span class="line" id="LC35" lang="plaintext" xml:lang="plaintext"> delimiter: ','</span> <span class="line" id="LC36" lang="plaintext" xml:lang="plaintext"> enclosure: '"'</span> <span class="line" id="LC37" lang="plaintext" xml:lang="plaintext">process:</span> <span class="line" id="LC38" lang="plaintext" xml:lang="plaintext"> label:</span> <span class="line" id="LC39" lang="plaintext" xml:lang="plaintext"> # TO show the current item to debug</span> <span class="line" id="LC40" lang="plaintext" xml:lang="plaintext"> #-</span> <span class="line" id="LC41" lang="plaintext" xml:lang="plaintext"> # plugin: callback</span> <span class="line" id="LC42" lang="plaintext" xml:lang="plaintext"> # callable: var_dump</span> <span class="line" id="LC43" lang="plaintext" xml:lang="plaintext"> # source: content_title</span> <span class="line" id="LC44" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC45" lang="plaintext" xml:lang="plaintext"> plugin: get</span> <span class="line" id="LC46" lang="plaintext" xml:lang="plaintext"> source: content_title</span> <span class="line" id="LC47" lang="plaintext" xml:lang="plaintext"> type:</span> <span class="line" id="LC48" lang="plaintext" xml:lang="plaintext"> plugin: static_map</span> <span class="line" id="LC49" lang="plaintext" xml:lang="plaintext"> source: content_bundle</span> <span class="line" id="LC50" lang="plaintext" xml:lang="plaintext"> bypass: false</span> <span class="line" id="LC51" lang="plaintext" xml:lang="plaintext"> # Customize this to match your values and group content plugins</span> <span class="line" id="LC52" lang="plaintext" xml:lang="plaintext"> map:</span> <span class="line" id="LC53" lang="plaintext" xml:lang="plaintext"> proposta: blog-group_node-proposta</span> <span class="line" id="LC54" lang="plaintext" xml:lang="plaintext"> blog: blog-group_node-blog_post</span> <span class="line" id="LC55" lang="plaintext" xml:lang="plaintext"> podcast: blog-group_node-podcast_episode</span> <span class="line" id="LC56" lang="plaintext" xml:lang="plaintext"> default_value: blog-group_node-blog_post</span> <span class="line" id="LC57" lang="plaintext" xml:lang="plaintext"> gid: gid</span> <span class="line" id="LC58" lang="plaintext" xml:lang="plaintext"> entity_id:</span> <span class="line" id="LC59" lang="plaintext" xml:lang="plaintext"> # To skip if element is not found (may be merged during translation</span> <span class="line" id="LC60" lang="plaintext" xml:lang="plaintext"> # nodes migration fixes)</span> <span class="line" id="LC61" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC62" lang="plaintext" xml:lang="plaintext"> plugin: get</span> <span class="line" id="LC63" lang="plaintext" xml:lang="plaintext"> source: content_nid</span> <span class="line" id="LC64" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC65" lang="plaintext" xml:lang="plaintext"> plugin: entity_lookup</span> <span class="line" id="LC66" lang="plaintext" xml:lang="plaintext"> entity_type: node</span> <span class="line" id="LC67" lang="plaintext" xml:lang="plaintext"> value_key: nid</span> <span class="line" id="LC68" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC69" lang="plaintext" xml:lang="plaintext"> plugin: skip_on_empty</span> <span class="line" id="LC70" lang="plaintext" xml:lang="plaintext"> method: row</span> <span class="line" id="LC71" lang="plaintext" xml:lang="plaintext"> uid: content_uid</span> <span class="line" id="LC72" lang="plaintext" xml:lang="plaintext">destination:</span> <span class="line" id="LC73" lang="plaintext" xml:lang="plaintext"> plugin: 'entity:group_content'</span> <span class="line" id="LC74" lang="plaintext" xml:lang="plaintext">migration_dependencies: null</span> </code></pre><p data-sourcepos="537:1-537:76" dir="auto">And that's all, after that Groups, Memberships and Content will be migrated.</p> <h1 data-sourcepos="541:1-541:89" dir="auto">Bonus track - rename machine name of a bundle when migration has been already executed.</h1> <p data-sourcepos="543:1-545:249" dir="auto">First of all we create the bundle giving the desired name, and with the module field_tools we can make the clone of view_modes first and after that the fields clones. Once it is identical, we must rollback the migration of the content a given bundle: <code>drush migrate:rollback d7_node_complete:podcast</code> and then copy from <code>web/sites/default/files/config__secret_directory_that _must_be_uniquely_and_obscured_from_public_found_at_settings/sync/migrate_plus.migration.upgrade_d7_node_complete_podcast.yml</code> to a dedicated custom module in its <code>migrations</code> directory, then modify file setting the destination to desired bundle machine_name, also must be changed the id and filename according to what you are doing(in this case we set to <code>rename_d7_node_complete_podcast</code>), then run <code>drush migrate:rollback d7_node_complete:podcast --verbose &amp;&amp; drush mim rename_d7_node_complete_podcast --verbose</code> to import again the content that we want. Any configuration over it must be executed once again, for example url_redirects migrations.</p> <p data-sourcepos="543:1-545:249" dir="auto"> </p> <p data-sourcepos="543:1-545:249" dir="auto"> </p> <h1 data-sourcepos="548:1-548:61" dir="auto">Bonus track 2 - node feeds in D7 to feeds_feed entity in D8</h1> <p data-sourcepos="550:1-550:195" dir="auto">First create the feed types and add the fields as it was defined in source nodes that were acting as importers, then edit add the migration configuration, two working samples are in <code>migrations</code>:</p> <ul data-sourcepos="552:1-554:0" dir="auto"><li data-sourcepos="552:1-552:46">d7_node_complete_og_to_canal_blog_extern.yml</li> <li data-sourcepos="553:1-554:0">d7_node_complete_og_to_canal_proposta_externa.yml</li> </ul><p data-sourcepos="555:1-557:164" dir="auto">Both are based on the stock migration configurations that migrateplus has created and exported in config sync directory: <code>upgrade_d7_node_complete_[bundle_of_source]</code> . You can edit to create the feed entity instead of a node. Be careful to rollback previous imported bundle nodes migrations that match (in example it was <code>feed</code> and <code>proposta_feed</code> bundles). Flush plugins cache, and after that <code>drush mim d7_node_complete_node_to_[bundle_of_source]</code> will do the magic. This is the first step, Now you have two options because  feed source url is not easily picked.</p> <p data-sourcepos="555:1-557:164" dir="auto">One way and recommended as it can be automatizated, is using a new source plugin to fix the feed urls, look at <a href="https://gitlab.com/communia/og_migrate_group/-/commit/d50f73a86a8418d5702f89eeb812263f6b8fb165">commit  </a>this is a new plugin that will lookup the feed in source d7 feed table and "magically" will provide the url using some config as this:</p> <p data-sourcepos="555:1-557:164" dir="auto"> </p> <pre> <code class="language-yaml">langcode: en status: true dependencies: { } id: d7_feed_sources class: Drupal\migrate\Plugin\Migration field_plugin_method: null cck_plugin_method: null migration_tags: - 'Drupal 7 feeds' - 'resync' migration_group: resync label: 'Drupal 7 Feeds sources' source: plugin: d7_feed process: fid: - plugin: entity_lookup source: title value_key: title entity_type: feeds_feed # - # plugin: callback # callable: var_dump source: source destination: plugin: 'entity:feeds_feed' migration_dependencies: optional: - d7_node_complete_og_to_canal_blog_extern - d7_node_complete_og_to_canal_proposta_externa </code></pre><p data-sourcepos="555:1-557:164" dir="auto"> </p> <p data-sourcepos="555:1-557:164" dir="auto">The other way is using csv in a manual way,  first instead of struggling too much I end up creating a view in source that outputs to csv these fields:</p> <ul data-sourcepos="559:1-563:0" dir="auto"><li data-sourcepos="559:1-559:24">Content: title (title)</li> <li data-sourcepos="560:1-560:31">Feeds source: Source (source)</li> <li data-sourcepos="561:1-561:24">Content: type (bundle)</li> <li data-sourcepos="562:1-563:0">Content: Nid (nid)</li> </ul><p data-sourcepos="564:1-565:69" dir="auto">Which csv I copied to <code>public://imports/export-feeds.csv</code> And created the auxiliary migration configuration to import from csv:</p> <pre class="code highlight js-syntax-highlight language-plaintext white" data-sourcepos="567:1-614:3" lang="plaintext" v-pre="true" xml:lang="plaintext"> <code><span class="line" id="LC1" lang="plaintext" xml:lang="plaintext">langcode: en</span> <span class="line" id="LC2" lang="plaintext" xml:lang="plaintext">status: true</span> <span class="line" id="LC3" lang="plaintext" xml:lang="plaintext">dependencies: { }</span> <span class="line" id="LC4" lang="plaintext" xml:lang="plaintext">id: fix_feeds_sources</span> <span class="line" id="LC5" lang="plaintext" xml:lang="plaintext">class: Drupal\migrate\Plugin\Migration</span> <span class="line" id="LC6" lang="plaintext" xml:lang="plaintext">field_plugin_method: null</span> <span class="line" id="LC7" lang="plaintext" xml:lang="plaintext">cck_plugin_method: null</span> <span class="line" id="LC8" lang="plaintext" xml:lang="plaintext">migration_tags:</span> <span class="line" id="LC9" lang="plaintext" xml:lang="plaintext"> - 'Drupal 7 feeds'</span> <span class="line" id="LC10" lang="plaintext" xml:lang="plaintext">migration_group: fix_feeds</span> <span class="line" id="LC11" lang="plaintext" xml:lang="plaintext">label: 'Fix Feeds sources'</span> <span class="line" id="LC12" lang="plaintext" xml:lang="plaintext">source:</span> <span class="line" id="LC13" lang="plaintext" xml:lang="plaintext"> plugin: csv</span> <span class="line" id="LC14" lang="plaintext" xml:lang="plaintext"> path: 'public://imports/export-feeds.csv'</span> <span class="line" id="LC15" lang="plaintext" xml:lang="plaintext"> header_row_count: 1</span> <span class="line" id="LC16" lang="plaintext" xml:lang="plaintext"> ids:</span> <span class="line" id="LC17" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC18" lang="plaintext" xml:lang="plaintext"> nid</span> <span class="line" id="LC19" lang="plaintext" xml:lang="plaintext"> column_names:</span> <span class="line" id="LC20" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC21" lang="plaintext" xml:lang="plaintext"> title: title</span> <span class="line" id="LC22" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC23" lang="plaintext" xml:lang="plaintext"> source: Source</span> <span class="line" id="LC24" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC25" lang="plaintext" xml:lang="plaintext"> bundle: bundle</span> <span class="line" id="LC26" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC27" lang="plaintext" xml:lang="plaintext"> nid: Identifier</span> <span class="line" id="LC28" lang="plaintext" xml:lang="plaintext"> delimiter: ','</span> <span class="line" id="LC29" lang="plaintext" xml:lang="plaintext"> enclosure: '"'</span> <span class="line" id="LC30" lang="plaintext" xml:lang="plaintext">process:</span> <span class="line" id="LC31" lang="plaintext" xml:lang="plaintext"> fid:</span> <span class="line" id="LC32" lang="plaintext" xml:lang="plaintext"> -</span> <span class="line" id="LC33" lang="plaintext" xml:lang="plaintext"> plugin: entity_lookup</span> <span class="line" id="LC34" lang="plaintext" xml:lang="plaintext"> source: title</span> <span class="line" id="LC35" lang="plaintext" xml:lang="plaintext"> value_key: title</span> <span class="line" id="LC36" lang="plaintext" xml:lang="plaintext"> entity_type: feeds_feed</span> <span class="line" id="LC37" lang="plaintext" xml:lang="plaintext"># -</span> <span class="line" id="LC38" lang="plaintext" xml:lang="plaintext"># plugin: callback</span> <span class="line" id="LC39" lang="plaintext" xml:lang="plaintext"># callable: var_dump</span> <span class="line" id="LC40" lang="plaintext" xml:lang="plaintext"> source: source</span> <span class="line" id="LC41" lang="plaintext" xml:lang="plaintext">destination:</span> <span class="line" id="LC42" lang="plaintext" xml:lang="plaintext"> plugin: 'entity:feeds_feed'</span> <span class="line" id="LC43" lang="plaintext" xml:lang="plaintext">migration_dependencies:</span> <span class="line" id="LC44" lang="plaintext" xml:lang="plaintext"> optional:</span> <span class="line" id="LC45" lang="plaintext" xml:lang="plaintext"> - d7_node_complete_og_to_canal_blog_extern</span> <span class="line" id="LC46" lang="plaintext" xml:lang="plaintext"> - d7_node_complete_og_to_canal_proposta_externa</span></code></pre><p data-sourcepos="616:1-617:98" dir="auto">then <code>drush mim fix_feeds_sources</code> again. Then create the feed mappings as it was done in source(or modify as you want). And start importing</p> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--blog--rss.html.twig * field--node--field-tags--blog.html.twig * field--node--field-tags.html.twig * field--node--blog.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-inline clearfix"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> <div class="field__item"><a href="/ca/etiquetes/migrations" hreflang="ca">migrations</a></div> <div class="field__item"><a href="/ca/etiquetes/develop" hreflang="ca">develop</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> Sun, 03 Oct 2021 20:43:19 +0000 kinta 6495 at https://planet.communia.org https://planet.communia.org/en/content/recipe-migrate-drupal-7-organic-groups-drupal-9-group#comments Caches de drupal https://planet.communia.org/ca/content/caches-de-drupal <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--link--rss.html.twig * field--node--title--link.html.twig x field--node--title.html.twig * field--node--link.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>Caches de drupal</span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--link--rss.html.twig * field--node--uid--link.html.twig x field--node--uid.html.twig * field--node--link.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/1" class="visually-hidden p-author h-card" rel="author" title="kinta">kinta <img src="" alt="kinta" /> </a> <a title="View user profile." href="/en/users/kinta">kinta</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--link--rss.html.twig * field--node--created--link.html.twig x field--node--created.html.twig * field--node--link.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2018-06-07T12:04:16+02:00" title="Thursday, June 7, 2018 - 12:04">Thu, 06/07/2018 - 12:04</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--link--rss.html.twig * field--node--body--link.html.twig * field--node--body.html.twig * field--node--link.html.twig * field--body.html.twig * field--text-with-summary.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="body field field--node-body field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Caches de drupal</p> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-link--link--rss.html.twig * field--node--field-link--link.html.twig * field--node--field-link.html.twig * field--node--link.html.twig * field--field-link.html.twig * field--link.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="text-content field field--node-field-link field--name-field-link field--type-link field--label-above"> <div class="field-label">Link</div> <div class="field__item"><a href="https://www.dx-experts.nl/blog/2017/drupal-8-development-caching">https://www.dx-experts.nl/blog/2017/drupal-8-development-caching</a></div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--link--rss.html.twig * field--node--field-tags--link.html.twig * field--node--field-tags.html.twig * field--node--link.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-above"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/ca/etiquetes/develop" hreflang="ca">develop</a></div> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> <div class="field__item"><a href="/ca/etiquetes/cache" hreflang="ca">cache</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--comment--link--rss.html.twig * field--node--comment--link.html.twig * field--node--comment.html.twig * field--node--link.html.twig x field--comment.html.twig x field--comment.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--comment.html.twig' --> <section> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=6407&amp;2=comment&amp;3=comment" token="7TWLPdUnE5WJ9cRsR9BXb54iS2-o49wgVFIn1_DDqeA"></drupal-render-placeholder> </section> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--comment.html.twig' --> Thu, 07 Jun 2018 10:04:16 +0000 kinta 6407 at https://planet.communia.org https://planet.communia.org/ca/content/caches-de-drupal#comments https://tecnonucleous.com/2018/06/05/mas-de-115000-sitios-drupal-aun-vulnerables-al-exploit-drupalgeddon2/ https://planet.communia.org/ca/content/httpstecnonucleouscom20180605mas-de-115000-sitios-drupal-aun-vulnerables-al-exploit <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--link--rss.html.twig * field--node--title--link.html.twig x field--node--title.html.twig * field--node--link.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>https://tecnonucleous.com/2018/06/05/mas-de-115000-sitios-drupal-aun-vulnerables-al-exploit-drupalgeddon2/</span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--link--rss.html.twig * field--node--uid--link.html.twig x field--node--uid.html.twig * field--node--link.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/5" class="visually-hidden p-author h-card" rel="author" title="mmxals">mmxals <img src="" alt="mmxals" /> </a> <a title="View user profile." href="/en/users/mmxals">mmxals</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--link--rss.html.twig * field--node--created--link.html.twig x field--node--created.html.twig * field--node--link.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2018-06-05T17:32:40+02:00" title="Tuesday, June 5, 2018 - 17:32">Tue, 06/05/2018 - 17:32</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-link--link--rss.html.twig * field--node--field-link--link.html.twig * field--node--field-link.html.twig * field--node--link.html.twig * field--field-link.html.twig * field--link.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="text-content field field--node-field-link field--name-field-link field--type-link field--label-above"> <div class="field-label">Link</div> <div class="field__item"><a href="https://tecnonucleous.com/2018/06/05/mas-de-115000-sitios-drupal-aun-vulnerables-al-exploit-drupalgeddon2/">https://tecnonucleous.com/2018/06/05/mas-de-115000-sitios-drupal-aun-vulnerable…</a></div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--link--rss.html.twig * field--node--field-tags--link.html.twig * field--node--field-tags.html.twig * field--node--link.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-above"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/ca/etiquetes/drupalgeddon2" hreflang="ca">Drupalgeddon2</a></div> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> <div class="field__item"><a href="/ca/etiquetes/seguretat" hreflang="ca">Seguretat</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--comment--link--rss.html.twig * field--node--comment--link.html.twig * field--node--comment.html.twig * field--node--link.html.twig x field--comment.html.twig x field--comment.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--comment.html.twig' --> <section> <h2>Add new comment</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=6406&amp;2=comment&amp;3=comment" token="qjR9aG1VDb68mtGq5ezh26wE_Zx3ccg2k10s7ku-zh4"></drupal-render-placeholder> </section> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--comment.html.twig' --> Tue, 05 Jun 2018 15:32:40 +0000 mmxals 6406 at https://planet.communia.org https://planet.communia.org/ca/content/httpstecnonucleouscom20180605mas-de-115000-sitios-drupal-aun-vulnerables-al-exploit#comments Managing multiple drupals (7 and 8, composer and drush) https://planet.communia.org/ca/content/managing-multiple-drupals-7-and-8-composer-and-drush <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--blog--rss.html.twig * field--node--title--blog.html.twig x field--node--title.html.twig * field--node--blog.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>Managing multiple drupals (7 and 8, composer and drush)</span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--blog--rss.html.twig * field--node--uid--blog.html.twig x field--node--uid.html.twig * field--node--blog.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/1" class="visually-hidden p-author h-card" rel="author" title="kinta">kinta <img src="" alt="kinta" /> </a> <a title="View user profile." href="/en/users/kinta">kinta</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--blog--rss.html.twig * field--node--created--blog.html.twig x field--node--created.html.twig * field--node--blog.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2018-04-03T18:38:23+02:00" title="Tuesday, April 3, 2018 - 18:38">Tue, 04/03/2018 - 18:38</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--blog--rss.html.twig * field--node--body--blog.html.twig * field--node--body.html.twig * field--node--blog.html.twig * field--body.html.twig * field--text-with-summary.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="body field field--node-body field--name-body field--type-text-with-summary field--label-hidden field__item"><p><span><span><span>Most drupal projects that we have created at communia require maintenance, and when the number of projects to mantain grow, a strategy is needed to carry out mass actions such as modules or libraries installation, upgrades, cleaning of caches or registries to monitor.</span></span></span></p> <p><span><span>Until version 8, drush allowed to create alias and group them together to perform operations by group. For example, an @autoup group could be created that allowed updating the drupals that were known to have had no reason at all to give bugs in the update.</span></span></p> <p><span><span>All this has come under review with Drupal 8, at the time that drupal goes on to follow the open innovation strategy that allows the inclusion of code not specifically designed for drupal, also known as innovation strategy <em><a href="https://www.drupal.org/8/standards">Proudly Found Elsewhere</a></em> (such as symfony, easyrdf, doctrine, twig ...).The orchestration of all the dependencies is done via <span><a href="https://getcomposer.org/doc/00-intro.md">composer</a></span> , and specifically from drupal 8 it is recommended to install a <span><a href="https://github.com/drupal-composer/drupal-project">structure (scaffolding)</a></span> .</span></span></p> <p><span><span>This gives us these changes in the structure of the project:</span></span></p> <p><img alt="Drupal7 structure vs Drupal 8 structure(drupal-composer scaffolding)" data-entity-type="file" data-entity-uuid="7b5d1084-238d-4ffb-ab1a-74644ef87b48" src="/sites/default/files/inline-images/drupal7-vs-drupalcomposer_1.png" /></p> <p><span><span>Where you really manage the dependencies is at web's parent directory, it is in the root folder of drupal-project where we will run composer to install dependencies.</span></span></p> <p><span><span>All these changes imply a new perspective to manage the project, we can no longer rely on drush, and in fact the version of drush 9.x <span><a href="https://drushcommands.com/drush-9x/pm/pm:download/">already warns us</a></span> that installing modules for drush is abandoned.</span></span></p> <p><span><span>Since I have not found a tool to manage multiple composer projects, I have created the <span><a href="https://github.com/aleixq/druman">druman</a></span> console <span><a href="https://github.com/aleixq/druman">application</a></span> with the symfony <span><a href="https://symfony.com/doc/current/console.html">console command</a></span> component .So you can do a project management based on drush, or composer.</span></span></p> <p><span><span><span><strong>Druman project manager at drupal</strong></span></span></span></p> <p><span><span>This program is based on a list defined in yml that will be ~ / .druman-aliases.yml, where we define some properties for each project: alias, path, groups, manager.</span></span></p> <p><span><span>There is an example of a yml in the examples folder:</span></span></p> <ul><li> <p><span><span><strong>alias</strong>: it will be the name with which we will index and we will be able to access the project.</span></span></p> </li> <li> <p><span><span><strong>Path</strong>: this is the path of the project, if we use the structure drupal-composer we must give the root of the project (not that of the web). If we do not use the drupal-composer structure we have to put the web root. If we want a remote alias we have to write "" there.</span></span></p> </li> <li> <p><span><span><strong>Groups</strong>: list of groups to which the project belongs, for example autoup if we want to do a group of self-updating or hacked if we want to list projects in which we have to pay special attention when updating or installing modules. (you can put the names that you want, those that have been put in the example are examples).</span></span></p> </li> <li> <p><span><span><strong>Manager</strong>: Which manager we will use to control dependencies:</span></span></p> <ul><li> <p><span><span><strong>drush8</strong> It will be useful for the command projects:update (useless in command projects:run), it uses the drush (v8) manager to update it following the standard drupal 7 procedure (not recommended by drupal 8).</span></span></p> </li> <li> <p><span><span><strong>drupal-composer</strong> It will be useful for the command projects:update (useless in command projects:run), it uses the composer manager to proceed with the update in drupal-composer structures.</span></span></p> </li> <li> <p><span><span><strong>drush8-alias</strong> It will be useful when updating project process (with the projects:update command) and when drush commands are called (via command projects:run).Indicate the drush8-alias manager is the way to keep a remote (or local) site defined in the drush aliases, instead of reinventing the logic of remote drush alias, I have chosen to reuse it. Aliases will be treated without changing to the project directory (since the path is not defined) or by changing the user, it is done just like drush aliases (with possible subsequent permissions problems that may arise). When calling, drush @alias will always be added, so the drush and druman alias must match, and the drush command should only be said, for example:</span></span><br />  </p> <pre> <code class="language-bash">druman project: run -a project_x status</code></pre></li> </ul></li> </ul><p><span><span><span><strong>Remote project management (only drupal 7).</strong></span></span></span></p> <p><span><span>We have to pay special attention to the fact that if we use a drush8-alias manager in a project to manage remote projects, we must first define the remote alias as always with drush until version 8. This is so by not having to rewrite the logic that drush uses to connect to remote (To add an alias to drush there is information at: <span><a href="https://raw.githubusercontent.com/drush-ops/drush/8.x/examples/example.aliases.drushrc.php">https://raw.githubusercontent.com/drush-ops/drush/8. x / examples / example.aliases.drushrc.php</a></span> ).Thus, the alias must be defined in ~ / .drush / aliases.drushrc.php and ~ / .druman-aliases.yml, maybe in the future this changes to be able to launch remotely composers.</span></span></p> <p><span><span>If we define a project managed by <strong>drush8-alias</strong> the path must be blank</span></span></p> <pre> <code class="language-yaml">alias: someexternal_com path: "" groups: hostingatx manager: drush8-alias</code></pre><p><span><span><span><strong>List projects</strong></span></span></span></p> <p><span><span>To dump the <strong>list of projects</strong> we can use:</span></span></p> <pre> <code class="language-bash">druman projects:list</code></pre><p><span> </span></p> <p><span><span>In order to <strong>filter</strong> the list by group or by origin (local or remote), this command allows the following options:</span></span></p> <pre> <code class="language-bash">druman projects: list -h Usage: projects: list [options] Options: -g, --group [= GROUP] List only projects of specified group -l, --local List only local projects -r, --remote List only remote projects -f, --full Show all fields from list: alias, path, management type and group.</code></pre><p><span> </span></p> <p><span><span><span><strong>Running commands at the root of projects</strong></span></span></span></p> <p><span><span>From the list of projects defined in .druman-aliases.yml we can perform operations. We can throw an order at the root of the project with:</span></span></p> <pre> <code class="language-bash">projects:run</code></pre><p><span><span>We will have the same filtering options as when we list and additionally the option of selecting a single aliases directly. The options are:</span></span></p> <pre> <code class="language-bash">druman projects:run -h Usage: projects: run [options] [-] [&lt;order&gt;] Arguments: order Command to run. Options: -g, --group [= GROUP] Run only on these projects which are members of specified group -a, --alias [= ALIAS] Run only on this specific alias -l, --local List only local projects -r, --remote List only remote projects -all, --all Run in all alias, except those using drush8-alias manager, if specified no filters will be used </code></pre><p><span><span>Before executing the command it will <strong>change the user</strong> by who is the owner of the folder defined in the path of the alias.</span></span></p> <p><span><span><span><strong>Running project updates</strong></span></span></span></p> <p><span><span>To update, there is the command druman projects:update, which allows the same options as the projects:run command.</span></span></p> <pre> <code class="language-bash">projects:update -h -g, --group [= GROUP] Run only on these projects which are members of specified group -a, --alias [= ALIAS] Run only on this specific alias -l, --local List only local projects -r, --remote List only remote projects -all, --all Run in all alias, excluding those using drush8-alias manager</code></pre><p><span><span>The way you update the projects managed by <strong>drush8-alias</strong> or <strong>drush8</strong> follow the orders to update a <strong>drupal 7</strong> .The way you update the projects managed by <strong>drupal-composer</strong> follow the procedure to update a <strong>drupal 8</strong> .You can see the procedures at <span><a href="https://github.com/aleixq/druman/blob/master/src/Command/ManagerRunnerProjectsCommand.php">https://github.com/aleixq/druman/blob/master/src/Command/ManagerRunnerProjectsCommand.php</a></span> .</span></span></p> <p><span><span><span><strong>What's left:</strong></span></span></span></p> <ul><li> <p><span><span>Remote, be able to manage remote drupal with composer. Maybe the way would be to add ssh properties to .druman-aliases.yml. Or, as with those indicated by a drush8-alias manager, define a remote alias as explained in <span><a href="https://raw.githubusercontent.com/drush-ops/drush/master/examples/example.site.yml">https://raw.githubusercontent.com/drush-ops/drush/master/examples/example.site.yml</a></span> .</span></span></p> </li> <li> <p><span><span>also add, remove or update projects from .druman-aliases.yml interactively.</span></span></p> </li> </ul><p><span> </span></p> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--blog--rss.html.twig * field--node--field-tags--blog.html.twig * field--node--field-tags.html.twig * field--node--blog.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-inline clearfix"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> <div class="field__item"><a href="/ca/etiquetes/tutorials" hreflang="ca">tutorials</a></div> <div class="field__item"><a href="/ca/etiquetes/documentacio" hreflang="ca">documentació</a></div> <div class="field__item"><a href="/ca/etiquetes/composer" hreflang="ca">composer</a></div> <div class="field__item"><a href="/ca/etiquetes/php" hreflang="ca">php</a></div> <div class="field__item"><a href="/ca/etiquetes/drush" hreflang="ca">drush</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> Tue, 03 Apr 2018 16:38:23 +0000 kinta 6396 at https://planet.communia.org https://planet.communia.org/en/content/managing-multiple-drupals-7-and-8-composer-and-drush#comments https://planet.communia.org/en/content/managing-multiple-drupals-7-and-8-composer-and-drush#comments Linkback module tagged alpha https://planet.communia.org/en/content/linkback-module-tagged-alpha <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--blog--rss.html.twig * field--node--title--blog.html.twig x field--node--title.html.twig * field--node--blog.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>Linkback module tagged alpha</span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-image--blog--rss.html.twig * field--node--field-image--blog.html.twig * field--node--field-image.html.twig * field--node--blog.html.twig * field--field-image.html.twig * field--image.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="image field field--node-field-image field--name-field-image field--type-image field--label-hidden field__items"> <div class="field__item"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'responsive_image_formatter' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/responsive-image-formatter.html.twig' --> <a href="/sites/default/files/webmention-logo-380_0_0.png"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'responsive_image' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/responsive-image.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'image' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/image.html.twig' --> <img loading="eager" srcset="/sites/default/files/styles/max_325x325/public/webmention-logo-380_0_0.png?itok=WRUx7Pve 325w, /sites/default/files/styles/max_650x650/public/webmention-logo-380_0_0.png?itok=wJueH0N0 380w" sizes="(min-width: 1290px) 325px, (min-width: 851px) 25vw, (min-width: 560px) 50vw, 100vw" width="325" height="325" src="/sites/default/files/styles/max_325x325/public/webmention-logo-380_0_0.png?itok=WRUx7Pve" alt="" /> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/image.html.twig' --> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/responsive-image.html.twig' --> </a> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/responsive-image-formatter.html.twig' --> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--blog--rss.html.twig * field--node--uid--blog.html.twig x field--node--uid.html.twig * field--node--blog.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/1" class="visually-hidden p-author h-card" rel="author" title="kinta">kinta <img src="" alt="kinta" /> </a> <a title="View user profile." href="/en/users/kinta">kinta</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--blog--rss.html.twig * field--node--created--blog.html.twig x field--node--created.html.twig * field--node--blog.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2017-12-04T15:48:52+01:00" title="Monday, December 4, 2017 - 15:48">Mon, 12/04/2017 - 15:48</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--blog--rss.html.twig * field--node--body--blog.html.twig * field--node--body.html.twig * field--node--blog.html.twig * field--body.html.twig * field--text-with-summary.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="body field field--node-body field--name-body field--type-text-with-summary field--label-hidden field__item"><p>The <a href="https://www.drupal.org/project/linkback">Linkback module</a>(<a href="https://planet.communia.org/content/manual-de-linkback-drupal-8">background information</a>) for Drupal 8 has been tagged alpha today!  here a good intro about it written by <a href="http://hongpong.com/">HongPong</a>. We've done a lot of work to get there!</p> <blockquote> <p>Note for alpha1 release:</p> <p>We are proud to bring you the first alpha release of <strong>Linkback</strong>, an interesting suite of modules which can help integrate your website with the wider internet. Linkback provides the backend functionality to save both outgoing and incoming pings and webmentions involving remote sites.</p> <p>This first release focuses on a robust, spam resistant and fault tolerant approach to processing and storing Linkbacks as Drupal entities, which provides a standardized and efficient storage structure that can be easily queried and extended. (Anyone interested in improving the theming is invited to file an issue or share code with us :) More information about the functions in the Linkback suite is in Developer.md and the Readme.md files inside each child module.</p> <p>linkback_pingback creates the appropriate endpoints on your site to receive pingbacks from other sites (that is, someone on a WordPress site includes a link to your site and attempts to send a pingback; linkback_pingback receives the ping, scans the originating site URL to see if it a really existing anchor there, and if so, then it saves a new Linkback with the pingback handler attached to it.</p> <p>linkback_webmention provides much the same functionality for your site to send and receive Webmentions. (see other <a href="https://webmention.net/implementations/" rel="nofollow">Webmention implementations</a> - this module should interoperate with them). Services such as <a href="https://brid.gy/" rel="nofollow">brid.gy</a> can help connect proprietary content silos like Facebook and Twitter to your webmentions.</p> <p>Linkback has been cleverly structured to apply the best of Drupal 8 and Symfony architecture while reapplying many of the ideas from its predecessor <a href="https://drupal.org/project/vinculum" rel="nofollow">Vinculum</a> which provided similar services in Drupal 7. It should be feasible to extend Linkback to store other similar types of entities as records of intra-site communication.</p> <p>Thank you for trying Linkback - it is a product of several years of effort including bringing "<a href="https://indieweb.org/" rel="nofollow">indieweb</a>" principles and specifications into Drupal.</p> </blockquote></div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--blog--rss.html.twig * field--node--field-tags--blog.html.twig * field--node--field-tags.html.twig * field--node--blog.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-inline clearfix"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/en/etiquetes/sil-hostil" hreflang="en">sil-hostil</a></div> <div class="field__item"><a href="/ca/etiquetes/webmentions" hreflang="ca">webmentions</a></div> <div class="field__item"><a href="/ca/etiquetes/linkback" hreflang="ca">linkback</a></div> <div class="field__item"><a href="/ca/etiquetes/semantica" hreflang="ca">semantica</a></div> <div class="field__item"><a href="/ca/etiquetes/rdf" hreflang="ca">rdf</a></div> <div class="field__item"><a href="/ca/etiquetes/microformats2" hreflang="ca">microformats2</a></div> <div class="field__item"><a href="/en/etiquetes/pingbacks" hreflang="en">pingbacks</a></div> <div class="field__item"><a href="/ca/etiquetes/drupal-8" hreflang="ca">Drupal 8</a></div> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> Mon, 04 Dec 2017 14:48:52 +0000 kinta 6374 at https://planet.communia.org https://planet.communia.org/en/content/linkback-module-tagged-alpha#comments Manual de Linkback per drupal 8 https://planet.communia.org/en/content/manual-de-linkback-drupal-8 <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--blog--rss.html.twig * field--node--title--blog.html.twig x field--node--title.html.twig * field--node--blog.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>Manual de Linkback per drupal 8</span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-image--blog--rss.html.twig * field--node--field-image--blog.html.twig * field--node--field-image.html.twig * field--node--blog.html.twig * field--field-image.html.twig * field--image.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="image field field--node-field-image field--name-field-image field--type-image field--label-hidden field__items"> <div class="field__item"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'responsive_image_formatter' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/responsive-image-formatter.html.twig' --> <a href="/sites/default/files/webmention-logo-380_0.png"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'responsive_image' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/responsive-image.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'image' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/image.html.twig' --> <img loading="eager" srcset="/sites/default/files/styles/max_325x325/public/webmention-logo-380_0.png?itok=qBkStNvE 325w, /sites/default/files/styles/max_650x650/public/webmention-logo-380_0.png?itok=SU0ngvBJ 380w" sizes="(min-width: 1290px) 325px, (min-width: 851px) 25vw, (min-width: 560px) 50vw, 100vw" width="325" height="325" src="/sites/default/files/styles/max_325x325/public/webmention-logo-380_0.png?itok=qBkStNvE" alt="" title="webmentions" /> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/image.html.twig' --> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/responsive-image.html.twig' --> </a> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/responsive-image-formatter.html.twig' --> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--blog--rss.html.twig * field--node--uid--blog.html.twig x field--node--uid.html.twig * field--node--blog.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/1" class="visually-hidden p-author h-card" rel="author" title="kinta">kinta <img src="" alt="kinta" /> </a> <a title="View user profile." href="/en/users/kinta">kinta</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--blog--rss.html.twig * field--node--created--blog.html.twig x field--node--created.html.twig * field--node--blog.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2017-05-02T00:33:32+02:00" title="Tuesday, May 2, 2017 - 00:33">Tue, 05/02/2017 - 00:33</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--blog--rss.html.twig * field--node--body--blog.html.twig * field--node--body.html.twig * field--node--blog.html.twig * field--body.html.twig * field--text-with-summary.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="body field field--node-body field--name-body field--type-text-with-summary field--label-hidden field__item"><p><strong>¡¡Aquesta entrada té un contingut amb llenguatge tècnic, sobre com instal·lar i desenvolupar un blog federable-federat dins la blogosfera</strong>!!</p> <h2>Instal·lació i configuració</h2> <p>Avís: el mòdul <a href="https://www.drupal.org/project/linkback">linkback</a> està en desenvolupament, i tot i que hi ha una versió en dev, que sigui en dev significa que to el que explico a continuació és susceptible a canvis.</p> <p>Descarrega el módul de linkbacks i activa linkback_pingback i linkback webmention. El mòdul linkback s'activarà com a dependència. Com que té dependències d'algunes llibreries via composer, s'haurà de modificar el composer.json de l'arrel, això s'haurà de fer cada cop que s'actualitzi el core:</p> <ul><li> <p>Activar el repo de github per la lib de microformats/test , dependència de mf2:</p> <ul><li> <pre> composer config repositories.1 vcs https://github.com/microformats/tests</pre></li> </ul></li> <li> <p>Activar la llibreria de mf2:</p> <ul><li> <pre> composer require mf2/mf2:dev-master</pre></li> </ul></li> <li> <p>Activar el client de webmention :</p> <ul><li> <pre> composer require indieweb/mention-client:dev-master</pre></li> </ul></li> <li> <p>Afegim el camp linkbacks al tipus de contingut que vulguem (de moment només es pot associar a entitats de tipus node [contingut]). Amb això ja tindrem la base.</p> </li> <li> <p>Hi han poques coses a configurar: si vols processar els linkbacks rebuts o enviats via cron o manualment, per llocs en producció més val confiar en el cron. Arribats a aquest punt quan rebem pingbacks/webmentions la nostra web ho porcessarà.</p> </li> <li> <p>Tot i això podem treure més suc de les relacions de web a web i dotar d'una semàntica bàsica el nostre site, podem triar microformats2 o rdf. Tot i que amb RDF podrem construir descripcions més acurades, com a punt de partida i tenint en compte que volem tenir un blog pel segle XXI amb microformats ja en tindrem prou. En una propera entrada de blog ja especificaré com es podria fer per dotar de descriptors rdf el nostre site i adaptar el mòdul linkbacks per tal que processi rdf's més complexes.</p> </li> </ul><h2>Oferta microformats2</h2> <p>Pel que fa al processament de microformats2 el mòdul linkbacks ja té tot el que ha de tenir, fa servir la <a href="https://packagist.org/packages/mf2/mf2">llibreria mf2</a>. El que no tindrem preparat és l'oferta de microformats al nostre lloc web. Per fer-ho haurem de modificar una mica el tema que haguem escollit pel nostre drupal. En el nostre cas fem servir un subtema de <a href="http://foundation.zurb.com/">foundation 6</a>, però es pot aplicar al que vulguem. Hi han dos entitats que necessiten ser modificades:</p> <ul><li> <p>El tipus de contingut que fem servir per crear entrades de blog. Normalment article o blog_entry.</p> </li> <li> <p>L'usuari. Això es configura al directori themes/nomdeltema/nomdeltema.theme i s'afegeixen les plantilles pertinents al directori themes/nomdeltema/templates/.</p> </li> </ul><h3>Theming del tipus de contingut</h3> <p>Hi han algunes aplicacions globals: e-content pel que fa a body i p-name pel que fa a títols. Així doncs en tots els camps on s'utilitzi aquests camps afegirem la classe corresponent. Al fitxer nomdeltema.theme:</p> <pre> /** * Implements template_preprocess_field(). */ function planet_founding_preprocess_field(&amp;$variables) { $element = $variables['element']; switch($element['#field_name']){ case 'body': $apply_mf = "e-content"; break; case 'title': $apply_mf = "p-name"; break; } if (!empty($apply_mf)){ $variables['attributes']['class'][] = $apply_mf; $variables['items'][0]['content']['#options']['attributes']['class'][] = $apply_mf; } }</pre><p>Un cop fet això podem modificar les plantilles per tal que s'afegeixin algunes classes i per adaptar l'estructura del DOM. A node.html.twig:</p> <pre> /** * El tag de html 'article' es descriu com a: h-entry. * * @todo Remove the id attribute (or make it a class), because if that gets * rendered twice on a page this is invalid CSS for example: two lists * in different view modes. * * @ingroup themeable */ #} {# !MF2 Afegim la descripció de h-entry a l'etiquta article #} &lt;article id="node-{{ node.id }}" {{ attributes.addClass('h-entry') }} &gt; {# !MF2 Afegim el link a la url del node amb text buit i la propietat u-url #} &lt;a class="u-url" href="{{ url }}"&gt;&lt;/a&gt; {{ title_prefix }} {% if teaser %} {# !MF2 En cas de teaser afegir la propietat p-name al títol#} &lt;h1{{ title_attributes.addClass('teaser').addClass('p-name') }}&gt; &lt;a href="{{ url }}" rel="bookmark"&gt;{{ label }}&lt;/a&gt; &lt;/h1&gt; {% elseif not page %} &lt;h2{{ title_attributes }}&gt; {# !MF2 En cas que no sigui teaser i tampoc pàgina completa afegir la propietat p-name al títol #} &lt;a href="{{ url }}" rel="bookmark" class="p-name" &gt;{{ label }}&lt;/a&gt; &lt;/h2&gt; {% elseif page %} {# !MF2 En cas que sigui pàgina completa afegir la propietat p-name al títol #} &lt;span class="hidden p-name"&gt;{{ label }}&lt;/span&gt; {% endif %} {{ title_suffix }} {% if display_submitted %} &lt;small&gt; &lt;p&gt; &lt;div class="posted row"&gt; &lt;div class="columns shrink align-self-middle"&gt; &lt;div class="float-left"&gt; {{ author_picture }} &lt;/div&gt; &lt;div{{ author_attributes.addClass('float-left').addClass('submitted') }}&gt; {# !MF2 Afegim la propietat de data del post dt-published #} {% trans %}Submitted by {{ author_name }} on &lt;time class="dt-published"&gt;{{ date }}&lt;/time&gt;{% endtrans %} {{ metadata }} &lt;/div&gt; {% if content.field_tags|length &gt; 2 and not is_front %} &lt;div class="tags fi-pricetag-multiple"&gt; {{ content.field_tags }} &lt;/div&gt; {% endif %} &lt;/div&gt; &lt;/div&gt; &lt;/p&gt; &lt;/small&gt; {% endif %} {# We hide the comments and links now so that we can render them later. #} &lt;div{{ content_attributes }}&gt; {# En cas que fem servir un tipus de comentari diferent per cada tipus de contingut , Amaguem els comentaris associats al tipus de contingut per poder-lo mostrar després #} {{ content|without('comment','comment_node_blog', 'links', 'field_tags') }} &lt;/div&gt; {{ content.links }} {{ content.comment }} &lt;/article&gt; &lt;hr class="superspace"&gt; </pre><h3>Theming de l'usuari</h3> <p>Pel que fa a l'usuari s'ha d'afegir microformats a l'username insertat a dins el tipus de contingut(modificant la plantilla username), i també a la pròpia pàgina de l'usuari(full). A la pàgina pròpia de l'usuari també afegirem la variable view_mode per tal de poder treure etiquetes només en cas que es mostri l'usuari amb el display 'full'.</p> <p>Haurem d'afegir les propietats de l'usuari:</p> <p>- url</p> <p>- nom d'usuari</p> <p>- thumbnail</p> <p>Amb una estructura(especificada a <a href="http://microformats.org/wiki/microformats-2">http://microformats.org/wiki/microformats-2</a>) similar a: <a href="http://microformats.org/wiki/microformats-2">http://microformats.org/wiki/microformats-2</a> :</p> <pre> &lt;a class="h-card" href="http://url_de_l_usuari"&gt; &lt;img alt="nom de l'autor" src="urldelaimatge.jpg" /&gt; &lt;/a&gt;</pre><p>Pel que fa a <b>thumbnail</b> afegirem la variable userthumb als dos llocs per disposar de la url a la imatge de l'avatar sencera, tant des del node com des de l'usuari. A nomdeltema.theme:</p> <pre> /** * Implements template_preprocess_username(). */ function planet_founding_preprocess_username(&amp;$variables){ if (!$variables['account']-&gt;user_picture-&gt;isEmpty()) { $fid = $variables['account']-&gt;user_picture-&gt;first()-&gt;target_id; $file = \Drupal\file\Entity\File::load($fid); $variables['user_thumb'] = file_create_url($file-&gt;getFileUri()); } } /** * Implements template_preprocess_user * * Add template suggestions and classes */ function planet_founding_preprocess_user(&amp;$variables) { if (!$variables['user']-&gt;user_picture-&gt;isEmpty()) { $variables['user_thumb'] = file_create_url($variables['user']-&gt;user_picture-&gt;entity-&gt;getFileUri()); } $variables['view_mode'] = $variables['elements']['#view_mode']; }</pre><p>Pel que fa a l'estructura del <b>dom username</b> dins cada entrada de blog es mostrarà amb la plantilla username.html.twig:</p> <pre> {# /** * @file * Theme override for displaying a username. * * Available variables: * - account: The full account information for the user. * - name: The user's name, sanitized. * - extra: Additional text to append to the user's name, sanitized. * - link_path: The path or URL of the user's profile page, home page, * or other desired page to link to for more information about the user. * - link_options: Options to set on the \Drupal\Core\Url object if linking the * user's name to the user's page. * - attributes: HTML attributes for the containing element. * * @see template_preprocess_username() * - user_thumb: the thumbnail */ #} {% if link_path -%} &lt;a href="/{{ link_path }}" class="visually-hidden p-author h-card" rel="author" title="{{ name }}"&gt;{{ name }} &lt;img src="{{ user_thumb }}" alt="{{ name }}" /&gt; &lt;/a&gt; &lt;a{{ attributes }}&gt;{{ name }}{{ extra }}&lt;/a&gt; {%- else -%} &lt;span{{ attributes }}&gt;{{ name }}{{ extra }}&lt;/span&gt; {%- endif -%} </pre><p>Pel que fa al display de <b>l'usuari sencer</b> modificarem la plantilla user.html.twig afegirem una estructura similar a:</p> <pre> + * + * - view_mode: the rendered view mode string. */ #} -&lt;article{{ attributes }}&gt; +&lt;article{{ attributes.addClass('h-card') }}&gt; +{% if view_mode == "full" %} + &lt;a class="visually-hidden p-name u-url" href="user/{{ user.uid.value }}" rel="me" title=&gt;{{ user.name.value }}&lt;/a&gt; + &lt;img class="hidden u-photo" src="{{ user_thumb }}" /&gt; +{% endif %}</pre><p>  </p> <h3>Dotar de semàntica els links que afegim al cos de l'entrada de blog</h3> <p>Per tal de poder afegir semàntica als links que afegim via l'editor de text enriquit podem instal·lar el mòdul <a href="https://www.drupal.org/sandbox/kinta/2865999">editorsemanticlink</a> que ens permetrà dotar de semàntica a cada link a que afegim via l'editor ckeditor. (Configurar correctament a admin/config/content/formats/manage/basichtml o admin/config/content/formats/manage/fullhtml afegint atributs class i rel a l'etiqueta a) Amb això ja podrem afegir links semàntics al cos de text de les entrades de blog.</p> <h2>Consum de linkbacks</h2> <p>Cada cop que rebem un linkback s’anirà al lloc d’origen i s’intentarà fer un parsing de la metainformació del lloc que ens menciona, si té microformats2 o RDF crearà un array json que s’emmagatzemarà al camp metainfo del linkback. Si volem utilitzar aquesta metainformació (per exemple per fer llistats de linkbacks filtrables o agrupables), hauriem de mapejar camps del json a camps del linkback.</p> <p>Per fer-ho haurem d’anar a admin/structure/linkback/manage i afegir els camps que vulguem. El mapejarem anant a l’edició del field, i al camp de text afegirem la proietat de l’array json: per exemple si creem el camp autor, al mapeig hi posarem «author/name» per agafar la propietat:</p> <pre> { «autor» : {«name» : «alison»}, «url»: «http://myurl» }</pre><p>Si es vol agafar la propietat url, simplement es posa «url»</p> <p>Cada cop que es guardi processarà el mapeig i assignarà el valor.</p> <p>Pel mapeig hi ha més informació a: <a href="https://www.drupal.org/docs/8/modules/linkback/metainfo-mappinghttps://www.drupal.org/docs/8/modules/linkback/metainfo-mappinghttps://www.drupal.org/docs/8/modules/linkback/metainfo-mapping">https://www.drupal.org/docs/8/modules/linkback/metainfo-mapping</a></p> <h3>Mostrar linkbacks</h3> <p>Un cop fet això ja podrem rebre i enviar linkbacks semàntics i quedarà mostrar a cada entrada de blog un comptador i el llistat de comentaris.</p> <p>Per tenir-ho podem utilitzar <a href="https://www.drupal.org/sandbox/kinta/2873693">el módul Linkback semantic</a>. Que crea el camp semantic_type a l’entitat linkback i instal·la un bloc.</p> <p>Aquest es pot configurar perquè només es mostri als tipus de contingut que ens interessi i farà que quan rebem linkbacks i aquests siguin categoritzables semànticament, es pugui veure un comptador per tipus i un llistat de comentaris agrupats per tipus.</p> <p>També disposa d'una plantilla per tal de poder fer el theming corresponent. Si no convenç la llista de comentaris, es pot fer amb views.</p> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--blog--rss.html.twig * field--node--field-tags--blog.html.twig * field--node--field-tags.html.twig * field--node--blog.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-inline clearfix"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/en/etiquetes/sil-hostil" hreflang="en">sil-hostil</a></div> <div class="field__item"><a href="/ca/etiquetes/webmentions" hreflang="ca">webmentions</a></div> <div class="field__item"><a href="/ca/etiquetes/linkback" hreflang="ca">linkback</a></div> <div class="field__item"><a href="/ca/etiquetes/semantica" hreflang="ca">semantica</a></div> <div class="field__item"><a href="/ca/etiquetes/rdf" hreflang="ca">rdf</a></div> <div class="field__item"><a href="/ca/etiquetes/microformats2" hreflang="ca">microformats2</a></div> <div class="field__item"><a href="/en/etiquetes/pingbacks" hreflang="en">pingbacks</a></div> <div class="field__item"><a href="/ca/etiquetes/drupal-8" hreflang="ca">Drupal 8</a></div> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> Mon, 01 May 2017 22:33:32 +0000 kinta 126 at https://planet.communia.org https://planet.communia.org/en/content/manual-de-linkback-drupal-8#comments Módulo gnusocial para drupal8 https://planet.communia.org/en/content/modulo-gnusocial-para-drupal8 <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--title--blog--rss.html.twig * field--node--title--blog.html.twig x field--node--title.html.twig * field--node--blog.html.twig * field--title.html.twig * field--string.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <span>Módulo gnusocial para drupal8 </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--title.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-image--blog--rss.html.twig * field--node--field-image--blog.html.twig * field--node--field-image.html.twig * field--node--blog.html.twig * field--field-image.html.twig * field--image.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="image field field--node-field-image field--name-field-image field--type-image field--label-hidden field__items"> <div class="field__item"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'responsive_image_formatter' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/responsive-image-formatter.html.twig' --> <a href="/sites/default/files/gnusocial-drupal_0.png"> <!-- THEME DEBUG --> <!-- THEME HOOK: 'responsive_image' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/responsive-image.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'image' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/image.html.twig' --> <img loading="eager" srcset="/sites/default/files/styles/max_325x325/public/gnusocial-drupal_0.png?itok=XGc1VuAo 325w, /sites/default/files/styles/max_650x650/public/gnusocial-drupal_0.png?itok=rrdTtP9i 649w, /sites/default/files/styles/max_1300x1300/public/gnusocial-drupal_0.png?itok=cgIvH2fo 800w" sizes="(min-width: 1290px) 325px, (min-width: 851px) 25vw, (min-width: 560px) 50vw, 100vw" width="325" height="325" src="/sites/default/files/styles/max_325x325/public/gnusocial-drupal_0.png?itok=XGc1VuAo" alt="" /> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/image.html.twig' --> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/responsive-image.html.twig' --> </a> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/responsive-image-formatter.html.twig' --> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--uid--blog--rss.html.twig * field--node--uid--blog.html.twig x field--node--uid.html.twig * field--node--blog.html.twig * field--uid.html.twig * field--entity-reference.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'username' --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> <a href="/user/1" class="visually-hidden p-author h-card" rel="author" title="kinta">kinta <img src="" alt="kinta" /> </a> <a title="View user profile." href="/en/users/kinta">kinta</a> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/username.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--uid.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--created--blog--rss.html.twig * field--node--created--blog.html.twig x field--node--created.html.twig * field--node--blog.html.twig * field--created.html.twig * field--created.html.twig * field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <span> <!-- THEME DEBUG --> <!-- THEME HOOK: 'time' --> <!-- BEGIN OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> <time datetime="2016-06-03T10:05:33+02:00" title="Friday, June 3, 2016 - 10:05">Fri, 06/03/2016 - 10:05</time> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/time.html.twig' --> </span> <!-- END OUTPUT from 'themes/contrib/stable/templates/field/field--node--created.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--body--blog--rss.html.twig * field--node--body--blog.html.twig * field--node--body.html.twig * field--node--blog.html.twig * field--body.html.twig * field--text-with-summary.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="body field field--node-body field--name-body field--type-text-with-summary field--label-hidden field__item"><p>(English <a href="http://cgit.drupalcode.org/sandbox-kinta-2732077/tree/README.txt?h=8.x-1.x">README</a>).</p> <p>El módulo gnusocial  habilita los comentarios de gnusocial a cualquier tipo de contenido de Drupal 8. Depende únicamente del módulo <a href="https://bojanz.wordpress.com/2015/09/18/d8-composer-definitive-intro/">composer manager</a>  para solucionar las dependencias del plugin de guzzle <a href="https://github.com/guzzle/oauth-subscriber">oauth-subscriber</a>.</p> <p>Puedes usar este módulo para postear un status cuando nuevo contenido es publicado en drupal, o simplemente para añadir cualquier conversación  que viva en una instancia gnusocial que implementa la api de statusnet.</p> <p>Basándome en el plugin de <a href="https://wordpress.org/plugins/wp-gnusocial/">wpgnusocial</a> y su idea de fondo: permitir comentarios de una red federada de conversaciones. </p> <p>Esto se consigue teniendo una cuenta del site en gnusocial (léase communiabot por ejemplo), esta será la que publicará la "notice" en gnusocial cuando un blog post se publique.</p> <p>Hay algunos cambios respeto a wpgnusocial:</p> <ul><li>El<strong> método de autentificación </strong>entre gnusocial y drupal se hace via Oauth 3-legged. Eso requiere crear previamente una aplicación en tu nodo de gnusocial. Ganamos evitar ir pasando contraseñas de un sitio a otro, y permitimos revocación de la conexión por parte de gnusocial.</li> <li>Posibilidad de <strong>asociar manualmente cualquier conversación </strong>de cualquier instancia gnusocial (configurada en el drupal o no) a un blog post generado, o editarla posteriormente.</li> <li>Se <strong>asocia a</strong> un elemento de la api de statusnet <strong>conversation</strong> (as in <a href="https://git.gnu.io/gnu/gnu-social/blob/master/actions/apiconversation.php">https://git.gnu.io/gnu/gnu-social/blob/master/actions/apiconversation.p…</a> | <a href="https://github.com/andstatus/andstatus/issues/328">https://github.com/andstatus/andstatus/issues/328</a> ).</li> <li><em>Está previsto (no implementado aún) de que si la publicación de comentarios sea en dos sentidos, o sea permitir comentarios en el site y  que la cuenta de gnu social asociada al site publique respuestas-comentarios.</em></li> <li><em>En un futuro se podrá configurar la visualización de la conversación de dos formas, obteniendo el hilo en</em><em> el lado del servidor via php, (tal como está desarrollado actualmente), o e</em><em>n el lado cliente(pendiente), para evitar trabajos en el servidor.</em></li> <li>Theming de la lista de comentarios y de cada status vía plantillas <a href="http://twig.sensiolabs.org/">twig</a>.</li> </ul><p>Intenta seguir en todo lo que puede las <a href="https://www.drupal.org/coding-standards">recomendaciones de drupal</a>, usando las librerías que usa drupal (<a href="http://docs.guzzlephp.org/en/latest/psr7.html">Guzzle</a>, <a href="http://symfony.com/">symfony</a>...), y usa la <a href="https://api.drupal.org/api/drupal/core%21modules%21field%21field.module/group/field/8.2.x">field api</a> de drupal para insertar los comentarios en las <a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/group/entity_api/8.2.x">entidades</a>, con toda la flexibilidad que permite esto.</p> <h3>Pasos para configurarlo</h3> <p>(copiado del <a href="http://cgit.drupalcode.org/sandbox-kinta-2732077/tree/README.txt?h=8.x-1.x">README.txt</a> en inglés) :</p> <pre> If you want to simply attach the conversation --------------------------------------------- You'll have to add the field to the content you want in field configuration check "Gnusocial Comments" and uncheck "Post to GnuSocial". For every post you'll have to manually fill the field with the conversation json url. It's your job to get it. To get full functionality (attach comments and post to gnusocial): ------------------------------------------------------------------ You'll need to configure both in gnusocial and drupal. For Gnusocial part create the user that will act as bot. It will create the statuses anouncing your blog entries, allowing to create a conversation over. Go to: Settings &gt;connections; There click on register an Oauth client applic- ation in right sidebar (https://gnusocialurl/settings/oauthapps). You'll have to register a new application, so fill the fields: - Icon if you want it, - Name: a descriptive name of the app, for example drupal_gnusocial. - Description: Explain this application, for example: Communicates with a drupal site. - Source Url: The drupal url. - Organization: Optionally, the name of the organization that owns the drupal with gnusocial integration. - Homepage: The homepage of the organization . - Callback url: http://yourdrupal/admin/config/services/gnusocial. - Type of application: Browser. - Read-write After that a "Consumer key" and "Consumer secret" will be provided. Copy these in a text editor. Don't close the gnusocial tab (session) yet. We'll go to your drupal instance, there configure in: configuration &gt; services &gt; gnusocial. It will do a 3-legged authentication against the provided gnusocial url, so add the base url of gnusocial ( https://yourgnusocial.url.com ), OAuth consumer key, the "Consumer secret" and click save. After saving, click "update tokens", it will redirect to gnusocial url to complete the authentication, allowing the application to interact with gnusocial, after that it will redirect to drupal and the process will be completed. Developer info: --------------- You can use templates to theme the comments: - field: You can use the field template as gnusocial comments is a field. - gnusocial-conversation.html.twig will be the container of each conversation (between field wrapper and each status). It has the statuses list, the more link, and the conversation link. - gnusocial-status.html.twig will be the template used to render each status. </pre></div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'field' --> <!-- FILE NAME SUGGESTIONS: * field--node--field-tags--blog--rss.html.twig * field--node--field-tags--blog.html.twig * field--node--field-tags.html.twig * field--node--blog.html.twig * field--field-tags.html.twig * field--entity-reference.html.twig x field.html.twig --> <!-- BEGIN OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <div class="field field--node-field-tags field--name-field-tags field--type-entity-reference field--label-inline clearfix"> <div class="field-label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/ca/etiquetes/gnusocial" hreflang="ca">Gnusocial</a></div> <div class="field__item"><a href="/ca/etiquetes/drupal" hreflang="ca">Drupal</a></div> <div class="field__item"><a href="/ca/etiquetes/drupal-8" hreflang="ca">Drupal 8</a></div> </div> </div> <!-- END OUTPUT from 'themes/contrib/zurb_foundation/templates/field.html.twig' --> <!-- THEME DEBUG --> <!-- THEME HOOK: 'links__node' --> <!-- FILE NAME SUGGESTIONS: * links--node.html.twig * links--node.html.twig x links.html.twig --> <!-- BEGIN OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> <!-- END OUTPUT from 'themes/custom/planet_foundated/templates/links.html.twig' --> Fri, 03 Jun 2016 08:05:33 +0000 kinta 113 at https://planet.communia.org https://planet.communia.org/en/content/modulo-gnusocial-para-drupal8#comments