Atomic Design in Drupal with GraphQL & Twig / DrupalCon Global 2020

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so we're going to talk about atomic design in drupal and how graphql and tweak can help us to build a clean concise and well-structured front-end which has been atomic design and drupal haven't been great friends ever so all approaches to connect drupal to pattern lab or in our case fractal and gradually building up user interfaces from small building blocks doesn't work very well with the way drupal thinks about render arrays and the way it builds up a page before it's sent to the browser but first uh let's start with a short recap of the first amazing art so we were talking or we presented you the idea of using graphql in tweak to fetch data into drupal templates into actually any drupal template uh without the need to implement pre-processing functions that are hard to track and keep in mind um we showed you how queries are assembled automatically if um templates include other templates and how to achieve the coupling within drupal so instead of using react we're going to decouple our applications in drupal first and this time we're going to do a real world example we're going to build a website for a completely fictional web agency called amazing apps and the end result will look like this um and this might be a little much for one hour but we wanted to pack in as much information for you as possible so we we came up with a different approach so we have prepared a github repository that contains all source codes necessary to to build and run this website there's also a readme to do this you don't have to do this right now because what we're going to do now is i'm essentially talking you through the the git history of this repository and we look at all the steps that have been taken to acquire this end result and you can have a look at this repository later or open it right now and just look at it on the go and also refer to the recording of this webinar later on when you tried out yourself so this is the project on the left you see the git history and we're going to start from the bottom there are first a lot of less interesting parts there is just we initiated the project with the drupal composer template so it's a vanilla drupal installation built with composer then we have some handy configuration files we exported the initial site configuration basically from uh it's it's a little cleaned up drupal standard profile installation without commands and the conflict module because we don't need that right now then we added the modules that were required to build this website so this is for first of all providing default content that you can easily test it we added better normalizers default content and our own default content module to provide test content and the actual important part is we're using obviously the graphql module the graphql core module which is included in the graphql module and provides all the graphql fields and resolvers of on behalf of drupalcore the graphql tweak module and the graphql views module then in the next step we just committed some developer friendly settings since this website is not supposed to be deployed to a production environment anyway so the graphql endpoint is accessible for anonymous users from the outside so you can use insomnia or the phpstone graphql extension to help you then the caches are turned off and tweak debugging is turned on by default if you check out this repository then we added some image presets that we're going to use and since this is a company website we added node types for job offerings so we have a open position the jobs listing and team members and then we also created a view with a graphql display so this is the that's where we use the graphql views module that will provide a field that allows us to fetch related content based on taxonomy terms so every node will have a graphql field that lists all other nodes that share the same taxonomy terms as this node then we created a lot of default content and we initialized a completely empty theme and then we finally get to the part where it gets interesting we initialized fractal within this theme so fractal is an atomic design tool it helps you to build ui components in the well-known atomic design structure or basically any structure you want to build them in and creates a nice display and we're going to just switch into our themes folder and run npm run dev obviously i did an npm install beforehand and this brings up the right now empty fractal interface so below this section here there should be components as soon as we have some so we're going to switch back into our git history i think we can jump over the readme and there is uh the addition of the first basic styles so this is the the lowest level uh of atomic design our basic styles that apply directly to already existing html elements we're going to define some colors very fancy with css custom properties uh then just have some demo text content to showcase how text is going to look like uh headline examples ordered and unordered lists just an image and a theming layer that allows us to switch colors for certain regions of the page and styling for drupal tabs we're going to check out this revision and switch back into fractal and it already updates it we can look through the color presets so the design consists of like three colors so default is just white black just yellow and blue we shouldn't resemble a well-known cooperative entity uh then this is our text base style then different header variants unordered all of lists an image so we have we laid the groundwork to build on top of that so we have our colors we have our typography all in place so the next important part right now if we look at the drupal side so nothing is down here the home page is also not found yet but we already see that this the font doesn't applied to this so in the next step we link the style sheets the fractal that the style sheet that fractal builds into our drupal theme by creating or defining a drupal library that basically just loads from this style.css that's the the build directory that we configured for fractal and require this library in our theme info that's it check out this revision and here we go well at least the fun change so now it's time to create our first actual component and it's going to be the logo the logo is as easy as possible just an embedded svg shape and some stylings for coloring that svg according to the current text color and automatically sizing appropriately and we're going to check out this revision and look at frankfurt let's close the base the new section atoms appear and here's our logo so what else will we need obviously a menu so we've created a basic menu molecule and that's where it gets a little more interesting because we're actually going to use graphql so if we look at the menu.twig file that's rather simple we are rendering an unordered list with class menu and we're iterating over a variable called links and we expect every link to contain a url and a label and we're rendering just this list and this is going to be our menu then there is the menu.config.yml config.yml files in fractal allow you to provide test data for your component and here we're pre-filling this links variable with just some test items and the most important part is this menu.twig dot graphql this file as we already learned in the last amazing r will automatically be picked up as soon as tweak renders this menu dot tweak and here we're just defining a fragment this is not yet a query but we're defining a fragment to pull all information from a menu in drupal to actually display this menu so how to how do we get here um if we switch back to drupal and go to the graphql explorer your one-stop shop for trying out and playing around with graphql and we search the schema for menu so we can see that there is a menu type that has the links property a description of this menu and the name and we also see that the root query type has a field called menu by name and that's what we're going to use it's already initialized here restart anyways so we're going to fetch a menu and the name is just the main menu then we want all links this is an object that white complains and wants us to pull additional properties and we're going to need the label and the url which is an object itself and from this url the path and executing this query will essentially give us back exactly the structure that we're expecting in our menu component template and if we're going to check out this revision we can have a look at fractal we have new section molecules that contains the menu that just renders a menu down here in fractal that's quite handy we have the rendered output to look at that's nice for debugging uh the template that is being rendered the data that is put in by fractals or test data in this case and also additional assets like this is the css file that will be loaded and you can also add additional documentation or information to you to your components so the page will add this add this logo atom and the menu molecule essentially in the header and the footer of the page and that's what atomic design kind of refers to as organisms so organisms are the the biggest building block and they're essentially so i think i'm not sure if there is a hard rule on that but in general an organism should not be included in another organism because this would be weird if you think about it so organisms are the top level building blocks that you use to assemble your pages and we defined here a header and the footer organism if we look at header.twig it includes the logo and the menu component and what's important here is this hash logo to address the logo component that's something we included both in graphql tweak so graphql tweak will search the components folder and enables you to address any any component template that's in there with hash component name and fractal that our fractal configuration does the same so components can be addressed the same way in fractal and in drupal and that's how we can make them work this nicely together then the header has itself again a graphql fragment and this time this fragment actually pulls the main menu and then applies our menu fragment from before so it just says okay i'm going to use this object and i'm going to use this template and by referring to the templates definition of which information it needs we can make sure that the responsibilities are where they should be so the header just says which menu and the menu can define how to render and which information then we also have some stylings for the header and uh also a configuration file and this time we're using another fractal feature in the context instead of again defining data for all menu items we're going to fill the header math variable with add menu and fractal will pick this up and just pull in the context that has been defined in the menu component so that's how you don't have to recreate your test data throughout all your components all over the place and the footer organism looks very similar so we're also including including a menu and then a hard coded contact block and the main difference is that we're going to fetch a different menu but with the same structure again the same menu component with the same menu fragment and we have two layout organisms that's our header it included the logo on the left and the menu on the right and the filter organism which has this contact block and again the menu on the right so now we obviously want to put these two organisms somewhere and so we're advancing to the next level of atomic design which is layout and we're going to define a layout um that will be the the top level frame of our page and layouts are a little different at least in from from our perspective than other components because they don't or they should not or that's kind of a best practice that we derived for ourselves that layouts don't get data and display it but and this works very well together with twigs they just expose blocks that can be overridden so in tweak you can define a block in any template and another template that extends on this can override whatever this block is doing and then we also have some stylings for this layout and then we're going to look at it so this is our layout we have a yellow themed header area a standard white content area and this dark colored filter and this dash boxes are essentially rendering of this placeholder component that was included in our basic fractal setup and now we would like to bring this layout into drupal and that's our first step where we get back into our group theme so we defined a page.html.twig and that's where we actually start writing a graphql query so our page.html tweak defines this query on top and just calls the header and the footer fragment so it just it just tells the system includes into this query whatever header and footer need to display the page template itself doesn't know what this is uh and then it i said before extends the page layout from our from our atomic design pattern and it overrides the header block to instead of displaying this placeholder box actually including the header component and passing in whatever is in the graphql variable so the query results of this query will end up in a tweak variable called graphql and we know that uh in this case we don't have any fields ourselves so we just can pass in the whole object and again including the header component automatically make sure that this header fragment is available then the content block in the content block we are for now just rendering uh the group whatever is in the drupal themes content area so no no graphql or tweak magic at this point and then the filter is again the same as the header so we're going to check out the revision just to be sure there it is our header and footer with the menu items that are actually [Music] in our main menu the page itself is not yet found since we have tweak debug mode enabled um we get this nice little graphql icon on the top left actually of every template that uses a graphql query and clicking here brings us into the graphql explorer with the query that was assembled for this template ready to be debugged so that's our main debugging feature to check which query has been built for this template and is executed and it will also pass the right variables as we will see later on okay so we have our overall frame for this page for this website we successfully connected and executed a graphql query that was built by our patent library in drupal and used it to populate our first first components in drupal and now we're going to draw the rest of the hole so there are a lot of other components obviously in there and in use and they all follow roughly the same pattern so we have html component we provide some dummy data in fractal and then we map them to drupal but this is checking out this revision will seriously populate a fractal instance so if we have a rough look so we've already seen everything in base uh then we have more link that can be used for wherever we want to display something like read more like in teacher listings a special style publish date which is an interesting perhaps because it like pulls the date twice and runs it through uh tweaks date filter so the layout or the design is in tight control of how everything is displayed then we have a simple title component which is a little larger h1 then there are teaser components with a thumbnail listings of teasers then a teaser box that has a listing and a headline and this more link at the bottom and they come in different colors then our organisms in our organisms we define or we assembled now from all these components that you've seen before uh different types of pages so this is what our homepage is going to look like then a simple basic page which just consists of the headline and the text a blog with a header image that will also display related data at the bottom then a blog listing page and generally the same for jobs and for team then there is another layout called grid that just assembles a couple of elements in the grid and then what we have not seen yet there are also pages so pages are the not really a part of the atomic design but the uppermost layer where you just assemble demo pages to showcase your design to the client essentially so we have one sample page that just shows the outermost layout but without any content and then we have a example page component that will just showcase the page layout with all content organisms a feeling light looks like you can also click here and switch your full screen motorcycle okay so we just have every uh every little piece of design we need to display our page or our whole website but it's still not connected to drupal and that's we're going to look at a new nice little feature we've got in graphql tweak we don't have a real name for it but i called it just theme based routing so in your theme you can define like something that are just easy route static routes that you need we have our home route here and this basically causes drupal to create a new menu callback that will just search for a template called home.html.tweak and try to display it with graphql so this is our home.html.tweak and it will just include the home component and the home component defines the home home page fragment we can look at this here so we have the home component for example that includes a title with a hard-coded title within our template and some nice sublime and then it includes the teaser box three times uh with different notes so first with team listing then with the jobs listing and then with the blogs listing and this is our homepage fragment that exactly exactly does that so it fetches loads of type job that are published and just gets the latest three of them and roughly the same happens also for blog team and jobs in these cases the queries are easier and they include other components but that's something you can look at later yourself and if we check out this revision our page should be fun yes um so home is defined as the home page the start page in this apple installation now we see now that we have the second query active within this page render which makes a lot of sense um since this is a separate template uh which is fully dependent on the current path or where we're at and the outermost query that just fetches the menu for header and footer doesn't depend on the current path at all uh and therefore can also be cached across all requests so it makes a lot of sense to have two queries here it's also often a question when it comes to graphql is should we cram everything into one query no you shouldn't because often it makes sense to use two queries to allow better caching if we have everything in one query this would mean the whole query and also the menus would have to be refreshed for for every different page and this way we can optimize caching and we have a second debug button that will bring up the assembled query for the home page so this is the query part that we've seen before um and we also need the teaser fragment in this case which defines that we need the title the dates the url and the thumbnail image to display the teaser foreign and this should also work for all the other pages now but this is blog listing jobs listing and the team listing which all look kind of the same and the last part that we still missing is the actual node display so this is still the standard drupal rendered node and we also want to display nodes the way we defined it so we have already have a team member component that displays the team members portray on the left and the content on the right and also shows blocks blog posts in this team members field of expertise and jobs that you could apply to to become a colleague of him or her and to do this we do something that is actually very similar to what we do in react we're building a generic node template that as you see on the right we'll just fetch the current node so that's something where we're overriding node.html in nodehtml.twig there is already a variable called node that contains the current node and graphql tweak tries to match existing template variables to query arguments of the current query that is executed for this template and in this case it also [Music] transforms entities into their string representation which is the id and then we load the node again which looks a bit clunky but it's not a problem in this case because the node is already in the drupal's entity cache so this is not a performance problem and what we do then is we're going to fetch the type name and then apply uh simply all fragments for um of these organisms that define these content pages so we have one organism for the basic page one for the article and one for the team member and one for the job and every one of these comes with its own graphql fragment to define what this page needs or what this node actually contains and needs to be displayed so we just assemble them all in a query so all these fields get fetched if they're available and then based on the outcome of this type variable if this is a node page node article node team member or nodejob offer we're just going to include a different different component and this way we don't have to recreate node.html.twig for every node type but can make this a little more dynamic unfortunately it can't be super dynamic so we're not able to have something like include and then just a variable that contains the type name that's because the graphql query is assembled at tweak compile time so to not lose performance on assembling queries we're collecting the query and all these fragments um when the tweak template is first compiled into a php file but at this time we have no idea what the variables are so this whole automatic assembly of the of the graphql query only works when includes is used with a static variable with a static string then it will know to attach the page fragment that is needed to properly execute this query and so we're going to check out this revision and clear the cache again and here's our layout along with related content and if we look at this query we see that these are our types that we added and these are the fragments so the in case of a node page we just pull the label into processed body text in case of an article we also want the image field and this is where graphql views that we've seen at the very beginning kicks in so this is a field that is defined by views and will match just taxonomy terms and find related notes based on that and we just return these notes and apply the teaser fragment to get everything a teaser needs to to be displayed and so on yes so this is the end of our git history um time for questions if you have something cool um thanks philip justin has a quick comment which is um what advice would you give on when this approach makes more sense than going fully to kaput budget so this way you can leverage atomic design or well well-structured design that wouldn't be possible with plain drupal rendering because triple forces you to use four different templates to render this thing if it's a view but you don't have the budget or the the risk you can't take the risk to go fully decoupled because there's still a lot of stuff that doesn't work in a fully decoupled environment and the other thing is uh you might not need fully for like this page has barely any benefits from being implemented in react technically because it would be statically cached by varnish and just pushed out and there would be a very small performance margin you would gain by using react in this case that probably wouldn't justify the much higher effort of actually implementing this in react um especially if you perhaps want to use a contact form where you would have to implement mutations again and make this work with react or even the the big you know the big elephant in the room is still web form very beloved module that has a very a lot of great use cases and we still just don't have a proper way to decouple it yet cool justin writes here makes sense thanks daniel writes using this approach are you missing functionality like quick edit that comes in color um in this example yes but technically you don't have to because for example quick edit just relies on some data attributes on text like on the field wrapper tag and you could emulate them yourself and the other important part is that you don't have to uh run everything for graphql so if you for example have a node that is just fine if you display it with drupal's standard mechanisms you can keep it this way and for this very complex um portal page where you pull in information from different drupal sources and perhaps even external sources like in the first amazing now we had this example where we pulled the number of drupal bugs from drupal.org uh live into drupal with graphql that's where we can use graphql so the the key here is that you don't have to go all in and decouple everything but you can use graphql and this whole power of decoupled components where it makes sense and where it helps you and you don't have to throw everything away that drupal brings you cool thanks alvaro has a question what if i have a block with some specific cache context like user or a short lifetime do i have to be careful with some special stuff um block in which context so you can if you just render a block it will be just so for example this whole the content area is just used as a block and it will it will just behave as every drupal block does then if you are going to if you override the block template and use graphql within the block uh graphql will pass on all cache information that it collects during its query and give it to the rendering layer and there again it's just handled the way drupal intends it to be there's also the possibility to actually fetch blocks within graphql by region but that's probably not something you would use with graphqlm3 so i'm not completely sure what what you would have to be careful about in this case okay cool um is there any other questions feel free to write in the q a or the chat or raise your hand and i can allow you to talk as well perhaps in the meantime we could run a little experiment since we have some time sure so what's now nice about we might want to display the taxonomy terms along with a blog article so um how would we approach this particle theme um daniel could you elaborate what you mean by particle theme ah no no in this case we we're just really using if you look at the configuration this is really a completely vanilla drupal theme it doesn't even extend on stark it's just it doesn't have a base feeling uh and all we did is initiate fractal in there and then link the style sheet and the important part or the only connection we have to fractal um is if we look at the fractal configuration so we're using the the tweak adapter for fractal by wondrous and this is the important part we set the handle prefix to hash and there is a dedicated uh template loader in graphql tweak that will just search for all dot tweak files in the components folder within the currently active theme and if the template that you're trying to address starts with within hash then it kicks in and tries to pull this template out of the components folder so that's the only connection we actually really need between graphql between fractal and drupal that they are able to address templates the same way yes um exactly thanks then so you can look through all these codes in the github repository and feel free to join us on uh the drupal slack in the graphql channel so we're constantly answering questions and brainstorming with the community there where graphql should go and we're we're happy for any help and all suggestions um yes and so it's actually i think it's by time for our closing slide thank you very much for watching and listening you
Info
Channel: Drupal Association
Views: 521
Rating: 5 out of 5
Keywords:
Id: VhRXVs3a7EA
Channel Id: undefined
Length: 50min 0sec (3000 seconds)
Published: Tue Sep 01 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.