Browse Source

added pathauto, refactored article to load gql directly from path, the vuejs route and drupal route can finally match, HALLELUYA git status

Bachir Soussi Chiadmi 3 years ago
parent
commit
78155f83b8

+ 22 - 0
config/sync/pathauto.pattern.blabla_article_.yml

@@ -0,0 +1,22 @@
+uuid: 5fdb800c-8953-42ec-b3c3-a1bdd8ff2817
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
+id: blabla_article_
+label: 'blabla/article '
+type: 'canonical_entities:node'
+pattern: 'blabla/[node:title]'
+selection_criteria:
+  d0ad31d5-4ed3-40f7-84ed-297271c60fc7:
+    id: node_type
+    bundles:
+      article: article
+    negate: false
+    context_mapping:
+      node: node
+    uuid: d0ad31d5-4ed3-40f7-84ed-297271c60fc7
+selection_logic: and
+weight: -5
+relationships: {  }

+ 55 - 0
config/sync/pathauto.settings.yml

@@ -0,0 +1,55 @@
+enabled_entity_types:
+  - user
+punctuation:
+  double_quotes: 0
+  quotes: 0
+  backtick: 0
+  comma: 0
+  period: 0
+  hyphen: 1
+  underscore: 0
+  colon: 0
+  semicolon: 0
+  pipe: 0
+  left_curly: 0
+  left_square: 0
+  right_curly: 0
+  right_square: 0
+  plus: 0
+  equal: 0
+  asterisk: 0
+  ampersand: 0
+  percent: 0
+  caret: 0
+  dollar: 0
+  hash: 0
+  at: 0
+  exclamation: 0
+  tilde: 0
+  left_parenthesis: 0
+  right_parenthesis: 0
+  question_mark: 0
+  less_than: 0
+  greater_than: 0
+  slash: 0
+  back_slash: 0
+verbose: true
+separator: '-'
+max_length: 100
+max_component_length: 100
+transliterate: true
+reduce_ascii: false
+case: true
+ignore_words: 'a, an, as, at, before, but, by, for, from, is, in, into, like, of, off, on, onto, per, since, than, the, this, that, to, up, via, with'
+update_action: 2
+langcode: fr
+safe_tokens:
+  - alias
+  - alias
+  - path
+  - join-path
+  - login-url
+  - url
+  - url-brief
+_core:
+  default_config_hash: QDedIRjSYDH1ZiuQZ1LIkF9_wOwsokd_Cidr-mXA25E

+ 16 - 0
config/sync/system.action.pathauto_update_alias_node.yml

@@ -0,0 +1,16 @@
+uuid: 455dc6bb-c7a5-4e86-83e7-2bd8bc7619b4
+langcode: en
+status: true
+dependencies:
+  enforced:
+    module:
+      - node
+  module:
+    - pathauto
+_core:
+  default_config_hash: lno8QThS348UX-kaUsagJtCnuPHKLXYnTQiF_9HSDWA
+id: pathauto_update_alias_node
+label: 'Update URL alias'
+type: node
+plugin: pathauto_update_alias
+configuration: {  }

+ 16 - 0
config/sync/system.action.pathauto_update_alias_user.yml

@@ -0,0 +1,16 @@
+uuid: 8ead36aa-aaf2-4a9f-a87f-addc4992695d
+langcode: en
+status: true
+dependencies:
+  enforced:
+    module:
+      - user
+  module:
+    - pathauto
+_core:
+  default_config_hash: x_ok_ZsfA4Xk4B_hVW3O4-3PcNoK57nXLz_Dlletidg
+id: pathauto_update_alias_user
+label: 'Update URL alias'
+type: user
+plugin: pathauto_update_alias
+configuration: {  }

+ 6 - 2
web/modules/custom/materio_graphql/graphql/materio_extension.base.graphqls

@@ -1,6 +1,10 @@
 scalar Violation
 
-type Materiau {
+interface NodeInterface {
+  id: Int!
+}
+
+type Materiau implements NodeInterface {
   id: Int!
   uuid: String!
   title: String!
@@ -23,7 +27,7 @@ type Materiau {
   samples: [Sample]
 }
 
-type Article {
+type Article implements NodeInterface {
   id: Int!
   uuid: String!
   title: String!

+ 4 - 0
web/modules/custom/materio_graphql/graphql/materio_extension.extension.graphqls

@@ -1,3 +1,7 @@
+extend type Query {
+  route(path: String!): NodeInterface
+}
+
 extend type Query {
   materiau(id: Int!): Materiau
 }

+ 32 - 1
web/modules/custom/materio_graphql/src/Plugin/GraphQL/Schema/MaterioSchema.php

@@ -3,7 +3,10 @@
 namespace Drupal\materio_graphql\Plugin\GraphQL\Schema;
 
 use Drupal\graphql\Plugin\GraphQL\Schema\ComposableSchema;
-
+use Drupal\graphql\GraphQL\ResolverBuilder;
+use Drupal\graphql\GraphQL\ResolverRegistry;
+// use Drupal\graphql\Plugin\GraphQL\Schema\SdlSchemaPluginBase;
+use GraphQL\Error\Error;
 /**
  * @Schema(
  *   id = "materio",
@@ -13,4 +16,32 @@ use Drupal\graphql\Plugin\GraphQL\Schema\ComposableSchema;
  */
 class MaterioSchema extends ComposableSchema {
 
+  // /**
+  //  * {@inheritdoc}
+  //  */
+  // public function getResolverRegistry() {
+  //   $builder = new ResolverBuilder();
+  //   $registry = new ResolverRegistry();
+  //
+  //   // Tell GraphQL how to resolve types of a common interface.
+  //   $registry->addTypeResolver('NodeInterface', function ($value) {
+  //     if ($value instanceof NodeInterface) {
+  //       switch ($value->bundle()) {
+  //         case 'article': return 'Article';
+  //         case 'materiau': return 'Materiau';
+  //       }
+  //     }
+  //     throw new Error('Could not resolve content type.');
+  //   });
+  //
+  //   $registry->addFieldResolver('Query', 'route', $builder->compose(
+  //     $builder->produce('route_load')
+  //       ->map('path', $builder->fromArgument('path')),
+  //     $builder->produce('route_entity')
+  //       ->map('url', $builder->fromParent())
+  //   ));
+  //
+  //   return $registry;
+  // }
+
 }

+ 31 - 4
web/modules/custom/materio_graphql/src/Plugin/GraphQL/SchemaExtension/MaterioSchemaExtension.php

@@ -8,6 +8,9 @@ use Drupal\graphql\GraphQL\Response\ResponseInterface;
 use Drupal\graphql\Plugin\GraphQL\SchemaExtension\SdlSchemaExtensionPluginBase;
 use Drupal\materio_graphql\GraphQL\Response\MaterioResponse;
 use Drupal\Core\Url;
+
+use GraphQL\Error\Error;
+
 /**
  * @SchemaExtension(
  *   id = "materio_extension",
@@ -24,6 +27,30 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
   public function registerResolvers(ResolverRegistryInterface $registry) {
     $builder = new ResolverBuilder();
 
+    // Tell GraphQL how to resolve types of a common interface.
+    $registry->addTypeResolver('NodeInterface', function ($value) {
+
+      $path = explode('\\', get_class($value));
+      $class = array_pop($path);
+
+      if ($class === 'Node') {
+        switch ($value->bundle()) {
+          case 'article': return 'Article';
+          case 'materiau': return 'Materiau';
+        }
+      }
+      throw new Error('Could not resolve content type.');
+    });
+
+    $registry->addFieldResolver('Query', 'route',
+      $builder->compose(
+        $builder->produce('route_load')
+          ->map('path', $builder->fromArgument('path')),
+        $builder->produce('route_entity')
+          ->map('url', $builder->fromParent())
+    ));
+
+
     $this->addMateriau($registry, $builder);
 
     $this->addSearchResult($registry, $builder);
@@ -577,12 +604,12 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
   protected function addLink(ResolverRegistryInterface $registry, ResolverBuilder $builder) {
     $registry->addFieldResolver('Link', 'url',
       $builder->callback(function ($parent, $args) {
-        return $parent[0]['uri'];
+        return isset($parent[0]) ? $parent[0]['uri'] : null;
       })
     );
     $registry->addFieldResolver('Link', 'title',
       $builder->callback(function ($parent, $args) {
-        return $parent[0]['title'];
+        return isset($parent[0]) ? $parent[0]['title'] : null;
       })
     );
   }
@@ -594,12 +621,12 @@ class MaterioSchemaExtension extends SdlSchemaExtensionPluginBase {
   protected function addDate(ResolverRegistryInterface $registry, ResolverBuilder $builder) {
     $registry->addFieldResolver('Date', 'start',
       $builder->callback(function ($parent, $args) {
-        return $parent[0]['value'];
+        return isset($parent[0]) ? $parent[0]['value'] : null;
       })
     );
     $registry->addFieldResolver('Date', 'end',
       $builder->callback(function ($parent, $args) {
-        return $parent[0]['end_value'];
+        return isset($parent[0]) ? $parent[0]['end_value'] : null;
       })
     );
   }

File diff suppressed because it is too large
+ 0 - 0
web/themes/custom/materiotheme/assets/dist/main.js


+ 3 - 3
web/themes/custom/materiotheme/assets/styles/base/_colors.scss

@@ -1,10 +1,10 @@
 $transparent-bg: rgba(255,255,255, 0.95);
 $transparent-bg-blk: rgba(0,0,0, 0.75);
 
-$alpha: 0.90;
 $color-base:#69cdcf;
-$color-base-transparent: change-color($color-base, $alpha: $alpha);
 $color-showrooms:#50aa3c;
-$color-showrooms-transparent: change-color($color-showrooms, $alpha: $alpha);
 $color-blabla:#9458aa;
+$alpha: 0.90;
+$color-base-transparent: change-color($color-base, $alpha: $alpha);
+$color-showrooms-transparent: change-color($color-showrooms, $alpha: $alpha);
 $color-blabla-transparent: change-color($color-blabla, $alpha: $alpha);

+ 2 - 2
web/themes/custom/materiotheme/vuejs/components/Content/ArticleCard.vue

@@ -37,8 +37,8 @@ export default {
       console.log('clicked on article', this.alias);
       this.$router.push({
         name:`article`,
-        params: { alias:this.alias },
-        query: { nid: this.item.nid }
+        params: { alias:this.alias }
+        // query: { nid: this.item.nid }
         // meta: { uuid:this.item.uuid },
       })
     }

+ 31 - 167
web/themes/custom/materiotheme/vuejs/components/Pages/Article.vue

@@ -140,7 +140,8 @@ export default {
     return {
       index:-1,
       prevnext:{},
-      uuid:null,
+      nid:null,
+      path: null,
       article:null,
       image_accroche: null,
       lightbox_items: null,
@@ -165,17 +166,26 @@ export default {
     getArticle(){
       console.log(this.$route);
       // get the article uuid
-      if(this.$route.query.nid){
+      // if(this.$route.query.nid){
+      //   // we come from internal link with vuejs
+      //   // directly record uuid
+      //   this.nid = this.$route.query.nid
+      //
+      // }else if(drupalDecoupled.entity_type == 'node' && drupalDecoupled.entity_bundle == 'article'){
+      //   // we landed in an internal page
+      //   // get the uuid from drupalDeclouped, provided by materio_decoupled.module
+      //   this.nid = drupalDecoupled.entity_id
+      // }
+
+      if (this.$route.path) {
         // we come from internal link with vuejs
-        // directly record uuid
-        this.nid = this.$route.query.nid
-      }else if(drupalDecoupled.entity_type == 'node' && drupalDecoupled.entity_bundle == 'article'){
+        this.path = this.$route.path
+      } else {
         // we landed in an internal page
-        // get the uuid from drupalDeclouped, provided by materio_decoupled.module
-        this.nid = drupalDecoupled.entity_id
+        this.path = window.location.pathname
       }
 
-      if(this.nid){
+      if(this.path){
         this.loadArticle()
         // get the prev next items
         if(!this.items.length){
@@ -205,33 +215,29 @@ export default {
       })
     },
     loadArticle(){
-      console.log('loadArticle', this.nid)
+      console.log('loadArticle')
       this.loading = true
-      // let params = {
-      //   include:'field_linked_materials.images,field_showroom,field_tags,field_thesaurus,field_visuel,uid'
+
+      // let ast = gql`{
+      //   article(id: ${this.nid}) {
+      //     ...ArticleFields
+      //   }
       // }
-      // let q = qs.stringify(params)
-      // JSONAPI.get(`node/article/${this.uuid}?${q}`)
-      //   .then(({ data }) => {
-      //     console.log('loadArticle data', data)
-      //     this.parseDataJSONAPI(data)
-      //   })
-      //   .catch(( error ) => {
-      //       console.warn('Issue with loadArticle', error)
-      //       Promise.reject(error)
-      //   })
+      // ${ articleFields }
+      // `
       let ast = gql`{
-        article(id: ${this.nid}) {
+        route(path: "${this.path}") {
           ...ArticleFields
         }
       }
       ${ articleFields }
       `
+
       MGQ.post('', { query: print(ast)
       })
-        .then(({ data:{data:{article}}}) => {
-          console.log('loadArticle', article )
-          this.parseDataGQL(article)
+        .then(({ data:{data:{route}}}) => {
+          console.log('loadArticle', route )
+          this.parseDataGQL(route)
         })
         .catch(error => {
           console.warn('Issue with loadArticle', error)
@@ -290,148 +296,6 @@ export default {
 
       this.loading = false;
     },
-    parseDataJSONAPI(data){
-      let attrs = data.data.attributes
-      let relations = data.data.relationships
-      console.log('relations', relations);
-      let inc = data.included
-      console.log('included', inc);
-
-      this.content = {
-        title:attrs.title,
-        body: attrs.body.value
-      }
-
-      // build lightbox array
-      // will be filled by videos and field_visuel
-      this.content.lightbox_items = [];
-
-      // parse embeded videos pushing it in lightbox
-      for(let key in attrs.field_video){
-        let videolink = attrs.field_video[key]
-        // console.log('videolink', videolink);
-        let provider_regex = /https:\/\/(www\.)?(?<provider>youtube|vimeo)\.com\/.+/;
-        let match = provider_regex.exec(videolink)
-        // console.log('provider', match.groups.provider);
-        let video_id = null;
-        let video_thumb = null;
-        switch (match.groups.provider) {
-          case 'vimeo':
-            let vimeo_regex = /https:\/\/vimeo\.com\/(?<id>\d+)/;
-            video_id = vimeo_regex.exec(videolink).groups.id || null;
-            // TODO: get the vimeo thumb https://coderwall.com/p/fdrdmg/get-a-thumbnail-from-a-vimeo-video
-            video_thumb = "http://blogpeda.ac-poitiers.fr/ent-lyc/files/2015/06/Vimeo_icon_block.png"
-            break;
-          case 'youtube':
-            let youtube_regex = /https:\/\/(www\.)?youtube\.com\/watch\?v=(?<id>.+)/;
-            video_id = youtube_regex.exec(videolink).groups.id || null;
-            video_thumb = "http://img.youtube.com/vi/"+video_id+"/0.jpg"
-            break;
-        }
-        // console.log('video_id', video_id);
-
-        this.content.lightbox_items.push({
-          src: videolink,
-          title: "",
-          description: "",
-          thumb: video_thumb
-        });
-        // this.content.videos.push({
-        //   provider: match.groups.provider,
-        //   id: video_id,
-        //   href: videolink
-        // });
-      }
-
-      // parse all relationships
-      for (let key in relations) {
-        // skip loop if the property is from prototype
-        if (!relations.hasOwnProperty(key)) continue;
-
-        let relation_obj = relations[key]
-        console.log("relation", key, relation_obj);
-        // console.log('typeof relation_obj.data', typeof relation_obj.data);
-        if(!relation_obj.data) continue;
-
-        // showroom is unique field so no array in data
-        // we parse it here
-        switch (key) {
-          case 'field_showroom':
-            let included = inc.find((i) => { return i.id == relation_obj.data.id })
-            // console.log('included',included);
-            this.content[key] = included.attributes;
-            break
-        }
-
-        // skip relation_obj if data is not array
-        if(!Array.isArray(relation_obj.data)) continue
-        // create empty field array
-        this.content[key] = []
-        // parse relationship values using included
-        let field = {}
-        // loop through all relation items
-        relation_obj.data.forEach((e) => {
-          // get the included values for each item using id
-          let included = inc.find((i) => { return i.id == e.id })
-          // if we not found an included item skip the item
-          if(typeof included != 'undefined'){
-            // fill the item values
-            switch (key) {
-              case 'field_visuel':
-                // build the field object (not used for now)
-                field = e.meta
-                field.id = e.id
-                field.src = included.attributes.uri.url
-                field.thumb = included.links.article_card_medium.href
-                break;
-              case 'field_linked_materials':
-                field = included.attributes
-                field.id = field.uuid = included.id
-                // get the linked material included images
-                field.images = [];
-                included.relationships.images.data.forEach((img) => {
-                  // console.log('href', img.meta.imageDerivatives.links.card_medium.href);
-                  if(img.meta.imageDerivatives){
-                    field.images.push({
-                      title:img.meta.title,
-                      src: img.meta.imageDerivatives.links.hd.href,
-                      img_styles: {
-                        card_medium: img.meta.imageDerivatives.links.card_medium.href,
-                        card_full: img.meta.imageDerivatives.links.card_full.href
-                      }
-                    })
-                  }
-                })
-                break;
-              case 'field_thesaurus':
-              case 'field_tags':
-                field = included.attributes
-                field.id = included.id
-                break;
-              default:
-            }
-            this.content[key].push(field)
-
-          }
-        })
-      }
-      // extract first visuel as accroche
-      this.content.image_accroche = this.content.field_visuel.shift()
-
-      // fill the lightbox
-      for(let visuel of this.content.field_visuel){
-        this.content.lightbox_items.push(visuel);
-      }
-      console.log('this.content.lightbox_items', this.content.lightbox_items);
-
-      // update main page title
-      this.$store.commit('Common/setPagetitle', this.content.title)
-
-      this.loading = false;
-      console.log('article.content',this.content);
-
-    },
-
     onNext(){
       // console.log('clicked on next', this.prevnext.next);
       let alias = this.prevnext.next.view_node.replace(/^.?\/blabla\//g, '')

Some files were not shown because too many files changed in this diff