Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ddev/commands/web/theme-compile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
## Aliases: theme-compile
## Example: "ddev theme:compile"

./vendor/bin/robo theme:compile
cd ./web/themes/custom/server_theme && npm install && npm run build
15 changes: 14 additions & 1 deletion .ddev/commands/web/theme-watch
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,17 @@
## Aliases: theme-watch
## Example: "ddev theme:watch"

cd ./web/themes/custom/server_theme && npx tailwindcss -i ./src/css/style.css -o ./dist/css/style.css --watch
cd ./web/themes/custom/server_theme || exit 1

# Ensure dependencies are installed
if [ ! -d node_modules ]; then
npm install || exit 1
fi

# Ensure an initial build exists
if [ ! -d dist/css ] || [ ! -d dist/fonts ] || [ ! -d dist/images ] || [ ! -d dist/js ]; then
npm run build || exit 1
fi

# Start the watcher
npm run watch
9 changes: 4 additions & 5 deletions .ddev/config.local.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ hooks:
# Import translations.
- exec: robo locale:import

# Compile theme in debug, so we can develop with all Tailwinds' classes.
# On deploy, we purge un-needed CSS.
- exec-host: ddev robo theme:compile-debug
# Compile the theme (CSS, JS, fonts, and images).
- exec-host: ddev theme:compile

# Install the default content.
- exec: drush pm-enable default_content --no-interaction
Expand Down Expand Up @@ -59,7 +58,7 @@ hooks:
- exec: drush sapi-c
- exec: drush sapi-i
# Compile theme.
- exec-host: ddev robo theme:compile
- exec-host: ddev theme:compile
# Get rid of sensitive user data.
- exec: drush sql:sanitize --yes
# Login as admin.
Expand All @@ -75,7 +74,7 @@ hooks:
- exec: drush sapi-c
- exec: drush sapi-i
# Compile theme.
- exec-host: ddev robo theme:compile
- exec-host: ddev theme:compile
# Get rid of sensitive user data.
- exec: drush sql:sanitize --yes
# Login as admin.
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,20 @@ Please refer to the [Default content documentation](https://www.drupal.org/docs/

## Theme Development

By default, `ddev restart` compiles the theme using Robo (`ddev robo theme:compile-debug`)
By default, `ddev restart` compiles the theme using npm scripts (`ddev theme:compile`).

This is used only for watching Tailwind styles, it's not compiling js, images, etc.
This compiles CSS (Tailwind), JS, fonts, and images into the `dist/` directory.

On the local development environment, which is using TailWind's [JIT](https://tailwindcss.com/docs/just-in-time-mode) (Just-In-Time), execute:
On the local development environment, execute:

```bash
ddev theme:watch
```

This will compile Tailwind and keep watching for any changes.
This will run an initial build and then watch for any changes to CSS, JS, fonts, and images.

When running `ddev robo theme:compile` it will purge any TailWind's CSS class
which is not found in the code, twig, or under `tailwind.config.js` `whitelist` property.
When running `ddev theme:compile`, Tailwind uses JIT (Just-In-Time) mode and only includes CSS classes
found in the source paths declared via `@source` directives in `src/css/style.css`.

The directory structure:
- `src/` - put all source stylesheets images, fonts, etc here.
Expand All @@ -111,7 +111,7 @@ For theme development, it's advisable to entirely turn off caching: https://www.
It is advised to use Drupal's Responsive image module.

If there are new breakpoints added, or existing breakpoints updated in
`server_theme/tailwind.config.js`, you must ensure to also update the Drupal
`src/css/style.css` (via `@theme` custom properties), you must ensure to also update the Drupal
breakpoints configuration file for the theme `server_theme.breakpoints.yml` so
that the media queries for the responsive images are in sync with tailwind's.
It is advisable to finalize this configuration before any responsive image
Expand Down Expand Up @@ -372,17 +372,17 @@ In order to deploy upon every merge automatically using GitHub Actions, you shal
1. `git commit -m "Deployment secrets and configuration"`
1. Add the public key in `pantheon-key.pub` to the newly created dummy [Pantheon user](https://pantheon.io/docs/ssh-keys)
1. Set up the following in your GitHub repository settings:

**GitHub Secrets** (Settings → Secrets and variables → Actions → Secrets):
- `TERMINUS_TOKEN`: Your Pantheon machine token
- `PANTHEON_DEPLOY_KEY`: The SSH private key for deployment
- `GH_TOKEN`: GitHub personal access token for posting deployment comments

**GitHub Variables** (Settings → Secrets and variables → Actions → Variables):
- `PANTHEON_GIT_URL`: The Pantheon Git URL for your project
- `ROLLBAR_SERVER_TOKEN`: Your Rollbar server token (optional)
- `DEPLOY_EXCLUDE_WARNING`: Warnings to exclude from deployment notifications (optional)

1. Actualize `public static string $githubProject = 'Gizra/the-client';` in the `RoboFile.php`.

Optionally you can specify which target branch you'd like to push on Pantheon, by default it's `master`, so the target is the DEV environment, but alternatively you can issue:
Expand Down
170 changes: 7 additions & 163 deletions robo-components/ThemeTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

namespace RoboComponents;

use Lurker\Event\FilesystemEvent;
use Robo\ResultData;
use Symfony\Component\Finder\Finder;

/**
* Compilation of theme source assets.
Expand All @@ -27,12 +25,12 @@ trait ThemeTrait {

/**
* Compile the theme.
*
* @param bool $optimize
* Indicate whether to optimize during compilation.
*/
private function doThemeCompile(bool $optimize = FALSE): void {
public function themeCompile(): void {
$theme_dir = self::$themeBase;
$directories = [
'css',
'fonts',
'js',
'images',
];
Expand All @@ -44,173 +42,19 @@ private function doThemeCompile(bool $optimize = FALSE): void {
$this->_mkdir($directory);
}

$theme_dir = self::$themeBase;

// Make sure we have all the node packages.
$this->_exec("cd $theme_dir && npm install");

// Use Tailwind CLI to compile CSS and always minify for consistent output.
$tailwind_command = "cd $theme_dir && npx tailwindcss -i ./src/css/style.css -o ./dist/css/style.css --minify";
$result = $this->_exec($tailwind_command);

// Safety check to verify theme was properly compiled before deployment.
if (!file_exists(sprintf('%s/dist/css/style.css', self::$themeBase))) {
throw new \Exception('Theme compilation failed.');
}
// Compile all assets (CSS, JS, fonts, images) in parallel via npm scripts.
$result = $this->_exec("cd $theme_dir && npm run build");

if ($result->getExitCode() !== 0) {
$this->taskCleanDir(['dist/css']);
return;
}

// Javascript.
if ($optimize) {
// Minify the JS files.
foreach (glob(self::$themeBase . '/src/js/*.js') as $js_file) {
// Make the path relative to the theme root.
$from = str_replace('web/themes/custom/server_theme/', '', $js_file);
$to = str_replace('src/', 'dist/', $from);
// Minify the js.
$this->_exec("cd $theme_dir && npx minify $from > $to");
}
}
else {
$this->_copyDir(self::$themeBase . '/src/js', self::$themeBase . '/dist/js');
}

// Fonts.
$this->_copyDir(self::$themeBase . '/src/fonts', self::$themeBase . '/dist/fonts');

// Images - Copy everything first.
$this->_copyDir(self::$themeBase . '/src/images', self::$themeBase . '/dist/images');

// Then for the formats that we can optimize, perform it.
if ($optimize) {
$input = [
self::$themeBase . '/src/images/*.jpg',
self::$themeBase . '/src/images/*.png',
];

$this->taskImageMinify($input)
->to(self::$themeBase . '/dist/images/')
->run();

// Compress all SVGs.
$this->themeSvgCompress();
throw new \Exception('Theme compilation failed.');
}

$this->_exec('drush cache:rebuild');
}

/**
* Compile the theme (optimized).
*/
public function themeCompile(): void {
$this->say('Compiling (optimized).');
$this->doThemeCompile(TRUE);
}

/**
* Compile the theme.
*
* Non-optimized.
*/
public function themeCompileDebug(): void {
$this->say('Compiling (non-optimized).');
$this->doThemeCompile();
}

/**
* Compress SVG files in the "dist" directories.
*
* This function is being called as part of `theme:compile`.
*
* @return \Robo\ResultData|null
* If there was an error a result data object is returned. Or void if
* successful.
*
* @see doThemeCompile()
*/
public function themeSvgCompress(): ?ResultData {
$directories = [
'./dist/images',
];

$error_code = NULL;

foreach ($directories as $directory) {
// Check if SVG files exists in this directory.
$finder = new Finder();
$finder
->in(self::$themeBase . '/' . $directory)
->files()
->name('*.svg');

if (!$finder->hasResults()) {
// No SVG files.
continue;
}

$result = $this->_exec("cd " . self::$themeBase . " && npx svgo $directory/*.svg");
if (empty($error_code) && !$result->wasSuccessful()) {
$error_code = $result->getExitCode();
}
}

if (!empty($error_code)) {
return new ResultData($error_code, '`svgo` failed to run.');
}
return NULL;
}

/**
* Directories that should be watched for the theme.
*
* @return array
* List of directories.
*/
protected function monitoredThemeDirectories(): array {
return [
self::$themeBase . '/src',
];
}

/**
* Watch the theme and compile on change (optimized).
*/
public function themeWatch(): void {
$this->say('Compiling and watching (optimized).');
$this->doThemeCompile(TRUE);
foreach ($this->monitoredThemeDirectories() as $directory) {
$this->taskWatch()
->monitor(
$directory,
function () {
$this->doThemeCompile(TRUE);
},
FilesystemEvent::ALL
)->run();
}
}

/**
* Watch the theme path and compile on change (non-optimized).
*/
public function themeWatchDebug(): void {
$this->say('Compiling and watching (non-optimized).');
$this->doThemeCompile();
foreach ($this->monitoredThemeDirectories() as $directory) {
$this->taskWatch()
->monitor(
$directory,
function () {
$this->doThemeCompile();
},
FilesystemEvent::ALL
)->run();
}
}

/**
* Update the caniuse-lite browserslist db.
*
Expand Down
Loading
Loading