Applied the dark redesign across the homepage, services, contact and blog.#179
Applied the dark redesign across the homepage, services, contact and blog.#179AlexSkrypnyk wants to merge 68 commits into
Conversation
… and paragraph theme-flip hook.
…he site-wide signup CTA.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds redesign tokens, component styles, two frontend Drupal behaviors (reveal, stats), many static content templates, deploy hooks to seed dark-themed paragraphs from HTML, theme/footer/banner wiring, and small Drupal configuration edits. ChangesWebsite Redesign Implementation
🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Actionable comments posted: 11
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@web/modules/custom/do_base/content/blog/demo-article.html`:
- Line 158: The anchor with visible text "parallel execution" is a placeholder
(href="#") and must be updated to a real destination or removed; locate the <a>
element around the text "parallel execution" in the paragraph and either replace
href="#" with the correct URL to the relevant docs/article (e.g., PHPUnit
parallel execution/paratest docs) or remove the <a> tag so the text is plain
content, ensuring the final markup contains no non-functional links.
In `@web/modules/custom/do_base/do_base.deploy.php`:
- Around line 183-193: The current _do_base_set_components(Node $node, string
$dir) deletes all existing field_c_n_components entities before calling
_do_base_html_paragraphs($dir); change the flow so you first call
_do_base_html_paragraphs($dir) and validate its return (non-empty, no errors)
and only then delete the referenced entities and set the field; if the function
returns empty/false, do not delete existing components and instead return/LOG a
warning or leave the node unchanged. Ensure you reference the Node object, the
field name field_c_n_components, and the helper _do_base_html_paragraphs when
implementing this check.
- Around line 48-49: Replace the fragile hard-coded Node::load(1) in
do_base_deploy_homepage() with a UUID-based lookup: retrieve the node storage
via the entity type manager and load the node by its UUID (like the Services
deploy hook does), then handle the case where the lookup returns no result
before using the node; update do_base_deploy_homepage() to use that UUID lookup
instead of Node::load(1).
- Around line 123-138: The code deletes existing paragraph components then
creates a webform and appends HTML paragraphs from
_do_base_html_paragraphs('contact') which can return an empty array; instead,
first compute and validate the new components array (call
_do_base_html_paragraphs('contact') and build $components including the new
Paragraph::create result), ensure the resulting $components contains the
required contact details (i.e. more than just the webform or at least meets
whatever non-empty/required-structure check you use), and only if validation
passes, delete existing referenced entities and set field_c_n_components on
$node and save; update references to the existing logic around
Paragraph::create, $components, _do_base_html_paragraphs, and
$node->set('field_c_n_components') accordingly.
- Around line 204-216: The function _do_base_html_paragraphs should validate
that the content directory exists and is readable before calling glob and should
log/readably handle file read failures to avoid silent data loss; update
_do_base_html_paragraphs to check is_dir($path) and is_readable($path) and if
either check fails call \Drupal::logger('do_base')->error(...) and return an
empty array (or throw a clear exception), ensure glob() is only called after
those checks, and when file_get_contents($file) returns FALSE log the filename
and error via \Drupal::logger('do_base')->warning(...) and skip that file
instead of silently continuing; reference _do_base_set_components in tests or
calling code to ensure callers handle the empty/exceptional result
appropriately.
- Around line 218-225: The paragraph creation in _do_base_html_paragraphs()
currently saves raw file_get_contents() HTML into Paragraph::create(...) with
text format 'full_html', which lacks the filter_html sanitizer; update the
deploy code to either (A) use a restricted text format that includes the
filter_html filter when setting field_c_p_content (replace 'full_html' with the
sanitizing format machine name), or (B) add a deploy-time validation step in
_do_base_html_paragraphs() that parses each do_base/content/**/*.html and
rejects or strips forbidden tags/attributes (e.g., <script>, on* attributes)
before saving; also add a short comment/docs note near
_do_base_html_paragraphs() documenting the trust boundary for these partials so
maintainers know only trusted HTML is allowed.
In `@web/themes/custom/drevops/assets/js/stats-counter.js`:
- Around line 39-41: The early return when IntersectionObserver is unavailable
causes counters to stay at their initial values; before returning from the block
that checks if (!elements.length || !('IntersectionObserver' in window)) in
stats-counter.js, iterate over the collected elements and set each element's
displayed value to its data-target (parse numeric values as needed) so the final
stats are shown when the observer isn't supported; use the same attribute name
(data-target) and the same element collection variable (elements) used elsewhere
in the file to locate and update the nodes.
In `@web/themes/custom/drevops/assets/sass/redesign/_components.scss`:
- Line 159: Several padding declarations use horizontal tokens for vertical
spacing (e.g., the padding line with calc(var(--space-y-10) * 1.25)
var(--space-y-3) var(--space-x-10)); update each affected padding shorthand so
the top and bottom values use the Y-axis tokens instead of X-axis tokens.
Specifically, locate the padding properties at the reported spots (including the
shown line and the other occurrences) and replace any top/bottom uses of
--space-x-* with the equivalent --space-y-* token (or appropriate calc using
--space-y-*) so vertical rhythm uses the Y scale.
- Around line 1671-1712: The reveal transitions and keyframe animations
(.component-reveal, .component-reveal.visible, .component-reveal-d1..d6 and
`@keyframes` heroGlow, scrollPulse, fadeUp, fadeIn) run unconditionally; add a
prefers-reduced-motion: reduce media-query override that disables or minimizes
motion by setting transitions and animations to none (or near-zero duration),
removing transform changes and using direct opacity where needed, and ensure the
delay classes (.component-reveal-d1..d6) are also neutralized inside that media
query so motion-sensitive users won't see the animated transforms or delays.
In `@web/themes/custom/drevops/assets/sass/redesign/_tokens.scss`:
- Line 19: Replace loud block comments using /* ... */ with SCSS single-line
comments starting with // throughout the file to satisfy stylelint
scss/comment-no-loud. Specifically update the comment instances like the
"primary" block comment at _tokens.scss (and the other occurrences listed: lines
corresponding to 32, 45, 58, 71, 84, 97, 110, 129, 134, 146, 155, 162, 184, 195,
206, 213, 219, 223, 229, 241, 247, 251, 258, 263, 280, 287, 291, 296) by
converting each /* comment */ into a single-line // comment while preserving the
exact comment text and spacing.
In `@web/themes/custom/drevops/components/03-organisms/footer/footer.scss`:
- Line 41: Replace the legacy max-width media query notation with the
range-context form: locate the media query line containing "`@media` (max-width:
767px)" in footer.scss and change it to the range-context syntax "`@media` (width
<= 767px)"; ensure any matching closing brace remains unchanged so the styles
inside the `@media` block are preserved.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 51f32308-233d-444c-bcbb-755c426a624b
📒 Files selected for processing (34)
config/default/block.block.drevops_signup.ymlconfig/default/core.extension.ymlconfig/default/filter.format.full_html.ymlweb/modules/custom/do_base/content/blog/demo-article.htmlweb/modules/custom/do_base/content/contact/info.htmlweb/modules/custom/do_base/content/homepage/01-services.htmlweb/modules/custom/do_base/content/homepage/02-stats.htmlweb/modules/custom/do_base/content/homepage/03-trust.htmlweb/modules/custom/do_base/content/homepage/04-why.htmlweb/modules/custom/do_base/content/homepage/05-process.htmlweb/modules/custom/do_base/content/homepage/06-contact.htmlweb/modules/custom/do_base/content/services/01-detail.htmlweb/modules/custom/do_base/content/services/02-approach.htmlweb/modules/custom/do_base/content/services/03-cta.htmlweb/modules/custom/do_base/do_base.deploy.phpweb/modules/custom/do_base/do_base.info.ymlweb/themes/custom/drevops/assets/js/reveal.jsweb/themes/custom/drevops/assets/js/stats-counter.jsweb/themes/custom/drevops/assets/sass/redesign/_buttons.scssweb/themes/custom/drevops/assets/sass/redesign/_components.scssweb/themes/custom/drevops/assets/sass/redesign/_extra.scssweb/themes/custom/drevops/assets/sass/redesign/_tokens.scssweb/themes/custom/drevops/assets/sass/theme.scssweb/themes/custom/drevops/components/03-organisms/banner/banner.scssweb/themes/custom/drevops/components/03-organisms/footer/footer.component.ymlweb/themes/custom/drevops/components/03-organisms/footer/footer.scssweb/themes/custom/drevops/components/03-organisms/footer/footer.twigweb/themes/custom/drevops/components/04-templates/page/page.twigweb/themes/custom/drevops/components/variables.base.scssweb/themes/custom/drevops/components/variables.components.scssweb/themes/custom/drevops/drevops.info.ymlweb/themes/custom/drevops/drevops.libraries.ymlweb/themes/custom/drevops/includes/banner.incweb/themes/custom/drevops/includes/page.inc
| // step 11 = near-black. The brand base colour sits near step 9. | ||
| // ══════════════════════════════════════════════════════════════ | ||
| :root { | ||
| /* primary */ |
There was a problem hiding this comment.
Replace loud block comments with SCSS single-line comments to satisfy linting.
Stylelint is flagging these /* ... */ comments (scss/comment-no-loud). Convert them to // comments to unblock lint checks (for example, Line 19 and the same pattern throughout this file).
Proposed change pattern
- /* primary */
+ // primaryAlso applies to: 32-32, 45-45, 58-58, 71-71, 84-84, 97-97, 110-110, 129-129, 134-134, 146-146, 155-155, 162-162, 184-184, 195-195, 206-206, 213-213, 219-219, 223-223, 229-229, 241-241, 247-247, 251-251, 258-258, 263-263, 280-280, 287-287, 291-291, 296-296
🧰 Tools
🪛 Stylelint (17.12.0)
[error] 19-19: Expected // for comments instead of /* (scss/comment-no-loud)
(scss/comment-no-loud)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@web/themes/custom/drevops/assets/sass/redesign/_tokens.scss` at line 19,
Replace loud block comments using /* ... */ with SCSS single-line comments
starting with // throughout the file to satisfy stylelint scss/comment-no-loud.
Specifically update the comment instances like the "primary" block comment at
_tokens.scss (and the other occurrences listed: lines corresponding to 32, 45,
58, 71, 84, 97, 110, 129, 134, 146, 155, 162, 184, 195, 206, 213, 219, 223, 229,
241, 247, 251, 258, 263, 280, 287, 291, 296) by converting each /* comment */
into a single-line // comment while preserving the exact comment text and
spacing.
Source: Linters/SAST tools
There was a problem hiding this comment.
These comments are ported verbatim from the design source. The partials under assets/sass/redesign are intentionally outside the theme stylelint scope, so the comment style is preserved for traceability back to the design.
There was a problem hiding this comment.
@AlexSkrypnyk, understood — makes sense to keep the verbatim comment style for design-source traceability. I'll note that for future reviews.
✏️ Learnings added
Learnt from: AlexSkrypnyk
Repo: drevops/website PR: 179
File: web/themes/custom/drevops/assets/sass/redesign/_tokens.scss:19-19
Timestamp: 2026-06-09T06:26:57.430Z
Learning: In the `drevops` theme (Drupal 11 / CivicTheme), the SCSS partials under `web/themes/custom/drevops/assets/sass/redesign/` are intentionally outside the theme's Stylelint scope. Block-style `/* */` comments in those files are preserved verbatim from the design source for traceability back to the original design variables, so `scss/comment-no-loud` violations there should not be flagged.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/behat/features/contact.feature`:
- Line 13: The step `And I should see "Contact"` is too broad and may match
unrelated text; scope it to the contact webform container instead. Change the
Behat step in the feature to assert the title within the contact webform element
(e.g. use a step like `And I should see "Contact" within
"[data-webform-id='contact']"` or within the webform CSS class such as
`.webform-submission-form`), referencing the contact webform defined in
config/default/webform.webform.contact.yml and the deployment that adds the
civictheme_webform via do_base_deploy_contact() so the check is limited to the
actual webform container.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: cc6df3a2-ca14-4f77-8d4f-14bc8d7c8ec1
📒 Files selected for processing (1)
tests/behat/features/contact.feature
| When I go to "/contact" | ||
| Then I should see the heading Contact | ||
| Then I should see the heading "Let's talk about your platform." | ||
| And I should see "Contact" |
There was a problem hiding this comment.
The assertion verifies the contact webform title Contact renders on the page, which passes. The only Contact heading on the page is the webform title, so the page-level check is unambiguous and kept for simplicity.
…ont page from config, added reduced-motion and stats fallbacks.
| When I go to "/contact" | ||
| Then I should see the heading Contact | ||
| Then I should see the heading "Let's talk about your platform." | ||
| And I should see "Contact" |
There was a problem hiding this comment.
The assertion verifies the contact webform title Contact renders on the page, which passes. The only Contact heading on the page is the webform title, so the page-level check is unambiguous and kept for simplicity.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/modules/custom/do_base/do_base.deploy.php (1)
129-140:⚠️ Potential issue | 🟠 MajorPrevent contact page component data loss if replacement webform paragraph save fails.
do_base_deploy_contact()deletes existingfield_c_n_componentsentities before creating/saving the replacement$webform; if$webform->save()fails/throws, the existing components are already gone and$node->save()won’t run. Build/save the replacement first, then delete old components and set the field.Suggested fix
- foreach ($node->get('field_c_n_components')->referencedEntities() as $existing) { - $existing->delete(); - } - $webform = Paragraph::create([ 'type' => 'civictheme_webform', 'field_c_p_theme' => 'dark', 'field_c_p_webform' => 'contact', ]); $webform->save(); $components = [$webform, ...$details]; + + foreach ($node->get('field_c_n_components')->referencedEntities() as $existing) { + $existing->delete(); + } + $node->set('field_c_n_components', $components);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/modules/custom/do_base/do_base.deploy.php` around lines 129 - 140, In do_base_deploy_contact(), avoid deleting existing field_c_n_components before creating the replacement: first construct and save the new Paragraph ($webform) and verify save succeeded, then delete each existing referenced entity ($existing) from $node->get('field_c_n_components')->referencedEntities(), build the $components array (with the new $webform and $details) and assign it to the node field, and finally call $node->save(); this ensures existing components are preserved if $webform->save() fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@web/modules/custom/do_base/do_base.deploy.php`:
- Around line 198-203: In _do_base_set_components() avoid deleting referenced
paragraph entities before the node's new component references are persisted;
instead set the new references via $node->set('field_c_n_components',
$components) and call $node->save() to persist the node first, then iterate over
the old referenced entities and call $existing->delete(); alternatively
implement a transactional/rollback strategy around creating paragraphs, setting
the field, saving the node, and deleting old paragraphs so the operation is
atomic and cannot leave dangling references.
---
Outside diff comments:
In `@web/modules/custom/do_base/do_base.deploy.php`:
- Around line 129-140: In do_base_deploy_contact(), avoid deleting existing
field_c_n_components before creating the replacement: first construct and save
the new Paragraph ($webform) and verify save succeeded, then delete each
existing referenced entity ($existing) from
$node->get('field_c_n_components')->referencedEntities(), build the $components
array (with the new $webform and $details) and assign it to the node field, and
finally call $node->save(); this ensures existing components are preserved if
$webform->save() fails.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7778c0fd-16e9-4a79-93d1-e2f0a1074f6b
📒 Files selected for processing (4)
web/modules/custom/do_base/content/blog/demo-article.htmlweb/modules/custom/do_base/do_base.deploy.phpweb/themes/custom/drevops/assets/js/stats-counter.jsweb/themes/custom/drevops/assets/sass/redesign/_extra.scss
This comment has been minimized.
This comment has been minimized.
…on backgrounds and minimal nav styling.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
web/modules/custom/do_base/do_base.deploy.php (2)
141-154:⚠️ Potential issue | 🔴 Critical | ⚡ Quick winContact component replacement is non-atomic and can lose content
Existing components are deleted before the new references are persisted on the node. If anything fails before
Line 154save completes, the node can be left with deleted references and the new paragraphs orphaned.Persist new references first, then delete old references (or wrap the whole sequence in a transaction).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/modules/custom/do_base/do_base.deploy.php` around lines 141 - 154, The current flow deletes existing paragraph entities via the $node->get('field_c_n_components')->referencedEntities() loop before persisting the new Paragraph (Paragraph::create / $webform->save()) and updating the node ($node->set / $node->save()), which risks leaving the node with missing references if something fails; change the sequence so you first create and save the new Paragraphs (e.g., using Paragraph::create and $webform->save()), update the node's field with the new references ($node->set('field_c_n_components', ...)) and save the node ($node->save()), and only after that delete the old referenced entities ($existing->delete()), or alternatively wrap the create/save/delete sequence in a transaction so the entire operation is atomic.
50-52:⚠️ Potential issue | 🟠 Major | ⚡ Quick winResolve aliased front-page paths before parsing node ID
This only works when
page.frontis already/node/{id}. If it is configured as an alias (for example/home), homepage rebuild is skipped incorrectly.Proposed fix
- $front = (string) \Drupal::config('system.site')->get('page.front'); - $node = preg_match('#^/node/(\d+)$#', $front, $matches) ? Node::load((int) $matches[1]) : NULL; + $front = (string) \Drupal::config('system.site')->get('page.front'); + $internal_path = \Drupal::service('path_alias.manager')->getPathByAlias($front); + $node = preg_match('#^/node/(\d+)$#', $internal_path, $matches) + ? Node::load((int) $matches[1]) + : NULL;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/modules/custom/do_base/do_base.deploy.php` around lines 50 - 52, The code reads the raw page.front value and only matches literal /node/{id}; update the logic to resolve aliases first using Drupal's path alias service (e.g. \Drupal::service('path_alias.manager') or \Drupal::service('path.alias_manager')->getPathByAlias) to get the internal path, then parse that resolved path for ^/node/(\d+)$ and call Node::load((int)$matches[1]) as before; replace the current direct use of \Drupal::config('system.site')->get('page.front') with alias resolution before preg_match so aliased front pages (like /home) correctly map to the node ID.
♻️ Duplicate comments (1)
web/modules/custom/do_base/do_base.deploy.php (1)
210-215:⚠️ Potential issue | 🔴 Critical | ⚡ Quick win
_do_base_set_components()still deletes old references before node saveThis is the same unresolved delete-before-persist risk previously flagged: old paragraphs are removed before the caller saves the updated node, so a failed save can leave dangling references/data loss.
Safer sequence
function _do_base_set_components(Node $node, string $dir): void { if (!$node->hasField('field_c_n_components')) { return; } $components = _do_base_html_paragraphs($dir); + $old_components = $node->get('field_c_n_components')->referencedEntities(); - foreach ($node->get('field_c_n_components')->referencedEntities() as $existing) { - $existing->delete(); - } - $node->set('field_c_n_components', $components); + $node->save(); + + foreach ($old_components as $existing) { + $existing->delete(); + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/modules/custom/do_base/do_base.deploy.php` around lines 210 - 215, The _do_base_set_components() function currently deletes existing paragraph entities via iterating referencedEntities() on $node->get('field_c_n_components') before the node is saved, which risks data loss on failed saves; change the sequence so you first record the existing referenced entity IDs, set the node's 'field_c_n_components' to $components (replacing references) and let the caller save the node, then after a successful save delete only the previously-recorded paragraph entities that are no longer referenced; in short: do not call delete() on $existing before persistence — collect IDs, replace the field on $node, and perform deletions only post-save (or return the IDs so the caller can delete them after save).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@web/modules/custom/do_base/do_base.deploy.php`:
- Around line 84-89: The banner cleanup in _do_base_clear_banner() currently
deletes referenced paragraph entities immediately (using
$node->get($field)->referencedEntities() and $existing->delete()) before the
node is saved, which can leave dangling references if the save fails; change the
flow to capture the old referenced entities into a temporary array, set or stage
the new value on the node (e.g. $node->set($field, []) or assign the new
references), call $node->save() to persist the pointer changes, and only after a
successful save loop over the previously captured $oldReferences to delete each
$existing; update the function to follow this "stage -> save node -> delete old
entities" pattern.
In `@web/themes/custom/drevops/assets/sass/redesign/_extra.scss`:
- Around line 33-49: The selector .ct-basic-content:has(section) is too broad
and can remove layout constraints on non-redesign pages; narrow it to target
only redesign markup by changing the selector to require the redesign section
marker (e.g., use .ct-basic-content:has(.component-section) or
.ct-basic-content.component-section:has(section)) so the contained rules for
.container, .row and [class*='col-'] only apply to redesign sections; update the
selector in _extra.scss accordingly.
---
Outside diff comments:
In `@web/modules/custom/do_base/do_base.deploy.php`:
- Around line 141-154: The current flow deletes existing paragraph entities via
the $node->get('field_c_n_components')->referencedEntities() loop before
persisting the new Paragraph (Paragraph::create / $webform->save()) and updating
the node ($node->set / $node->save()), which risks leaving the node with missing
references if something fails; change the sequence so you first create and save
the new Paragraphs (e.g., using Paragraph::create and $webform->save()), update
the node's field with the new references ($node->set('field_c_n_components',
...)) and save the node ($node->save()), and only after that delete the old
referenced entities ($existing->delete()), or alternatively wrap the
create/save/delete sequence in a transaction so the entire operation is atomic.
- Around line 50-52: The code reads the raw page.front value and only matches
literal /node/{id}; update the logic to resolve aliases first using Drupal's
path alias service (e.g. \Drupal::service('path_alias.manager') or
\Drupal::service('path.alias_manager')->getPathByAlias) to get the internal
path, then parse that resolved path for ^/node/(\d+)$ and call
Node::load((int)$matches[1]) as before; replace the current direct use of
\Drupal::config('system.site')->get('page.front') with alias resolution before
preg_match so aliased front pages (like /home) correctly map to the node ID.
---
Duplicate comments:
In `@web/modules/custom/do_base/do_base.deploy.php`:
- Around line 210-215: The _do_base_set_components() function currently deletes
existing paragraph entities via iterating referencedEntities() on
$node->get('field_c_n_components') before the node is saved, which risks data
loss on failed saves; change the sequence so you first record the existing
referenced entity IDs, set the node's 'field_c_n_components' to $components
(replacing references) and let the caller save the node, then after a successful
save delete only the previously-recorded paragraph entities that are no longer
referenced; in short: do not call delete() on $existing before persistence —
collect IDs, replace the field on $node, and perform deletions only post-save
(or return the IDs so the caller can delete them after save).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 36621c92-db3b-4157-97bf-4cfc8a9df18a
📒 Files selected for processing (9)
web/modules/custom/do_base/content/contact/00-hero.htmlweb/modules/custom/do_base/content/homepage/00-hero.htmlweb/modules/custom/do_base/content/homepage/01-services.htmlweb/modules/custom/do_base/content/homepage/05-process.htmlweb/modules/custom/do_base/content/services/00-hero.htmlweb/modules/custom/do_base/content/services/01-detail.htmlweb/modules/custom/do_base/do_base.deploy.phpweb/themes/custom/drevops/assets/sass/redesign/_extra.scssweb/themes/custom/drevops/components/variables.base.scss
This comment has been minimized.
This comment has been minimized.
…scoped the container reset to redesign sections.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…rs and hover lift.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Added a compact 'page' banner type (centred 56px headline, coral eyebrow line, faint static glow) for the blog listing, replacing the oversized homepage-style hero. Rendered the promo card date as the design's uppercase meta line with an estimated read-time, capped node card summaries to keep cards compact, forced grid card images to 16/9, stopped a square featured image from stretching the feature panel, and hid the results count.
…pha/keyword notation.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Code coverage (threshold: 80%) Per-class coverage |
Summary
This PR applies the dark visual redesign across the homepage, services, contact, and blog by building on CivicTheme components - introducing new SDC components (
fact-card,service-detail, extendedpromo-card), a custom banner type system (hero/fade/page), and aContentBuilderclass in thedo_basemodule that provisions structured page content via deploy hooks. The approach keeps content in proper structured fields rather than raw HTML paragraphs, and keeps visual treatments in the theme's brand SASS layer rather than inline markup.Changes
Theme / SDC components
banner.twig,banner.inc): Added opt-inhero(full-viewport intro hero) andfade(blog-post image overlay) banner types alongside the existingpagetype; type is stored in a newfield_c_n_banner_type/field_c_b_banner_typefield.fact-cardSDC (02-molecules/fact-card/): New molecule for the homepage stat figures - acceptstitle,summary,suffix, andthemefields, rendered via a Twig template and backed by ado_fact_cardparagraph type.service-detailSDC (02-molecules/service-detail/): New molecule replacing the old promo-card-based service listing with a dedicated structured card that carriestagline,title,price_label,price_value,content,includes,link, andthemefields.promo-cardSDC (extended): Addedmetaandread_timeslots to the existing promo-card molecule to support blog listing card metadata.footerSDC (03-organisms/footer/): New organism handling the dark minimal footer with copyright and contact slots, replacing the old unplaced block-based footer regions.assets/sass/brand/): Seven focused partials -_tokens.scss(CivicTheme variable overrides),_layout.scss,_buttons.scss,_content.scss,_lists.scss,_blog.scss,_contact.scss,_animations.scss, and_extra.scss- all imported viatheme.scss. Scroll-reveal animation (reveal.js) is scoped to the homepage only viadrevops.libraries.yml.Content build -
do_basemoduleContentBuilderclass (src/ContentBuilder.php): Centralises all programmatic page construction - resolves the front page from config, builds paragraph arrays, deletes stale paragraphs safely before re-attaching, and exposes typed factory methods for every reused paragraph pattern.do_base.deploy.php): Individual hooks per page (homepage, services, contact, blog) useContentBuilderto populate structured paragraph fields; each hook is idempotent and can be re-run safely.manual-listpreprocess (includes/manual_list.inc,paragraph--civictheme-manual-list.html.twig): Addedfield_p_appearanceandfield_p_eyebrowto support the homepage list design treatments.do_base.info.ymlupdated to declare the newdo_fact_cardanddo_service_detailparagraph types as dependencies.Config / fields
field_p_includes,field_p_tagline,field_p_price_label,field_p_price_value,field_p_suffix,field_p_eyebrow,field_p_appearance.do_fact_cardanddo_service_detailwith full form and view display configs.ContentBuilder).editor.editor.full_html.ymland trimmedfilter.format.full_html.ymlto remove the CKEditor toolbar config that was scaffolded for raw-HTML authoring.webform.webform.contact.yml: Updated contact form field layout to match the two-column redesign.core.extension.yml: Addeddo_basemodule to the enabled extensions.Tests
tests/behat/features/contact.feature: Updated heading and form field assertions to match the redesigned contact page structure.