Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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.');
}
Comment thread
dipakmdhrm marked this conversation as resolved.

$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