{"id":69189,"date":"2024-12-29T12:48:25","date_gmt":"2024-12-29T07:18:25","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=69189"},"modified":"2024-12-29T17:28:18","modified_gmt":"2024-12-29T11:58:18","slug":"basic-concepts-of-single-directory-component-in-drupal","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/basic-concepts-of-single-directory-component-in-drupal\/","title":{"rendered":"Basic Concepts of Single Directory Component in Drupal"},"content":{"rendered":"<h3>What is a Component?<\/h3>\n<p>In <a href=\"https:\/\/www.tothenew.com\/digital-engineering\/web-development\">web development<\/a>, a component is a part of a web page or application that is modular and reusable, with a specific functionality or purpose. It&#8217;s like a building block that can be used to create complex interfaces.<\/p>\n<p>Components are made up of <strong>HTML, CSS, and JavaScript code<\/strong>, and can be easily customized and reused across multiple pages or applications. Examples of components include navigation menus, forms, sliders, and buttons.<\/p>\n<h3>What is a Single Directory Component?<\/h3>\n<p>Single-Directory Components (often abbreviated as SDC) are <a href=\"https:\/\/www.tothenew.com\/cx\/drupal-development-consulting\">Drupal<\/a> core\u2019s implementation of components. Within SDC, all files necessary to render the component are grouped together in a single directory (hence the name!). This includes Twig, YAML, and optional CSS, JavaScript, etc. SDC will automatically generate a library to load CSS\/JS when the template is invoked.<\/p>\n<h3>Why Single Directory Component introduced in Drupal?<\/h3>\n<p>The SDC feature was introduced in Drupal 9 to address specific challenges and limitations in traditional theming and component-based development. Here are a few reasons:<\/p>\n<p><strong>1. Modern Development Paradigm<\/strong><\/p>\n<ul>\n<li><strong>Trend Towards Component-Based Architecture: <\/strong>Modern frontend frameworks like React, Vue, and Angular organize UI elements as self-contained components. SDC brings this component-based development approach to Drupal, where all related files (Twig, CSS, JavaScript, and configuration) for a specific component are grouped in one directory.<\/li>\n<\/ul>\n<p><strong>2. Improve Code Organization<\/strong><\/p>\n<ul>\n<li><strong>Traditional Approach Issues:<\/strong> Files for a single component are often scattered across multiple directories: Twig templates in \/templates. CSS in \/css or \/scss. JavaScript in \/js. This scattering makes it harder to manage, debug, and reuse components.<\/li>\n<li><strong>SDC Solution:<\/strong> By grouping everything into one directory, developers can focus on one self-contained folder for a specific feature or UI element.<\/li>\n<\/ul>\n<p><strong>3. Simplify Reusability<\/strong><\/p>\n<ul>\n<li><strong>Traditional Challenge:<\/strong> Reusing components across themes or modules often requires duplicating templates, styles, and logic. Extending or overriding components could lead to inconsistencies.<\/li>\n<li><strong>SDC Solution:<\/strong> Components are self-contained and modular, making them easier to reuse or override in different themes or modules<\/li>\n<\/ul>\n<p><strong>4. Support for Design Systems<\/strong><\/p>\n<ul>\n<li><strong>Traditional Challenge:<\/strong> Design systems require a structured approach to components. Scattered files make it harder to enforce consistency or adapt to modern workflows like using Storybook.<\/li>\n<li><strong>SDC Solution:<\/strong> SDC aligns Drupal with design systems by providing a structured and standardized approach to component creation. It facilitates integration with tools like Storybook for component libraries.<\/li>\n<\/ul>\n<p><strong>5. Alignment with Modern Standards<\/strong><\/p>\n<ul>\n<li><strong>Keeping Drupal Competitive:<\/strong> With SDC, Drupal aligns with modern CMSs and frameworks that prioritize developer experience and modularity (e.g., WordPress block editor, React components). It modernizes the development experience, attracting developers familiar with component-based architectures.<\/li>\n<\/ul>\n<p><strong>6. Better Multilingual and Theming Support<\/strong><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li>Components within SDC can leverage Drupal&#8217;s translation and theming systems more effectively.<\/li>\n<li>Translations are managed in Twig templates with t() functions.<\/li>\n<li>Theme-specific components can override SDC without breaking core functionality.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ol>\n<li style=\"list-style-type: none;\"><\/li>\n<\/ol>\n<h3>Benefits of Using SDC<\/h3>\n<p>There are many benefits of using SDC<\/p>\n<ul>\n<li><strong>Organization<\/strong>: Grouping all necessary code into one directory makes finding and jumping between relevant files easier.<\/li>\n<li><strong>Automatic<\/strong> library creation: SDC will automatically look for my-component.css and my-component.js and add to an automatically generated library if found. You can specify additional assets and dependencies within the component\u2019s YML file if necessary.<\/li>\n<li><strong>Reusability<\/strong>: Components are designed to be modular and reusable, which means that they can be easily integrated into multiple pages or applications.<\/li>\n<li><strong>Consistency<\/strong>: By using components, developers can ensure that their web pages or applications have a consistent look and feel throughout.<\/li>\n<li><strong>Scalability<\/strong>: Components can help make web pages or applications more scalable, as they can be easily added or removed as needed.<\/li>\n<li><strong>Testing<\/strong>: Components can often be tested in isolation, which can make it easier to identify and fix bugs or issues.<\/li>\n<li><strong>Collaboration<\/strong>: Using components can make it easier for teams of developers to work together, as they can share and reuse components across different projects.<\/li>\n<\/ul>\n<h3>How to work with SDC?<\/h3>\n<h4>To develop SDC, things we need to know<\/h4>\n<ul>\n<li>If you\u2019re using <strong>Drupal 9<\/strong> you have to install the <strong>contrib module<\/strong> using this command composer requires &#8216;drupal\/sdc:^1.0\u2019.<\/li>\n<li>For <strong>Drupal 10.1<\/strong> and later core versions, the Single Directory Component (SDC) module is included in the core.<\/li>\n<li>Enable the Single Directory Components module.<\/li>\n<li>In <strong>Drupal 10.3<\/strong> Single-Directory Components became part of the render system.<\/li>\n<li>Disable CSS and JS aggregation in the Drupal admin UI for development purposes.<\/li>\n<li>Enable Twig development mode and disable caching.<\/li>\n<\/ul>\n<h4>Create A Component<\/h4>\n<ol>\n<li>Create a new directory called components\/ in your custom theme or module\u2019s directory.<\/li>\n<li>Create a new directory within the components\/ directory with the name of your new component (ex &#8211; carousel).<\/li>\n<li>Create two new files within this directory\n<ol>\n<li>A twig file with the name of your component (ex carousel.twig)<\/li>\n<li>A YAML file with the *.component.yml extension that is named with your component (ex carousel.component.yml).<\/li>\n<\/ol>\n<\/li>\n<li>The CSS and JavaScript must be named after the component (e.g., carousel.css, and carousel.js) to load them automatically.<\/li>\n<li>You can load additional styles, scripts, and dependencies using the libraryOverrides key within your<\/li>\n<\/ol>\n<h4>Final directory structure<\/h4>\n<p>As an example, we are creating a component in a custom module.<\/p>\n<pre>|- web\/modules\/custom\/my-module\r\n    |- components\r\n        |- my-component\r\n            |- my-component.twig (required)\r\n            |- my-component.component.yml (required)\r\n            |- README.md (optional)\r\n            |- thumbnail.png  (optional)\r\n            |- my-component.js\r\n            |- my-component.css\r\n            |- assets (optional)\r\n                |- img1.png\r\n<\/pre>\n<h4>Drush Command with SDC<\/h4>\n<pre>drush generate single_directory_component<\/pre>\n<blockquote><p><b>Note &#8211; Minimum drush version &#8211; Drush 12 or later<\/b><\/p><\/blockquote>\n<h3>Some Common Terminology before diving into *.component.yml file<\/h3>\n<p>Within the Drupal Single Directory Component (SDC) framework, data can be transmitted to a component using two methods: <strong>&#8220;props&#8221; (short for &#8220;properties&#8221;) and &#8220;slots.&#8221;<\/strong> These concepts originate from JavaScript frameworks like Vue and React, embodying the notion of providing or feeding data into a component.<\/p>\n<ul>\n<li><strong>Props<\/strong> adhere to a specified structure for transmitting data to the component, utilizing the JavaScript Object Notation (JSON) format with key-value pairs.<\/li>\n<li><strong>Slots<\/strong> handle unstructured data, encompassing scenarios like nested components, Twig blocks, or HTML markup. Unlike props, slots do not require a JSON schema with key-value pairs and are not confined by JSON data types.<\/li>\n<\/ul>\n<h4>Exploring component.yml File &#8211; Metadata<\/h4>\n<p>The presence of the <strong>*.component.yml<\/strong> file is important; in its absence, Drupal remains uninformed about the existence of your component. This file must be created within the component&#8217;s directory. Let&#8217;s go through the definition of *.component.yml file.<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\">\n<tbody>\n<tr>\n<td style=\"width: 50%;\">KEY<\/td>\n<td style=\"width: 50%;\">DEFINITION<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">name<\/td>\n<td style=\"width: 50%;\">Name of the component.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">description<\/td>\n<td style=\"width: 50%;\">Detailed explanation of the component.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">schema props<\/td>\n<td style=\"width: 50%;\">Are the properties like mail, image, headline, etc?<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">schema slots<\/td>\n<td style=\"width: 50%;\">A container to put data that does not have a template or data structure.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 50%;\">libraryOverrides<\/td>\n<td style=\"width: 50%;\">To add extra JS or css libraries apart from libraries that are inside the component\u2019s directory.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Example of Component YAML file<\/h3>\n<p>Here, we are creating a carousel component in a custom module having props as a title and slider.<\/p>\n<p>On the below path web\/modules\/custom\/my-module\/components\/carousel.component.yml<\/p>\n<pre># This is so your IDE knows about the syntax for fixes and autocomplete.\r\n$schema: 'https:\/\/git.drupalcode.org\/project\/drupal\/-\/raw\/10.1.x\/core\/modules\/sdc\/src\/metadata.schema.json'\r\n\r\n# The human readable name.\r\nname: Carousel\r\n\r\n# Status can be: \"experimental\", \"stable\", \"deprecated\", \"obsolete\".\r\nstatus: stable\r\n\r\nprops:\r\n  type: object\r\n  properties:\r\n    title:\r\n      type: string\r\n      title: Section Title\r\n      description: The title shown above the carousel (e.g. \"popular courses\")\r\n    slides:\r\n      type: array\r\n      title: Carousel Slides\r\n      items:\r\n        type: object\r\n        properties:\r\n          image:\r\n            type: object\r\n            required:\r\n              - url\r\n              - alt\r\n            properties:\r\n              url:\r\n                type: string\r\n                title: Image URL\r\n              alt:\r\n                type: string\r\n                title: Image Alt Text\r\n          title:\r\n            type: string\r\n            title: Slide Title\r\n          description:\r\n            type: string\r\n            title: Slide Description\r\n  required:\r\n    - title\r\n    - slides\r\n\r\n\r\n<\/pre>\n<h3>Render a Component<\/h3>\n<p>To use a component in an *.html.twig template uses Twig\u2019s built-in embed or include functions.<\/p>\n<ul>\n<li>Use <strong>include(): <\/strong>Use the Twig include() function if there are no slots or arbitrary HTML properties and the data all follows a defined structure. Example &#8211;\n<pre>{{ include('my-module:carousel',{ props:{\r\n    title: 'Carousel',\r\n    slides: [\r\n      {\r\n        image: {\r\n          url: 'https:\/\/images.unsplash.com\/photo-1508766206392-8bd5cf550d1c',\r\n          alt: 'Internal medicine course image'\r\n        },\r\n        title: 'internal medicine i',\r\n        description: 'Explore the intricacies of diagnosing and treating adult diseases! From common ailments to complex medical conditions, gain a comprehensive understanding of internal medicine.'\r\n      }\r\n    ]\r\n  }}) }}\r\n<\/pre>\n<\/li>\n<li>Use <strong>{% embed %}: <\/strong>Use a Twig {% embed %} tag if you need to populate slots.<br \/>\nExample of embed function.<br \/>\nHere data will be the dynamic object of the slider and the slider title will be passed as a slot<\/p>\n<pre>{% embed 'my-module:carousel' with { props:{\r\n    slides: data\r\n  }}\r\n%}\r\n  {% block heading %}\r\n    {{ slider_title }}\r\n  {% endblock %}\r\n{% endembed %}<\/pre>\n<\/li>\n<\/ul>\n<h4>Override a Component<\/h4>\n<p>Only themes can override components, and there are two important requirements to do so:<\/p>\n<ol>\n<li>Add a <strong>replaces<\/strong> key at the top in the *.component.yml file you want to override\n<pre>name: Override existing Carousel\r\nreplaces: my-custom.carousel\r\n<\/pre>\n<\/li>\n<li>The component needs to have a defined schema.<\/li>\n<\/ol>\n<p>It is important to note that modules cannot override components, and only components that have a defined schema can replace and be replaced by others.<\/p>\n<h2>Conclusion<\/h2>\n<p>This blog will help you create a <strong>Basic Single Directory Component<\/strong> in your<a href=\"https:\/\/www.tothenew.com\/cx\/drupal-development-consulting\"> Drupal application<\/a>. SDC lets you define schemas in the YML file, enabling contributed modules and Drupal core to automatically generate forms for data entry. This allows us to add components directly using tools like Layout Builder and CKEditor without needing custom entities.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What is a Component? In web development, a component is a part of a web page or application that is modular and reusable, with a specific functionality or purpose. It&#8217;s like a building block that can be used to create complex interfaces. Components are made up of HTML, CSS, and JavaScript code, and can be [&hellip;]<\/p>\n","protected":false},"author":1511,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":396},"categories":[3602],"tags":[4862],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/69189"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1511"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=69189"}],"version-history":[{"count":10,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/69189\/revisions"}],"predecessor-version":[{"id":69226,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/69189\/revisions\/69226"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=69189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=69189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=69189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}