elgentos / magento2-prismicio

Magento 2 Prismic integration
GNU General Public License v3.0
38 stars 18 forks source link

Add CLI command to scaffold content-types #37

Closed peterjaap closed 5 months ago

peterjaap commented 3 years ago

We could create a CLI command that scaffolds PHTML/XML for content-types. Let's say you have a content type in Prismic called authors.

You would then run bin/magento prismic:scaffold --title authors--content-type authors --route authors --theme Vendor/Theme --overview. The overview flag would be optional, to create an overview page.

The title and route flag would also be optional. If these are passed we could create the route entries;

INSERT INTO prismicio_route (title, content_type, route, status) VALUES ('authors', 'authors', '/authors',  1);
INSERT INTO prismicio_route_store (route_id, store_id) VALUES (1, 1);

The command would then generate:

Detail page XML: app/design/frontend/Vendor/Theme/Elgentos_PrismicIO/layout/prismicio_by_type_authors.xml

<?xml version="1.0" encoding="UTF-8" ?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="prismicio_content">
            <block class="Elgentos\PrismicIO\Block\Template" template="authors/detail.phtml">
                <block name="author.title" class="Elgentos\PrismicIO\Block\Layout\PageTitle">
                    <block class="Elgentos\PrismicIO\Block\Dom\Plain" template="data.title"/>
                </block>
        </referenceContainer>
    </body>
</page>

Detail template; app/design/frontend/Vendor/Theme/Elgentos_PrismicIO/templates/authors/detail.phtml

<?php declare(strict_types=1);
/** @var $block \Elgentos\PrismicIO\Block\Template */
?>
<h1><?=$block->getChildHtml('author.title');?></h1>

And if the --overview flag was passed, also generate the overview XML/template & card template;

Overview page XML: app/design/frontend/Vendor/Theme/Elgentos_PrismicIO/layout/prismicio_route_index_authors.xml

<?xml version="1.0" encoding="UTF-8" ?>
<page layout="2columns-right" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <title>Authors</title>
    </head>
    <body>
        <referenceBlock name="page.main.title" remove="true" />
        <referenceContainer name="content">
            <block class="Elgentos\PrismicIO\Block\Overview" template="Elgentos_PrismicIO::authors/overview.phtml" name="authors.list">
                <arguments>
                    <argument name="content_type" xsi:type="string">Authors</argument>
                </arguments>

                <action method="setDocumentType">
                    <argument name="documentType" xsi:type="string">authors</argument>
                </action>

                <block class="Elgentos\PrismicIO\Block\Group" name="authors.document.index" template="results">
                    <block class="Elgentos\PrismicIO\Block\Template" template="Elgentos_PrismicIO::authors/card.phtml">
                        <block class="Elgentos\PrismicIO\Block\Dom\Plain" name="author.document.title" template="data.title" />
                        <block class="Elgentos\PrismicIO\Block\Dom\Link" name="author.document.link" />
                    </block>
                </block>

            </block>
        </referenceContainer>
    </body>
</page>

Overview template; app/design/frontend/Vendor/Theme/Elgentos_PrismicIO/templates/authors/overview.phtml

<?php declare(strict_types=1);
/** @var $block \Elgentos\PrismicIO\Block\Overview */

$contentType = $this->getContentType();

$documents = new \stdClass();
$documents->results = $block->getDocumentsWithoutLanguage();

/** @var Elgentos\PrismicIO\Block\Group $documentRenderer */
$documentRenderer = $block->getChildBlock('authors.document.index');
$documentRenderer->setDocument($documents);
?>
<div class="posts">
    <header class="posts__header">
        <h4><?= __($contentType) ?></h4>
    </header>
    <?= $documentRenderer->toHtml(); ?>
</div>

Card template: app/design/frontend/Vendor/Theme/Elgentos_PrismicIO/templates/authors/card.phtml

<?php declare(strict_types=1);
/** @var $block \Elgentos\PrismicIO\Block\Template */

$document = $block->getContext();
$document->link_type = 'Document';

$authorName = $block->getChildHtml('author.document.title');
?>

<a href="<?=$block->getChildHtml('author.document.link'); ?>"><?=$authorName;?></a><br/>
peterjaap commented 3 years ago

We could (and this is dangerous territory ;)) use the Prismic API to query the field types and generate the block definitions as well, but that would involve a large number of assumptions.

peterjaap commented 3 years ago

First stab at scaffolding; https://github.com/elgentos/magento2-prismicio/tree/scaffolding

There are a number of assumptions, hard-coded examples and omissions, most notably;

Ideally, we should provide another command (or a flag) that allows us to either pass the JSON from Prismic or even better, query the Prismic API to retrieve the content type configuration. It can then infer block classes (Elgentos\PrismicIO\Block\Dom\Plain / Elgentos\PrismicIO\Block\Dom\RichText/ Elgentos\PrismicIO\Block\Dom\Url / etc) based on the field type and generate the XML's.

Output;


 ✘  ~/development/workspace/client/magento2   master  php bin/magento prismic:scaffold blog
Please select a theme:
  [1] Magento/blank
  [2] Hyva/reset
  [3] Magento/backend
  [4] Magento/luma
  [5] Hyva/default
  [6] Client/Hyva
 > 6
Copied prismicio_by_type_blog.xml into /data/client/magento2/app/design/frontend/Client/Hyva/Elgentos_PrismicIO/layout/
Copied prismicio_route_index_blog.xml into /data/client/magento2/app/design/frontend/Client/Hyva/Elgentos_PrismicIO/layout/
Copied blog-list.phtml into /data/client/magento2/app/design/frontend/Client/Hyva/Elgentos_PrismicIO/templates/
Route prefix: [/blog] 
Route /blog created for store 1
Create a new custom type called 'blog' in Prismic and paste the following JSON into the JSON editor field
{
  "Main": {
    "uid": {
      "type": "UID",
      "config": {
        "label": "uid",
        "placeholder": "UID"
      }
    },
    "title": {
      "type": "StructuredText",
      "config": {
        "single": "heading1, heading2, heading3, heading4, heading5, heading6",
        "label": "Title"
      }
    },
    "author": {
      "type": "StructuredText",
      "config": {
        "single": "heading1, heading2, heading3, heading4, heading5, heading6",
        "label": "Author"
      }
    },
    "image": {
      "type": "Image",
      "config": {
        "constraint": {},
        "thumbnails": [],
        "label": "Image"
      }
    },
    "publish_date": {
      "type": "Date",
      "config": {
        "label": "Publish Date"
      }
    },
    "content": {
      "type": "StructuredText",
      "config": {
        "multi": "paragraph, preformatted, heading1, heading2, heading3, heading4, heading5, heading6, strong, em, hyperlink, image, embed, list-item, o-list-item, rtl",
        "label": "Content"
      }
    }
  }
}

 ~/development/workspace/client/magento2   master  gst
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        app/design/frontend/Client/Hyva/Elgentos_PrismicIO/layout/prismicio_by_type_blog.xml
        app/design/frontend/Client/Hyva/Elgentos_PrismicIO/layout/prismicio_route_index_blog.xml
        app/design/frontend/Client/Hyva/Elgentos_PrismicIO/templates/blog-list.phtml
peterjaap commented 3 years ago

Created a video to show how easy the process is; https://www.youtube.com/watch?v=ze1j91-4_OE

JoostWan commented 3 years ago

@peterjaap thanks for the great work! It's working over here. But when i change the pageSize to 5 and there are more than 5 posts there is no pagination. Is this already available in the module?

peterjaap commented 3 years ago

@JoostWan I also noticed that didn't work. Have you found a solution in the meantime?

peterjaap commented 3 years ago

The scaffold command has been merged into version 1.6.0, and it is now a bit more generic; just run bin/magento prismic:scaffold yourcontenttypename to scaffold a very basic template with an XML.

JoostWan commented 3 years ago

I was just checking if we can use the module for a client. Maybe i have some time later to fix this.

peterjaap commented 5 months ago

I'm closing this issue since it turns out, this isn't needed that often. We have a basic command in place for learning purposes and we also have SliceMachine now.