Creating a Custom Acquia Site Studio Component with Twig Template
If you’ve worked with Acquia Site Studio before, you know how powerful it is and how quickly you can use it to build components, CSS Definitions, and template layouts. As of a recent update, you can now create custom components using file structure. The great thing about this is that you can build a Site Studio component with the standard Site Studio forms and then pass this data into a Twig template structure that normal Drupal users and developers already know. These components are then available in your normal Site Studio ecosystem.
Interested in trying this feature yourself? I’ll explain how you can create these custom components.
Getting Started
Before building anything, you must decide whether these components will live inside a custom theme or module. For ease of content separation, we usually create a new custom module with the naming convention “some_project_site_studio.” Inside this module, you need your normal “.info” file to define the module and the “.module” file. We’ll explain the “.module” file and how it’s helpful later. Within this module, you need a folder called “custom_components,” where you’ll place all your new components.
For our example, I’ll build a simple search block widget. Something that will display a container with a title, a tooltip, and an input box. As far as file structure goes, here’s how it would look:
- some_project_site_studio
- custom_components
- some_project_component
- component_img.jpg
- some-project-component.css
- some-project-component.js
- some-project-twig-template.html.twig
- some_project_component_name.custom_component.yml
- form.json
- README.md
- some_project_site_studio.info.yml
- some_project_site_studio.module
I’ll explain what each of these files does before continuing:
- component_img.jpg
- An image that Site Studio shows as a thumbnail for the component. Consider the size of this thumbnail when creating the image.
- some-project-component.css
- Base CSS file for this component.
- This CSS will only load when this component is placed onto the page. It will be referenced as a library within the “some_project_component_name.custom_component.yml” file.
- some-project-component.js
- Base JS file for this component.
- This JS will only load when this component is placed onto the page. It will be referenced as a library within the “some_project_component_name.custom_component.yml” file
- some-project-twig-template.html.twig
- The Twig template that will render when the component is used.
- some_project_component_name.custom_component.yml
- Defines the component, libraries, dependencies, etc.
- form.json
- JSON file that is built in Site Studio to create the component.
- Holds the data for the form inputs/data used in the render process.
- README.md
- General README file because in the future, you’ll want to know what this component does.
YML File Definition
This should be familiar to anyone who has built a Drupal module before, but there are some minor differences. Within the “some_project_component_name.custom_component.yml” file we would want to add the data needed for this component:
name: Search Widget
category: cpt_cat_uncategorized
template: some-project-twig-template.html.twig
js:
some-project-component.js: {}
css:
some-project-component.css: {}
dependencies:
- core/jquery
form: form.json
preview_image: component_img.jpg
The NAME is just the name of the component that the users will see when adding it to a Layout Canvas. The CATEGORY is the machine name for the component category you want it to be listed under. TEMPLATE is the filename of the Twig template file. JS and CSS references load those files into the component. DEPENDENCIES are any dependencies that need to load for this component to work. FORM is the Site Studio components JSON file that will be created shortly. PREVIEW_IMAGE is the Site Studio thumbnail image displayed for the end user.
Build the Site Studio Component
Once you understand the component in the file structure, you can begin building it. First, create the component in Site Studio by going to Site Studio >> Components >> Custom component builder in the menu.
You’ll see that it’s like a normal component, just without most of the Layout Canvas options. For this example, we know that we need three pieces of information that a user would need to enter for this component to be useful: Title, Tooltip, and a Page URL.
You will get most of the normal input field options so a user can load the data needed into the template. Once this is built, there’s a button at the bottom for “Download form JSON.” This is the “form.json” file that will be placed inside your component's file structure. So just put this file there and you’re done with the components data portion.
Create the Template
Within the “some-project-twig-template.html.twig“ file you can start to add the structure of the Twig file. It would look something like this:
<div class="search-widget">
<h2>{{ field.title }}</h2>
<p>{{ field.tooltip | raw }}</p>
<form method="get" action="{{ field.search_page_url }}">
<input type="text" class="coh-input" name="search_api_fulltext">
<input type="submit" class="coh-button" value="Search">
</form>
</div>
Note that the fields are rendered from the content entered from the Site Studio component. You would use “{{ field.whatever }}” to view the resulting data. You can use the “{{ dump(field) }}“ call to temporarily show all the fields the component renders. Remember that when the info gets passed to Twig, the dashes in the field machine name will be converted to underscores.
JS / CSS / Dependencies
I won’t go into depth here because these depend on each component’s requirements. These files will load based on the information passed into the component’s YML file. For the JS file, you can still use a normal Drupal behaviors process and generic JS if needed.
Test Out the Component
Now you have everything you need to display the component on a page. Add it to the Layout Canvas, fill out the fields, and see how it looks:
This example has some additional styling from the site I’m sampling from, but otherwise, the template would render the Twig file with the user input in the component.
Extras
“.module” File
The “.module” file is extremely helpful if you need to preprocess data before rendering something to the component. Our example is straightforward, but in some cases, you may need to do something different with the user input data or render something else based on that information. To do this, you need to implement “HOOK_preprocess_HOOK” in this file. Here is an example:
function
some_project_site_studio_preprocess_custom_component_some_project_component(&$variables): void {
…
}
So, the first HOOK is the module name, then “_preprocess_”, and the second hook would be “custom_component_” plus the name of the custom component. In this case “some_project_component”.
Some reasons you may use this are:
- Changing/Adding a variable based on user input
- So maybe if “field.title” needed to be something different you could have some process assign it to something else:
- variables[‘field’][‘title’] = “something else”;
- Rendering a view based on user input
- $variables['search_view'] = $view->buildRenderable('block_1', $args, FALSE);
- Catch a URL parameter and pass it back to the template:
- $variables['keywordSearch'] = \Drupal::request()->query->get('search_api_fulltext') ?? '';
Inline CSS
For most use cases the CSS file pre-defined in the YML file will suffice, but sometimes you need to use data that a user enters to define a style. In that case, you can use the “{{ renderInlineStyle(styles) }}” functionality to capture this data and style it. For example, here is a use case when we need the user to define an icon for a component, and then we need to add it to a style:
{% set styles %}
<style>
…
.project-social-share a.icon::before {
color: black;
content: {{ field.icon_picker | raw }};
font-size: 1.6rem;
}
…
</style>
{% endset %}
{{ renderInlineStyle(styles) }}
Use Twigs “dump()” function to get an idea of the field data when adding it to the template, but in this case, we just used “raw” formatting for the icon and it allowed the icons to show as needed.
Creating Your Own Custom Components in Acquia Site Studio
Following the steps in this post, you too can create custom components in Acquia Site Studio. First, take some time to understand the custom component’s file structure. Once you do you can start building it. Start with our example to see how it’s done or try something new yourself.
If you have any questions about the steps in this post, please don’t hesitate to reach out. Our team, including our Triple Certified Drupal Expert, would happily assist you.