Building components
9. Creating the Movie List component
Just when you thought "I got this!", we are now going to build a new component that uses slightly different approach. For the most part, most component you'll built follow the same principles you've been following all along, however, there are other type of components that may deviate from those principles a little. When content needs to be displayed in some kind of list or collection of components, there are a few things we need to do differently.
Let's start with our usual process of creating some files and adding the respective code to each file. We will explain everything once this step is done.
Inside nitflex_dev_theme/src/components/ create a new directory called movie-list
Inside the movie-list directory create these files:
movie-list.json
,movie-list.scss
, andmovie-list.twig
Inside
movie-list.json
copy the following code:{ "list_title": "Action & Adventure", "items": [ { "cover_image": "<img src=\"/sites/default/files/action-3.jpg\" alt=\"\" />", "heading": { "title": "Mattis Magna Mollis Pellentesque", "url": "#", "heading_level": 4, "classes": "movie-card__heading" }, "average_rating": "3", "mpaa_rating": "G", "synopsis": "Aenean lacinia bibendum nulla sed consectetur. Maecenas sed diam eget risus varius blandit sit amet non magna." }, { "cover_image": "<img src=\"/sites/default/files/action-3.jpg\" alt=\"\" />", "heading": { "title": "Bibendum Euismod Mollis Quam Egestas", "url": "#", "heading_level": 4, "classes": "movie-card__heading" }, "average_rating": "2", "mpaa_rating": "PG", "synopsis": "Sed posuere consectetur est at lobortis. Nullam id dolor id nibh ultricies vehicula ut id elit." }, { "cover_image": "<img src=\"/sites/default/files/action-3.jpg\" alt=\"\" />", "heading": { "title": "Egestas Fusce Euismod Elit Condimentum", "url": "#", "heading_level": 4, "classes": "movie-card__heading" }, "average_rating": "5", "mpaa_rating": "R", "synopsis": "Sed posuere consectetur est at lobortis. Nulla vitae elit libero, a pharetra augue." }, { "cover_image": "<img src=\"/sites/default/files/action-3.jpg\" alt=\"\" />", "heading": { "title": "Commodo Nibh Justo Sollicitudin Fermentum", "url": "#", "heading_level": 4, "classes": "movie-card__heading" }, "average_rating": "4", "mpaa_rating": "PG-13", "synopsis": "Maecenas faucibus mollis interdum.Donec ullamcorper nulla non metus auctor fringilla." }, { "cover_image": "<img src=\"/sites/default/files/action-3.jpg\" alt=\"\" />", "heading": { "title": "Condimentum Nibh Nullam Fringilla", "url": "#", "heading_level": 4, "classes": "movie-card__heading" }, "average_rating": "4", "mpaa_rating": "PG", "synopsis": "Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit." } ] }
Main difference here from other components is that we have created an
items[ ]
array. The array contains multiple instances of a movie card which we will use to render a collection of movie cards.Paste the following code snippet into movie-list.twig:
{{ attach_library('nitflex_dev_theme/movie-list') }} <section class="movie-list {{- attributes ? ' ' ~ attributes.class -}}" {{- attributes ? attributes|without(class) -}}> <div class="movie-list__title"> {% include '@nitflex_dev_theme/heading/heading.twig' with { "heading": { "title": list_title, "heading_level": '3' } } only %} </div> {% block list %} {% embed '@nitflex_dev_theme/movie-card-collection/movie-card-collection.twig' %} {% block collection %} {% for item in items %} {% include '@nitflex_dev_theme/movie-card/movie-card.twig' with { cover_image: item.cover_image, heading: item.heading, mpaa_rating: item.mpaa_rating, average_rating: item.average_rating, synopsis: item.synopsis } %} {% endfor %} {% endblock %} {% endembed %} {% endblock %} </section>
First, don't forget to create the movie-list library we are attaching above.
Next notice we are using the very helpful include statement to nest the heading component in order to print a title for each collection.
Then we have declared
{% block list %}
so we are able to alter how content is rendered when we integrate this component with Drupal.Inside the twig block, we are using an embed statements to include the previously built movie-card-collection component.
Then we use the
{% block collection %}
twig block to insert a movie card per each item found in the items[ ] array. So if the array has 10 items, we will end up with 10 movie cards in the collection.
Twig blocks
Twig blocks, not the same as Drupal blocks, are a great way to extend twig templates. It can be confusing at first given that all of our lives as Drupal developers we have worked with blocks. However, as Jacine Luisi from Chapter Three puts it in her great article about Twig Concepts in Drupal 8 themes, Twig blocks are more like Drupal regions.
Embeds
This is also a new concept being introduced here and to keep it simple, embeds combines the advantages of includes and extends twig statements into one. They allow us to include an existing component and give us the option to alter the data or how data is printed/rendered. Our own Eric Huffman has written a great blog post which explains Twig blocks, Embeds, Includes and more in detail.
Now paste the component's styles below into movie-list.scss:
// Movie List // // This is the movie list component. // // Markup: movie-list.twig // // Classes: kss-full-width // // Style guide: Components.Movie List // Import site utilities. @import '../../global/utils/init'; .movie-list { background-color: $color-black; padding: 30px 10px 20px; @include breakpoint($bp-md) { padding: 50px 5px 40px; } } .movie-list__title { color: $color-white; padding: 0 5px; text-align: center; text-transform: uppercase; .heading { font-size: 2rem; font-weight: $font-weight-bold; line-height: 1; margin: 0; } @include breakpoint($bp-lg) { text-align: left; } }
Compiling the styleguide
Now that we have writen all the necessary code to build the Movie Listing component, it's time to see the component in the styleguide. Let's compile our project first.
- From the theme's root (
/themes/custom/nitflex_dev_theme
), run the following command:lando npm run build
Viewing the Movie Listing component
Open your drupal site and point to the URL below
http://nitflex.lndo.site:8000/themes/custom/nitflex_dev_theme/dist/style-guide/index.html
Depending on your setup, you may not need to enter ":8000". Also if you did not use the provided Lando setup, ensure you are using your own custom URL.
Under the Components category you should see the new Movie Listing component.