Fix palette swatches, login styling, and login redirect

- PaletteController: render proper color swatch cards (box + label) and
  wrap output in Markup::create() so Drupal's XSS filter doesn't strip
  inline style attributes
- riverside_pt.module: scope page_attachments and page_top to
  riverside_pt.* routes only — Tailwind preflight was blowing away
  Drupal's default form styles on the login page
- settings.php: derive trusted_host_patterns from BASE_URL so the host
  and port always agree; prevents localhost:8080 being treated as untrusted
- entrypoint.sh: pass --base-url to drush site:install so Drupal stores
  the correct canonical URL from the start

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Philip Peterson 2026-06-01 03:00:19 -07:00
parent 1cb8335158
commit 0d35dda628
5 changed files with 30 additions and 19 deletions

View file

@ -35,6 +35,7 @@ else
--site-name="$SITE_NAME" \ --site-name="$SITE_NAME" \
--account-name=admin \ --account-name=admin \
--account-pass="$ADMIN_PASS" \ --account-pass="$ADMIN_PASS" \
--base-url="${BASE_URL:-http://localhost:8080}" \
-y || { echo "[entrypoint] FATAL: site:install failed."; exit 1; } -y || { echo "[entrypoint] FATAL: site:install failed."; exit 1; }
echo "[entrypoint] Drupal installed." echo "[entrypoint] Drupal installed."
fi fi

File diff suppressed because one or more lines are too long

View file

@ -5,6 +5,10 @@ use Drupal\Core\Link;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
function riverside_pt_page_attachments(array &$attachments): void { function riverside_pt_page_attachments(array &$attachments): void {
$route = \Drupal::routeMatch()->getRouteName() ?? '';
if (!str_starts_with($route, 'riverside_pt.')) {
return;
}
$attachments['#attached']['library'][] = 'riverside_pt/app'; $attachments['#attached']['library'][] = 'riverside_pt/app';
} }
@ -25,9 +29,13 @@ function riverside_pt_theme(): array {
} }
function riverside_pt_page_top(array &$page_top): void { function riverside_pt_page_top(array &$page_top): void {
$route = \Drupal::routeMatch()->getRouteName() ?? '';
if (!str_starts_with($route, 'riverside_pt.')) {
return;
}
$page_top['rpt_header'] = [ $page_top['rpt_header'] = [
'#theme' => 'riverside_pt_header', '#theme' => 'riverside_pt_header',
'#cache' => ['contexts' => ['url.path']], '#cache' => ['contexts' => ['url.path', 'route']],
]; ];
} }

View file

@ -10,32 +10,34 @@ class PaletteController extends ControllerBase {
$colors = $this->parseColors(); $colors = $this->parseColors();
if (!$colors) { if (!$colors) {
return ['#markup' => '<p>Could not parse tailwind.config.js</p>']; return ['#markup' => \Drupal\Core\Render\Markup::create('<p>Could not parse tailwind.config.js</p>')];
} }
$html = '<div style="font-family:monospace;font-size:13px;padding:32px;background:#f5f5f5;max-width:480px">'; $html = '<div style="font-family:monospace;font-size:13px;padding:32px;background:#f5f5f5">';
foreach ($colors as $group => $shades) { foreach ($colors as $group => $shades) {
$html .= '<div style="font-size:11px;text-transform:uppercase;letter-spacing:.1em;color:#666;margin:20px 0 8px">' $html .= '<div style="font-size:11px;text-transform:uppercase;letter-spacing:.1em;color:#666;margin:28px 0 12px">'
. htmlspecialchars($group) . '</div>'; . htmlspecialchars($group) . '</div>';
$html .= '<div style="display:flex;flex-wrap:wrap;gap:12px">';
foreach ($shades as $shade => $hex) { foreach ($shades as $shade => $hex) {
$label = $shade === 'DEFAULT' ? $group : "$group-$shade"; $label = $shade === 'DEFAULT' ? $group : "$group-$shade";
$lum = $this->luminance($hex); $border = $this->luminance($hex) > 200 ? 'border:1px solid #ddd;' : '';
$textColor = $lum > 140 ? '#333' : '#fff';
$border = $lum > 200 ? 'border:1px solid #ccc;' : '';
$html .= '<div style="display:flex;align-items:center;gap:12px;margin-bottom:6px">' $html .= '<div style="width:100px">'
. "<div style=\"width:80px;height:40px;background:{$hex};{$border}\"></div>" . "<div style=\"width:100px;height:64px;background:{$hex};border-radius:6px 6px 0 0;{$border}\"></div>"
. "<span style=\"background:{$hex};color:{$textColor};padding:2px 8px\">" . '<div style="background:#fff;border:1px solid #ddd;border-top:none;border-radius:0 0 6px 6px;padding:6px 8px">'
. htmlspecialchars("$label$hex") . '<div style="font-weight:600;color:#333">' . htmlspecialchars($label) . '</div>'
. '</span></div>'; . '<div style="color:#888;font-size:11px">' . htmlspecialchars($hex) . '</div>'
. '</div>'
. '</div>';
} }
$html .= '</div>';
} }
$html .= '</div>'; $html .= '</div>';
return ['#markup' => $html]; return ['#markup' => \Drupal\Core\Render\Markup::create($html)];
} }
private function parseColors(): array { private function parseColors(): array {

View file

@ -37,10 +37,10 @@ if (getenv('DEBUG')) {
if ($base = getenv('BASE_URL')) { if ($base = getenv('BASE_URL')) {
$base_url = $base; $base_url = $base;
} $parsed = parse_url($base);
$host = $parsed['host'] ?? 'localhost';
if ($trusted = getenv('TRUSTED_HOST')) { $port = isset($parsed['port']) ? ':' . $parsed['port'] : '';
$settings['trusted_host_patterns'] = ['^' . preg_quote($trusted, '/') . '$']; $settings['trusted_host_patterns'] = ['^' . preg_quote($host . $port, '/') . '$'];
} else { } else {
$settings['trusted_host_patterns'] = ['^localhost$', '^127\.0\.0\.1$', '^0\.0\.0\.0$']; $settings['trusted_host_patterns'] = ['^localhost$', '^localhost:8080$', '^127\.0\.0\.1$'];
} }