# GovNL NLDS Development Guidelines

This document outlines the coding standards and conventions for developing and contributing to the GovNL NLDS Drupal theme, which uses Single Directory Components (SDC).

## Core Principles

This theme follows [Drupal's coding standards](https://www.drupal.org/docs/develop/standards) and extends them with additional conventions for component-based development.

## Twig Template Conventions

### 1. Component Inclusion Rules

**Always use `embed` with `only`:**

```twig
{% embed '@govnl_nlds/button/button.twig' with { 'text': 'Click me', 'variant': 'primary' } only %}
  ...
{% endembed %}
```

**Why this is mandatory:**

- The `only` keyword prevents unexpected side-effects by ensuring only explicitly passed variables are available in the component
- Improves component isolation and predictability by preventing access to parent template variables
- Makes component dependencies explicit and easier to debug
- Follows Drupal SDC best practices for maintainable component architecture

**Always use `include` with `with_context=false`:**

```twig
{{ include('@govnl_nlds/icon/icon.twig', {
  'name': 'arrow-right',
  'size': 'small'
}, with_context: false }}
```

**Why this is mandatory:**

- `with_context=false` ensures only explicitly passed variables are available, preventing unexpected side-effects
- Maintains component isolation by blocking access to parent template context
- Ensures components work consistently regardless of where they're included

**When to use `include` vs `embed`:**

| Component Output Method                   | Use This Twig Function              |
| ----------------------------------------- | ----------------------------------- |
| Variables only (e.g., `{{ label }}`)      | `include()` function                |
| Twig blocks (e.g., `{% block content %}`) | `{% embed %}` tag                   |
| Mixed variables and blocks                | Either `include()` or `{% embed %}` |

**Never use the `{% include %}` tag:**
The Twig documentation recommends using the `include()` function instead of the `{% include %}` tag because:

- The function is more semantically correct
- It provides better composability
- It supports named arguments for better readability

### 2. Content Filtering

### Content Filtering Guidelines

**Never use the `|raw` filter:**

```twig
{# ❌ Wrong #}
{{ content|raw }}

{# ✅ Correct #}
{{ content }}
```

_Why?_
Using `|raw` disables Drupal's automatic escaping, which can introduce security vulnerabilities such as XSS. Always rely on Drupal's default escaping for safe output.

**Always use `|children` for conditional checks on render arrays:**

```twig
{# ❌ Wrong #}
{% if content %}

{# ✅ Correct #}
{% if content|children %}
  {{ content }}
{% endif %}
```

_Why?_
Render arrays may be empty but still evaluate as truthy. The `|children` filter ensures you only render content when there are actual child elements, preventing empty markup and improving template reliability.

## Resources

- [Drupal SDC Documentation](https://www.drupal.org/docs/develop/theming-drupal/using-single-directory-components)
- [Canvas SDC Components](https://project.pages.drupalcode.org/canvas/sdc-components/)
- [Drupal Coding Standards](https://www.drupal.org/docs/develop/standards)
