https://bit.ly/sdc-workflow
(a sappy aside about the community)
But for some projects they are overkill.
Will I miss my fancy frameworks?
also...The one true way
Astro is current tool of choice
<retro-card>
is valid htmlSlots - unstructured data - markup, other components
Props - key value pairs (think attributes)
<retro-card>
<div class="card">
<div class="card-image">
<slot name="image" />
</div>
<div class="card-content">
<div class="card-meta">
<span class="date">{date}</span>
<div class="tags">
<span class="tag">{tag}</span>
</div>
</div>
<h2 class="card-title">{title}</h2>
<div class="card-text">
<slot name="body" />
</div>
<a href={url} class="read-more">Jack In →</a>
</div>
</div>
</retro-card>
---
import Card from '../components/Card.astro';
import Layout from '../layouts/Layout.astro';
---
<Layout>
<Card
date="March 14, 2024"
tag="Retro"
title="Synthwave Dreams"
url="/synthwave-dreams"
>
<img slot="image" src="https://picsum.photos/400/250" alt="Card image" />
<p slot="body">Welcome to the future that never was. A nostalgic journey through neon-lit streets and digital horizons. Where synthwave meets design in a perfect harmony.</p>
</Card>
</Layout>
---
interface Props {
date: string;
tag: string;
title: string;
url: string;
}
const { title, date, tag, url } = Astro.props;
---
<script>
// Add glitch effect to image on click
const cardImage = document.querySelector('.card-image');
cardImage?.addEventListener('click', () => {
cardImage.classList.add('glitch');
setTimeout(() => {
cardImage.classList.remove('glitch');
}, 300);
});
// Add flicker effect to tags on click
const tags = document.querySelectorAll('.tag');
tags.forEach(tag => {
tag.addEventListener('click', () => {
tag.classList.add('flicker');
setTimeout(() => {
tag.classList.remove('flicker');
}, 300);
});
});
</script>
<retro-card>
Spoiler: this should feel pretty similar
components/card
subdirectory in a module or theme
card.component.yml
filebare minimum version:
name: Card
props:
type: object
properties: {}
card.twig:
<retro-card>Card component</retro-card>
Note that the extension is .twig
not .html.twig
card.css
retro-card {
color: green;
}
We'll add more css/markup along the way...
In our drupal_cms_olivero_sdc
theme
node--card.html.twig
:
{% embed 'drupal_cms_olivero_sdc:card' %}{% endembed %}
Slots in our prototype looked like:
<div class="card-text">
<slot name="body" />
</div>
For Drupal, we first define the slot in yml
slots:
body:
title: Body
description: Body markup
Next, we define it as a block in our twig template
<div class="card-text">
{% block body %}{% endblock %}
</div>
And populate the block in our Twig embed
{% embed 'drupal_cms_olivero_sdc:card' %}
{% block body %}
{{ content|without('field_featured_image', 'links') }}
{% endblock %}
{% endembed %}
Slots in our prototype looked like:
<Card
date="March 14, 2024"
tag="Retro"
title="Synthwave Dreams"
url="/synthwave-dreams"
>
For Drupal, we first update our yml to add a date prop:
name: Card
props:
type: object
properties:
date:
type: string
title: date
description: "The date content was created"
Next we use the date
prop in our twig template:
{% if display_submitted %}
<span class="date">{{date}}</span>
{% endif %}
And pass the prop in our Twig embed
{% embed 'drupal_cms_olivero_sdc:card' with { date: date} %}
Similar to TypeScript, you can enforce your schema
---
interface Props {
date: string;
tag: string;
title: string;
url: string;
}
const { title, date, tag, url } = Astro.props;
---
For theme components:
enforce_prop_schemas: true
No modifications required in this case.
drush generate sdc
Easy as...
{% embed 'drupal_cms_olivero_sdc:card' %}
vs
{% embed 'drupal_cms_olivero_sdc:business_card' %}
nomarkup
module
twig_tweak
module