Používání Craft 3 jako bezhlavého CMS s GraphQL a Vue Apollo

Používání Craft 3 jako bezhlavého CMS s GraphQL a Vue Apollo
Jako člen skvělého týmu ve společnosti Telegraph jsem měl nedávno příležitost používat Craft novým způsobem a myslel jsem si, že ostatním by mohlo být užitečné přečíst si o našem procesu. Náš tým měl za úkol přidat na web Neighborhood Goods funkcionalitu, která umožní zjistit polohu návštěvníka a nabízet obsah a produkty na základě nejbližšího obchodu Neighborhood Goods.

Nastavení

Neighborhood Goods spoléhá na Shopify pro online prodej a správu zásob. I když jsme zjistili, že Shopify je v těchto úkolech skvělý, při pokusu o správu redakčního obsahu selhává. Základní položky blogu fungují dobře, ale když začnete přidávat složitější rozvržení, události a obsah specifický pro umístění, Shopify se nezdálo, že by tento úkol splnilo.

Vstupte do CMS CMS! Jsme velkými fanoušky Craftu a zatímco Twig může být užitečný pro vytváření šablon v rámci Craftu, naše soubory šablon stále potřebují, aby žily v oblasti šablon Shopify, aby mohly využívat celou sadu funkcí Shopify. To nás vedlo k použití Craft 3 jako bezhlavého CMS, který by poskytoval všechna naše data přes GraphQL API. Bylo to poprvé, co jsme pracovali s pluginem CraftQL a díky tomu bylo nastavení schématu GraphQL a správa granulárního ověřování docela snadné.

Jakmile byl CraftQL nastaven, obrátili jsme se na Vue (náš vybraný rámec Javascriptu) a Vue Apollo, abychom využili naše API v šablonách Shopify. Díky tomu bylo vytváření ad hoc dotazů pro náš vývoj frontendu snadné. Zhruba 90 % našeho nastavení bylo vše připraveno k vybalení z krabice. Setkali jsme se s několika problémy a napadlo mě, že se o ně zde podělím.

Co je třeba zvážit

Jeden problém, na který jsme narazili u tohoto nastavení, je způsob, jakým zpracováváme maticová pole. Obvykle, pokud máme část stránky, která by mohla zobrazovat různé typy obsahu, vytvoříme maticové pole s několika volitelnými typy bloků. Například:pokud existuje stránka, která zobrazuje základní text odstavce a také volitelné obrázky hrdinů nebo text hrdinů, vytvořili bychom maticové pole, které vypadá takto:

Potom v Twig můžeme procházet každý typ bloku a zahrnout správnou šablonu. To poskytuje velkou flexibilitu pro obsah, kde můžete mít jeden, mnoho nebo žádné bloky určitého typu a mohou být v libovolném pořadí.

    {% if blocks | length %}
        {% for block in blocks.all() %}
            {% switch block.type %}
                {# Article Body #}
                {% case "articleBody" %}
                    {% include '_components/longform-blocks/article-body' %}

                {# Text Hero #}
                {% case "textHero" %}
                    {% include '_components/longform-blocks/text-hero' %}

                {# Image Hero #}
                {% case "imageHero" %}
                    {% include '_components/longform-blocks/image-hero' %}
            {% endswitch %}
        {% endfor %}
    {% endif %}

Při testování této struktury na hřišti CraftQL vše vypadalo dobře:


    query {
        entries(id: 3) {
            title
            id
            ...on MatrixExample {
                dynamicContent {
                    ... on DynamicContentBodyText {
                        copy
                    }
                    ... on DynamicContentTextHero {
                        text
                        backgroundColor {
                            hex
                        }
                    }
                    ... on DynamicContentImageHero {
                        image {
                            url
                        }
                        caption
                    }
                }
            }
        }
    }

Při pokusu o stažení tohoto dotazu přes Vue Apollo jsme však narazili na následující chybu:


WARNING: heuristic fragment matching going on!

Ukazuje se, že Vue Apollo dokáže zpracovat maticová pole, pokud existuje pouze jeden typ bloku (tělesný text v příkladu výše). Pokud existuje více typů bloků (hlavní text a textový hrdina atd.), Vue Apollo varuje, že nezná celé schéma a nemůže předvídat, jaký typ obsahu přijímá. Po nějakém pátrání jsem zjistil, že nejsme jediní, kdo se s tímto problémem setkal.

Naše řešení tohoto problému skončilo kombinací rozhodnutí o maximálním počtu sekcí a vytvořením polí textových a obrázkových aktiv, která se přizpůsobí, a vytvořením maticových polí s volitelnými poli, která by mohla mít dvojí účel (tj.:Hero Matrix, která může přijímat buď text nebo obrázek).

Další možností, jak je popsáno v problému Github, je spustit skript na příkazovém řádku (./craft craftql/tools/fetch-fragment-types ), který vygeneruje soubor JSON, který zahrnete do vašeho nastavení Vue Apollo. Při zpětném pohledu se to zdá jako dostatečně snadný úkol, pokud si všichni ve vašem týmu pamatují spustit příkaz po úpravě polí v Craftu. Tento přístup bych rád vyzkoušel na budoucích projektech. Použili jste tento přístup? Máte nějakou radu, jak jej integrovat do vašeho pracovního postupu vývoje/nasazení?

Jedna další věc, která nebyla tak přímočará, jak jsem doufal u CraftQL, je dotazování podle hodnoty pole. Při dotazování na položky můžete použít slug takto:

    query {
      entries(
        type: MatrixExample
        slug: "first-example"
      ) {
        id
        title
      }
    }

Doufal jsem, že bychom mohli udělat to samé při dotazování pomocí pole kategorie, které je připojeno k položce, ale v tuto chvíli můžete tento vztah dotazovat pouze pomocí ID:

    query {
      entries(
        type: MatrixExample
        relatedTo: [{element: 36}] # 36 is the Id of our Category
      ) {
        id
        title
      }
    }

Jdeme vpřed

Craft 3.3 nebo novější s licencí Pro nyní obsahuje funkce GraphQL. Na základě krátkého pohledu se zdá, že nastavení je trochu jiné než u CraftQL. Zajímalo by mě, jestli tam jsou nějaké výhody ve výkonu/funkčnosti. Použili jste oba? Máte nějaké myšlenky na jejich srovnání?