Skip to content

feat: CMD-187 autocreate search page#1129

Draft
wesleyboar wants to merge 123 commits into
mainfrom
feat/template-and-setting-for-google-search
Draft

feat: CMD-187 autocreate search page#1129
wesleyboar wants to merge 123 commits into
mainfrom
feat/template-and-setting-for-google-search

Conversation

@wesleyboar
Copy link
Copy Markdown
Member

Overview

Support a Google Search page with less effort.

What Effort?

Every Time:

  1. Create search engine.
  2. Configure search engine to match others.
  3. Set owners of search engine.
  4. Copy search codeID.
  5. Set relevant SEARCH settings.

Previously:

  1. Restart the server.
  2. Create /search page.
  3. Create snippet on page.
  4. Paste search code in snippet.
  5. Duplicate-or-Neglect search styles from TACC

Now, Instead:

  1. Restart the server.

Important

Incomplete because there is a suggestion (which I agree with) to use a custom migration.
Originally built off code from release/v4.36.X when it had been main branch.

Caution

Do not merge.

To Do:

Warning

Successful run requires two deploys. Help wanted.

Related

Instances:

Changes

  • added search_page app
  • added SEARCH_AUTO_SETUP setting
  • added GOOGLE_SEARCH_ENGINE_ID setting

Testing

  1. Register a Google Programmable Search Engine.
  2. Add real GOOGLE_SEARCH_ENGINE_ID setting e.g.
    GOOGLE_SEARCH_ENGINE_ID = 'b099996c09ebd4ece'
  3. Add SEARCH_AUTO_SETUP = True setting.
  4. Run/Deploy website that has no search page.
  5. Verify "Search (Auto-Generated)" page exists.
  6. Search using search bar.
  7. ✅ Verify search page shows with results.
  8. Remove GOOGLE_SEARCH_ENGINE_ID setting.
  9. Run/Deploy site.
  10. Revisit search page.
  11. ✅ Verify warning appears on page.

UI

with GOOGLE_SEARCH_ENGINE_ID sans GOOGLE_SEARCH_ENGINE_ID
search is set search not set

So that it can be loaded from CDN. Use cases are:
- if search template is broken
- for custom search page
- for non-Core website
Compared to "cms-search", "google-search" is:
- more accurate
- more obvious to those not familiar with Core-CMS
So dev sees 'google-search' from CSS before seeing it in HTML `id` attr.
This had create dbreadcrumsb before.
Final markup undecided, so keep it simple, and easy to understand.
wesleyboar and others added 20 commits November 13, 2025 18:35
* feat: logo icons inherit color

* feat: organization logos inherit color

* feat: core logo inherit color

* feat: logos inherit size

* fix: ending `<p>` tag

* feat: Icon svg inherit size

* fix: no empty underlined space on hover

* fix: tacc formal logo fill wrong

* fix: bluesky logo duplicate code

* feat: color icons

* fix: bust cache
feat: support DjangoCMS Bootstrap4 Link/Button (#1020) (#1022) (#1030)

fix: remove redundtant social media icon css
Also, I am locally using newer Poetry version (2.1.4 to 2.2.1).
## Overview

Merge v4.35.23.

## Changes

-
[incoming](v4.36.14...v4.35.23)
-
[current](v4.35.23...v4.36.14)

## Testing

1. Branch https://github.com/TACC/Texascale-CMS.
2. Use a branch with this merge:
    - [ ] `main--merge-v4-35.23`
    - [x] `taccwma/core-cms:fix-core-cms-template-gh-18--v4-36`
3. Build `taccwma/texascale-cms` image.
4. Deploy to pre-prod.
5. Verify no error & no change (compare to prod).

---------

Co-authored-by: fnets <fnetscher@gmail.com>
## Overview

Merge in
[v4.37.0](https://github.com/TACC/Core-CMS/releases/tag/v4.37.0).

## Changes

- v4.36.23...v4.37.0

## Testing

Already tested via #1075 on Texascale.

---------

Co-authored-by: fnets <fnetscher@gmail.com>
Added styles to fix link UI and UX.
Added styles to fix MORE link UI and UX.
@wesleyboar wesleyboar marked this pull request as draft March 24, 2026 18:29
@wesleyboar wesleyboar marked this pull request as ready for review May 12, 2026 19:22
@wesleyboar wesleyboar marked this pull request as draft May 12, 2026 19:22
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Auto-create Google Search page with Django CMS integration

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Automatically create and manage Google Search page with minimal configuration
• Add new search_page Django app with CMS integration and apphook support
• Introduce SEARCH_PAGE_AUTO_SETUP and GOOGLE_SEARCH_ENGINE_ID settings
• Implement search template with Google Custom Search Engine styling and fallback warning
• Update search bar to use dynamically resolved search page URL via template tag
Diagram
flowchart LR
  A["Settings<br/>SEARCH_PAGE_AUTO_SETUP<br/>GOOGLE_SEARCH_ENGINE_ID"] -->|triggers| B["SearchPageConfig.ready()"]
  B -->|calls| C["create_page()"]
  C -->|creates CMS Page<br/>with apphook| D["SearchPageApphook"]
  D -->|routes to| E["SearchPageView"]
  E -->|renders| F["search_page.html<br/>with Google CSE"]
  G["nav_search.raw.html"] -->|uses| H["search_page_url tag"]
  H -->|resolves to| D
Loading

Grey Divider

File Changes

1. apps/search_page/apps.py ✨ Enhancement +10/-0

App config with auto-setup trigger

apps/search_page/apps.py


2. apps/search_page/cms_apps.py ✨ Enhancement +11/-0

CMS apphook for search page routing

apps/search_page/cms_apps.py


3. apps/search_page/urls.py ✨ Enhancement +8/-0

URL patterns for search page view

apps/search_page/urls.py


View more (10)
4. apps/search_page/views.py ✨ Enhancement +4/-0

Simple view rendering search template

apps/search_page/views.py


5. apps/search_page/utils.py ✨ Enhancement +64/-0

Utilities for page creation and retrieval

apps/search_page/utils.py


6. apps/search_page/templates/search_page.html ✨ Enhancement +25/-0

Search page template with Google CSE integration

apps/search_page/templates/search_page.html


7. apps/search_page/static/search_page/css/google-search.css ✨ Enhancement +152/-0

Comprehensive styling for Google Custom Search

apps/search_page/static/search_page/css/google-search.css


8. taccsite_cms/templatetags/search_tags.py ✨ Enhancement +10/-0

Template tag for dynamic search page URL resolution

taccsite_cms/templatetags/search_tags.py


9. taccsite_cms/_settings/search.py ⚙️ Configuration changes +6/-2

Add search configuration settings and defaults

taccsite_cms/_settings/search.py


10. taccsite_cms/settings/settings.py ⚙️ Configuration changes +2/-0

Register search_page app and expose settings

taccsite_cms/settings/settings.py


11. taccsite_cms/settings/settings_custom.example.py 📝 Documentation +3/-2

Document Google Search configuration example

taccsite_cms/settings/settings_custom.example.py


12. taccsite_cms/templates/nav_search.raw.html ✨ Enhancement +2/-2

Update search form to use dynamic search URL

taccsite_cms/templates/nav_search.raw.html


13. apps/search_page/__init__.py Additional files +0/-0

...

apps/search_page/init.py


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 12, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📎 Requirement gaps (0)

Context used
✅ Tickets: CMD-187

Grey Divider


Action required

1. Unused Page import 📘 Rule violation ⚙ Maintainability
Description
taccsite_cms/templatetags/search_tags.py imports Page but never uses it, which triggers a Flake8
F401 unused import violation. This can fail linting for the taccsite_cms/ module.
Code

taccsite_cms/templatetags/search_tags.py[2]

+from cms.models import Page
Evidence
PR Compliance ID 1 requires no new Flake8 violations in taccsite_cms/. The added file imports
Page on line 2 but does not reference it anywhere in the module, which is an F401 violation.

AGENTS.md
taccsite_cms/templatetags/search_tags.py[1-10]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`taccsite_cms/templatetags/search_tags.py` imports `Page` but does not use it, which violates Flake8 (`F401`).

## Issue Context
Compliance requires no new Flake8 violations when running `flake8 taccsite_cms/ --max-line-length=120`.

## Fix Focus Areas
- taccsite_cms/templatetags/search_tags.py[1-4]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. DB write in AppConfig.ready 🐞 Bug ☼ Reliability
Description
SearchPageConfig.ready() calls create_page(), which performs ORM reads/writes during Django app
initialization; this can crash server startup or management commands when CMS tables aren’t
migrated/available yet. The codebase already uses post_migrate for DB bootstrapping, so this is an
inconsistent and unsafe initialization mechanism.
Code

apps/search_page/apps.py[R7-10]

+    def ready(self):
+        if settings.SEARCH_PAGE_AUTO_SETUP:
+            from .utils import create_page
+            create_page()
Evidence
SearchPageConfig.ready() immediately calls create_page(), and create_page() uses the CMS
Page model and create_cms_page() (DB write). In contrast, existing DB bootstrapping in this repo
is deferred to post_migrate, indicating the intended safe lifecycle for DB-touching
initialization.

apps/search_page/apps.py[4-10]
apps/search_page/utils.py[41-59]
taccsite_cms/apps.py[13-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`SearchPageConfig.ready()` triggers DB work (`create_page()`) during app initialization. This runs on every process start and can fail before migrations (or when DB is unavailable), preventing startup.

## Issue Context
The repository already bootstraps DB state using `post_migrate` (see `taccsite_cms/apps.py`). The search page creation should follow the same pattern and be resilient to missing tables.

## Fix Focus Areas
- apps/search_page/apps.py[1-10]
- apps/search_page/utils.py[41-64]
- taccsite_cms/apps.py[13-24]

## Implementation notes
- Replace `ready()` DB call with `post_migrate.connect(...)` (like `taccsite_cms.apps.TaccsiteCmsConfig`).
- Guard access to `settings.SEARCH_PAGE_AUTO_SETUP` via `getattr(settings, 'SEARCH_PAGE_AUTO_SETUP', False)`.
- Ensure the handler is idempotent and wraps DB errors (e.g., `OperationalError`, `ProgrammingError`) with logging instead of crashing startup.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Uncaught DB errors in tag 🐞 Bug ☼ Reliability
Description
{% search_page_url %} calls get_page_url()/get_page() which performs a CMS Page query
without effective exception handling, so DB/table-not-ready failures can break rendering of
/cms/nav/search/markup/ instead of falling back to PORTAL_SEARCH_PATH. The current `except
Page.DoesNotExist around filter(...).first()` is unreachable and misleading, and it does not
protect against real DB-level errors for this TemplateView-served markup endpoint relied on by other
services.
Code

taccsite_cms/templates/nav_search.raw.html[R3-6]

+{% load static search_tags %}
<!-- FAQ: This template loads independently at a unique url (see `urls.py`)
          so Portal and User Guide can render this markup into their markup. -->
Evidence
The nav search markup template invokes search_page_url, which calls get_page_url() and then
get_page() to query the CMS Page table via Page.objects.filter(...).first(), meaning it can
hit the database during template rendering. Because .filter().first() does not raise
Page.DoesNotExist (only .get() does), the existing except Page.DoesNotExist handler is dead
code and provides no resilience; additionally, there is no handling for DB-level exceptions such as
missing tables or connection issues, so those exceptions would propagate and break
/cms/nav/search/markup/, which is explicitly exposed via TemplateView in taccsite_cms/urls.py.

taccsite_cms/urls.py[32-40]
taccsite_cms/templates/nav_search.raw.html[3-26]
taccsite_cms/templatetags/search_tags.py[1-10]
apps/search_page/utils.py[18-39]
apps/search_page/utils.py[18-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The `search_page_url` template tag triggers a CMS `Page` database query via `get_page_url()`/`get_page()` during rendering of `/cms/nav/search/markup/`. The current error handling is ineffective because it catches `Page.DoesNotExist` around a `filter(...).first()` query that never raises that exception, and DB/table-not-ready errors (e.g., during deploy/migration windows) can propagate and break this markup endpoint instead of gracefully falling back to `settings.PORTAL_SEARCH_PATH`.

## Issue Context
`/cms/nav/search/markup/` is served via `TemplateView` and is used to return markup to other apps/services, so it should remain reliable even when CMS tables are temporarily unavailable. The code path is: nav search markup template -> `search_page_url` -> `get_page_url()` -> `get_page()` -> `Page.objects.filter(...).first()`, which currently lacks appropriate DB-level exception handling and contains an unreachable `except Page.DoesNotExist`.

## Fix Focus Areas
- taccsite_cms/templates/nav_search.raw.html[3-13]
- taccsite_cms/templatetags/search_tags.py[1-10]
- apps/search_page/utils.py[18-39]
- taccsite_cms/urls.py[32-40]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@wesleyboar wesleyboar changed the base branch from release/v4.36.X to main May 12, 2026 19:25
@@ -0,0 +1,10 @@
from django import template
from cms.models import Page
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Unused page import 📘 Rule violation ⚙ Maintainability

taccsite_cms/templatetags/search_tags.py imports Page but never uses it, which triggers a Flake8
F401 unused import violation. This can fail linting for the taccsite_cms/ module.
Agent Prompt
## Issue description
`taccsite_cms/templatetags/search_tags.py` imports `Page` but does not use it, which violates Flake8 (`F401`).

## Issue Context
Compliance requires no new Flake8 violations when running `flake8 taccsite_cms/ --max-line-length=120`.

## Fix Focus Areas
- taccsite_cms/templatetags/search_tags.py[1-4]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread apps/search_page/apps.py
Comment on lines +7 to +10
def ready(self):
if settings.SEARCH_PAGE_AUTO_SETUP:
from .utils import create_page
create_page()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Db write in appconfig.ready 🐞 Bug ☼ Reliability

SearchPageConfig.ready() calls create_page(), which performs ORM reads/writes during Django app
initialization; this can crash server startup or management commands when CMS tables aren’t
migrated/available yet. The codebase already uses post_migrate for DB bootstrapping, so this is an
inconsistent and unsafe initialization mechanism.
Agent Prompt
## Issue description
`SearchPageConfig.ready()` triggers DB work (`create_page()`) during app initialization. This runs on every process start and can fail before migrations (or when DB is unavailable), preventing startup.

## Issue Context
The repository already bootstraps DB state using `post_migrate` (see `taccsite_cms/apps.py`). The search page creation should follow the same pattern and be resilient to missing tables.

## Fix Focus Areas
- apps/search_page/apps.py[1-10]
- apps/search_page/utils.py[41-64]
- taccsite_cms/apps.py[13-24]

## Implementation notes
- Replace `ready()` DB call with `post_migrate.connect(...)` (like `taccsite_cms.apps.TaccsiteCmsConfig`).
- Guard access to `settings.SEARCH_PAGE_AUTO_SETUP` via `getattr(settings, 'SEARCH_PAGE_AUTO_SETUP', False)`.
- Ensure the handler is idempotent and wraps DB errors (e.g., `OperationalError`, `ProgrammingError`) with logging instead of crashing startup.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant