Skip to content

feat: CMD-187 autocreate search page - #1129

Closed
wesleyboar wants to merge 74 commits into
release/v4.36.Xfrom
feat/template-and-setting-for-google-search
Closed

feat: CMD-187 autocreate search page#1129
wesleyboar wants to merge 74 commits into
release/v4.36.Xfrom
feat/template-and-setting-for-google-search

Conversation

@wesleyboar

@wesleyboar wesleyboar commented Mar 24, 2026

Copy link
Copy Markdown
Member

Tip

Superseded by #1215 (into #1216).


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.
Updated pull request template to improve clarity and structure.
## Overview

Update to [Core-Styles
v2.55](https://github.com/TACC/Core-Styles/releases/tag/v2.55.0) for:
- accessibility fixes to `.section`s
- new `.section` style **`accent`**
- support [Bootstrap v4 `media`
object](https://getbootstrap.com/docs/4.6/components/media-object/)
- new script to create page to test sections

## Related

- required by TACC/Core-CMS-Custom#531

## Changes

- **updated** Core-Styles
- **added** section--accent`

## Testing

1. `make build`
2. `make start`
3. Create a page with:
    - two sections, one after the other
    - each section has `<h2>` and text
    - try different section combinations
4. Verify UI matches sections of:
    - TACC/Core-Styles#625
    - TACC/Core-Styles#624


## UI

<img width="899" height="470" alt="Screenshot 2026-04-08 at 20 48 11"
src="https://github.com/user-attachments/assets/bc90026d-c1c0-4491-b362-913aa7eb48eb"
/>
## Overview / Changes

Update Dockerfile to use Node 20 (to match Core-Styles dependency
expectation).

## Related

- TACC/Core-Styles#595

## Testing

1. `make stop`
2. `make build`
3. `make start`
4. No errors.
5. http://localhost:8000/
6. Site loads.

## UI

```log
Core-CMS % make build
docker-compose -f ./docker-compose.yml build
[+] Building 128.4s (26/26) FINISHED                                        
 => [internal] load local bake definitions                             0.0s
 => => reading from stdin 517B                                         0.0s
 => [internal] load build definition from Dockerfile                   0.1s
 => => transferring dockerfile: 1.72kB                                 0.0s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match  0.1s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match  0.1s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match  0.1s
 => WARN: FromAsCasing: 'as' and 'FROM' keywords' casing do not match  0.1s
 => [internal] load metadata for docker.io/library/node:20             3.9s
 => [internal] load metadata for docker.io/library/python:3.11-bullse  2.8s
 => [auth] library/python:pull token for registry-1.docker.io          0.0s
 => [auth] library/node:pull token for registry-1.docker.io            0.0s
 => [internal] load .dockerignore                                      0.0s
 => => transferring context: 176B                                      0.0s
 => [python-base 1/8] FROM docker.io/library/python:3.11-bullseye@sha  0.0s
 => => resolve docker.io/library/python:3.11-bullseye@sha256:df0bd610  0.0s
 => [node_build 1/6] FROM docker.io/library/node:20@sha256:8789e1e07  50.4s
 => => resolve docker.io/library/node:20@sha256:8789e1e0752d81088a085  0.0s
 => => sha256:05af486a428bc264e22e9b46c9b0d3e75a3b868c1b4 447B / 447B  0.6s
 => => sha256:3043560987f3ed858a74597354d7d913ab0ae88 1.25MB / 1.25MB  0.5s
 => => sha256:4ab7d5d5363a3853730f20f1192dd6640eba1 48.59MB / 48.59MB  3.6s
 => => sha256:2ad0741a80b84ae8126670b69ac8e761fc 203.07MB / 203.07MB  12.8s
 => => sha256:d970c14c7a02db7b2db8e2a7f7302b3362854d2 3.33kB / 3.33kB  0.3s
 => => sha256:95b913dee6e116304b9bb2391ef8aedbb1f5e 64.48MB / 64.48MB  9.6s
 => => sha256:0af98f0879b367460715b477e9118922ba24f 23.60MB / 23.60MB  9.6s
 => => sha256:d03e31a3f7ef0d2866d799846c3a18286fab 48.37MB / 48.37MB  10.2s
 => => extracting sha256:d03e31a3f7ef0d2866d799846c3a18286fab6fcddbd8  3.7s
 => => extracting sha256:0af98f0879b367460715b477e9118922ba24f17d9a4a  1.5s
 => => extracting sha256:95b913dee6e116304b9bb2391ef8aedbb1f5ee16d16  10.4s
 => => extracting sha256:2ad0741a80b84ae8126670b69ac8e761fcd50aa252d  11.8s
 => => extracting sha256:d970c14c7a02db7b2db8e2a7f7302b3362854d2d5307  0.0s
 => => extracting sha256:4ab7d5d5363a3853730f20f1192dd6640eba1a6576ab  7.0s
 => => extracting sha256:3043560987f3ed858a74597354d7d913ab0ae886bbe9  0.1s
 => => extracting sha256:05af486a428bc264e22e9b46c9b0d3e75a3b868c1b48  0.1s
 => [internal] load build context                                      2.3s
 => => transferring context: 15.02MB                                   2.2s
 => [node_build 2/6] COPY package.json package-lock.json /code/        1.9s
 => [node_build 3/6] WORKDIR /code                                     0.1s
 => [node_build 4/6] RUN npm ci                                       14.3s
 => [node_build 5/6] COPY . /code/                                     3.1s
 => [node_build 6/6] RUN npm run build --build-id="$BUILD_ID"         16.8s
 => CACHED [python-base 2/8] RUN apt-get update && apt-get install -y  0.0s
 => CACHED [python-base 3/8] RUN pip3 install --upgrade pip setuptool  0.0s
 => CACHED [python-base 4/8] RUN curl -sSL https://install.python-poe  0.0s
 => CACHED [python-base 5/8] RUN mkdir /code                           0.0s
 => CACHED [python-base 6/8] COPY pyproject.toml poetry.lock /code/    0.0s
 => CACHED [python-base 7/8] WORKDIR /code                             0.0s
 => CACHED [python-base 8/8] RUN poetry install --only main --no-root  0.0s
 => CACHED [production 1/2] RUN mkdir -p /var/log/cms                  0.1s
 => [production 2/2] COPY --from=node_build /code/ /code               2.1s
 => exporting to image                                                18.2s
 => => exporting layers                                               13.3s
 => => exporting manifest sha256:3c78d75eb72ed4e682cc3e5474d578cc5bb4  0.1s
 => => exporting config sha256:50d8ed278a89aca09a0acb279557e19803c2ce  0.0s
 => => exporting attestation manifest sha256:9a1884c8b82634fb21ccaf3f  0.1s
 => => exporting manifest list sha256:f5200ba0b4a47719c2fac6e6da6c117  0.0s
 => => naming to docker.io/taccwma/core-cms:latest                     0.0s
 => => unpacking to docker.io/taccwma/core-cms:latest                  4.5s
 => resolving provenance for metadata file                             0.1s
[+] build 1/1
 ✔ Image taccwma/core-cms:latest Built                                130.8s
```
## Overview

Another Core-Styles bump for accessibility fixes.

I actually think I am near the end of all this, for now.
## Overview

**Before:**
* no footer links by default
* added footer link style did not match design

**After:**
* footer links by default
* footer link style matches design
* footer links are accessible

## Related

- requires
[TACC/Core-Styles@v2.56.0](https://github.com/TACC/Core-Styles/releases/tag/v2.56.0)

## Changes

- **added** default footer links
- **updated** Core-Styles

## Testing

1. `make setup`
2. Open http://localhost:8000/.
3. See footer has links.
4. See footer links match text color but have faint underline.
5. See footer link hover and press change footer link style.

## UI

| Before Links<br>Before Styles | After Links<br>Before Styles | After
Links<br>After Styles |
| - | - | - |
| <img width="405" height="465" alt="before footer links, before footer
styles"
src="https://github.com/user-attachments/assets/429eccc5-2106-42bf-81a3-a1b849ffb2df"
/> | <img width="405" height="465" alt="after footer links, before
footer styles"
src="https://github.com/user-attachments/assets/16fe8fa6-3046-49c3-8186-f7539f1766a0"
/> | <img width="405" height="465" alt="after footer links, after footer
styles"
src="https://github.com/user-attachments/assets/9a23bf01-dd20-4d96-a6d7-f8cb24264ae2"
/>


https://github.com/user-attachments/assets/18fc6809-4854-4e04-a57d-60f38a2e23e1


https://github.com/user-attachments/assets/ce4a87df-5f66-4638-93b8-3a27506c8d4e


https://github.com/user-attachments/assets/71fe0d5c-c4ca-4908-b1a2-74be5aba0e21
Stop reporting this outdated security risk.
Updated the default URL path for the Section/Container style QA page from '/section-style-qa/' to '/test-section-style/'.
## Overview

Updated README to reflect command name change for creating test pages.
Added sections for Architecture and Pull Requests to AGENTS.md.
I know its for agents, but i view it when I need to edit. And others view it when they want to know.
Found helpful since using local agents.
## Overview
Use a Core-Styles commit-ish with the footer text-color fix.

## Related
- requires TACC/Core-Styles#633

## Changes
- **updated** `@tacc/core-styles` to a branch-based install
- **updated** lockfile entries to the matching Core-Styles commit

## Testing
1. Verify dependency and lockfile both reference
`fix/footer-text-color-one-step-darker`.
2. Build CSS locally and confirm footer text/links render one step
darker.

## UI

<img width="960" height="874" alt="cms-footer-after"
src="https://github.com/user-attachments/assets/48b850ce-7f0e-43f2-be2c-ded2452113fc"
/>

---

Made with [Cursor](https://cursor.com)
@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

qodo-code-review Bot commented May 12, 2026

Copy link
Copy Markdown

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

@wesleyboar
wesleyboar changed the base branch from main to release/v4.36.X July 27, 2026 17:02
@wesleyboar
wesleyboar changed the base branch from release/v4.36.X to main July 27, 2026 17:03
@wesleyboar
wesleyboar changed the base branch from main to release/v4.36.X July 27, 2026 21:20
wesleyboar added a commit that referenced this pull request Jul 27, 2026
## Overview

Rebuilds the search feature on current `main` instead of stale
`release/v4.36.X`.

> [!WARNING]
> First run on a fresh database will crash `manage.py migrate` itself,
because `apps/search_page/apps.py`'s `ready()` hook queries `cms_page`
before it exists. Workaround: set `SEARCH_PAGE_AUTO_SETUP = False`,
migrate, then set it back to `True` and restart.
[Details.](#885 (review))

> [!IMPORTANT]
> Should instead:
> - [Use a custom
migration.](#885 (review))
> - (and/or) Create a [Core-CMS
plugin](https://github.com/search?q=org%3ATACC+%22Core-CMS-Plugin%22&type=repositories)
(from [TACC/Django-App](https://github.com/TACC/Django-App)).

## Related

- replaces #1129

## Changes

- **rebuilt** branch from `main` + cherry-picked search-only commits
- **dropped** unrelated inherited commits (favicons, breadcrumbs,
image-zoom, etc.)

## Testing / UI

See #1129.
@wesleyboar

Copy link
Copy Markdown
Member Author

Tip

Superseded by #1215 (into #1216).

@wesleyboar wesleyboar closed this Jul 27, 2026
@wesleyboar
wesleyboar deleted the feat/template-and-setting-for-google-search branch July 27, 2026 23:08
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.

2 participants