Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6ce515d
feat: template & setting for Google search
wesleyboar Oct 22, 2024
a94eb5a
fix: styles and fallback warning for Google Search
wesleyboar Oct 22, 2024
3b7ead1
enhance: move sarch CSS to its own file
wesleyboar Oct 22, 2024
948e43b
enhance: rename search stylesheet and ID
wesleyboar Oct 22, 2024
19652d7
refactor: move css to top of template
wesleyboar Oct 22, 2024
cc60de5
fix: missing default GOOGLE_SEARCH_ENGINE_ID
wesleyboar Oct 22, 2024
cfb2c93
feat: search template is standard
wesleyboar Oct 23, 2024
6673b49
feat: convert search template into a search app
wesleyboar Oct 23, 2024
af2f202
feat(search_page): slimmer views.py
wesleyboar Oct 23, 2024
ad24ead
feat(search): create page if it does not exist
wesleyboar Oct 23, 2024
ed24295
fix(search): restore breadcrumbs
wesleyboar Oct 23, 2024
df95a9a
chore(search_page): remove now-unnecessary file
wesleyboar Oct 23, 2024
7eae863
enhance(search_page): flag page as auto-generated
wesleyboar Oct 23, 2024
572fdd9
enhance(search): attach apphook to manage urls
wesleyboar Oct 23, 2024
7cdf7fa
style(search): polish
wesleyboar Oct 24, 2024
90798f9
fix(search): searchbar not using curr. search path
wesleyboar Oct 24, 2024
8d7cc86
chore(search): remove cruft
wesleyboar Oct 24, 2024
8fd1828
chore(search): reduce silly complexity of tag
wesleyboar Oct 24, 2024
25a68c3
chore(search): remove cruft 2
wesleyboar Oct 24, 2024
79feab0
feat(search): auto isntall and setup
wesleyboar Oct 24, 2024
5bbe3a8
feat(search): simplify an isolate markup
wesleyboar Oct 24, 2024
64107b1
core(search): remove cruft markup
wesleyboar Oct 24, 2024
7c279e1
chore(search): simlify utils.py
wesleyboar Oct 24, 2024
d620e6c
style(search): new line
wesleyboar Oct 24, 2024
b8419f9
refactor(search): polish
wesleyboar Oct 24, 2024
635212c
refactor(search): rename a function
wesleyboar Oct 24, 2024
2cac822
style(search): ending slash for example path
wesleyboar Oct 24, 2024
3058537
style(search): ending slash for example path
wesleyboar Oct 24, 2024
f013903
fix: search results style bugs
wesleyboar Feb 23, 2026
d0227aa
fix: MORE search results style bugs
wesleyboar Feb 23, 2026
bd857e3
fix(a11y): lighter accent color
wesleyboar Feb 23, 2026
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
Empty file added apps/search_page/__init__.py
Empty file.
10 changes: 10 additions & 0 deletions apps/search_page/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.apps import AppConfig
from django.conf import settings

class SearchPageConfig(AppConfig):
name = 'apps.search_page'

def ready(self):
if settings.SEARCH_PAGE_AUTO_SETUP:
from .utils import create_page
create_page()
11 changes: 11 additions & 0 deletions apps/search_page/cms_apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool


@apphook_pool.register
class SearchPageApphook(CMSApp):
app_name = 'apps.search_page'
name = 'SearchPage'

def get_urls(self, page=None, language=None, **kwargs):
return ['apps.search_page.urls']
152 changes: 152 additions & 0 deletions apps/search_page/static/search_page/css/google-search.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#google-search {

&:is(#cms-content-container > *:last-child) {
margin-bottom: var(--global-space--section-gap, 60px);
}

/* SEARCH CONTAINER */

/* To remove padding from search container */
& .gsc-control-cse {
padding: unset;
}



/* TABLE OF SEARCH STATS & SORTING OPTIONS */

/* To remove border from search analytics, add gray background */
& .gsc-above-wrapper-area {
--bkgd-color: var(--global-color-primary--x-light);

background-color: var(--bkgd-color);
box-shadow: 40vw 0 var(--bkgd-color), -40vw 0 var(--bkgd-color);
border-bottom: unset;
}

& .gsc-above-wrapper-area-container {
border-bottom: unset;
}

/* To override Core-Styles tables */
& tbody > tr:first-child > :is(td, th) {
border: unset;
padding-inline: unset;
background: unset;
vertical-align: middle;
}

& .gsc-selected-option-container {
background: var(--global-color-primary--xx-light);
border: var(--global-border--normal);
}

& .gsc-result-info {
padding: unset;
font-size: var(--global-font-size--medium);
}



/* SUGGESTION PHRASE (after "Did you mean:") */

& .gs-spelling {
padding: unset;
}
& .gs-spelling a {
color: var(--global-color-accent--light);

/* to undo core-styles.base */
/* https://github.com/TACC/Core-Styles/blob/8ab89d3/src/lib/_imports/elements/links.css */
&:not([href]) {
opacity: 1;
pointer-events: auto;
}
}



/* SEARCH RESULTS */

/* (search result body text) */
& .gs-snippet {
color: var(--global-color-primary--dark);
}

/* (url under search result title) */
& .gs-webResult div.gs-visibleUrl {
color: var(--global-color-secondary--normal);
}

/* (search result titles) */
& a.gs-title:link {
color: var(--global-color-accent--light);
text-decoration: none;
text-decoration-thickness: var(--global-border-width--normal);
text-underline-offset: 0.2em;
}
& a.gs-title:link:hover {
text-decoration-line: underline;
text-decoration-style: solid;
}
& a.gs-title b {
color: currentColor;
}
& .gs-result .gs-title:not(a):hover {
/* to remove duplicate underline */
/* (fix Google's default_v6+en.css bug `.gs-result .gs-title:hover`) */
text-decoration: auto;
}

/* (push search-result description to right) */
& .gs-image-box {
margin-right: 10px;
}



/* GOOGLE PAGE NAVIGATION (at bottom) */

& .gsc-cursor-box {
display: flex;
justify-content: center;
margin-block: var(--global-space--large);
}

& .gsc-cursor-current-page {
color: var(--global-color-accent--light);
text-decoration: none;
text-decoration-thickness: var(--global-border-width--normal);
text-underline-offset: 0.2em;
}

& .gsc-cursor-current-page:hover {
text-decoration-line: underline;
text-decoration-style: solid;
}



/* GOOGLE BRANDING */

& .gcsc-find-more-on-google {
color: var(--global-color-accent--light);
text-decoration: none;
text-decoration-thickness: var(--global-border-width--normal);
text-underline-offset: 0.2em;
}
svg.gcsc-find-more-on-google-magnifier {
fill: currentColor;
}

& .gcsc-find-more-on-google:hover {
text-decoration-line: underline;
text-decoration-style: solid;
}

& .gcsc-branding-img-noclear {
vertical-align: unset;
top: 1px;
}

}
25 changes: 25 additions & 0 deletions apps/search_page/templates/search_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "base.html" %}
{% load static cms_tags %}

{% block css %}
{{ block.super }}
<link id="css-search" rel="stylesheet" href="{% static 'search_page/css/google-search.css' %}">
{% endblock css %}

{% block app_content %}
<div class="row">
<div class="col col-12 col-sm-12 col-md-6 col-lg-6 col-xl-6">
<h1>{% page_attribute "page_title" %}</h1>
</div>
</div>

{% if settings.GOOGLE_SEARCH_ENGINE_ID %}
<div id="google-search">
<script async src="https://cse.google.com/cse.js?cx={{ settings.GOOGLE_SEARCH_ENGINE_ID }}">
</script>
<div class="gcse-searchresults-only"></div>
</div>
{% else %}
<p class="c-message c-message--scope-section c-message--type-warning">Please inform your website administrator to verify a <code>GOOGLE_SEARCH_ENGINE_ID</code> is set for this website.</p>
{% endif %}
{% endblock app_content %}
8 changes: 8 additions & 0 deletions apps/search_page/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.urls import path
from . import views

app_name = 'apps.search_page'

urlpatterns = [
path('', views.SearchPageView, name='search'),
]
64 changes: 64 additions & 0 deletions apps/search_page/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import logging

from django.conf import settings
from django.urls import reverse, NoReverseMatch

from cms.api import create_page as create_cms_page
from cms.models.pagemodel import Page

from .cms_apps import SearchPageApphook


logger = logging.getLogger(f'portal.{__name__}')

TITLE = 'Search'
REVERSE_ID = 'search_page'
DEFAULT_SLUG = settings.PORTAL_SEARCH_PATH.strip('/')

def get_page():
try:
return Page.objects.filter(reverse_id=REVERSE_ID).first()
except Page.DoesNotExist:
return None

def get_slug(page=None):
if page:
return page.get_slug()
else:
page = get_page()
return get_slug(page) if page else DEFAULT_SLUG

def get_page_url():
page = get_page()
if page:
return page.get_absolute_url()
else:
try:
return reverse('apps.search_page:search')
except NoReverseMatch:
return None

def create_page():
page = get_page()
slug = get_slug(page)

if not page:
page = create_cms_page(
title=f'{TITLE} (Auto-Generated)',
menu_title=TITLE,
page_title=TITLE,
reverse_id=REVERSE_ID,
# Use a template from CMS_TEMPLATES setting
template='standard.html',
language='en',
published=True,
slug=slug,
in_navigation=False,
apphook=SearchPageApphook,
apphook_namespace=SearchPageApphook.name,
)
logger.info(f'Created search page "{TITLE}" at "{slug}"')
else:
logger.info(f'Found existing search page at "{slug}"')

return page
4 changes: 4 additions & 0 deletions apps/search_page/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.shortcuts import render

def SearchPageView(request):
return render(request, 'search_page.html')
8 changes: 6 additions & 2 deletions taccsite_cms/_settings/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
########################

# To support any search
PORTAL_SEARCH_PATH = '/search'
PORTAL_SEARCH_PATH = '/search/'

# To support Google search
# PORTAL_SEARCH_QUERY_PARAM_NAME = 'q'
# PORTAL_SEARCH_INDEX_IS_AUTOMATIC = False
GOOGLE_SEARCH_ENGINE_ID = ''

# (DEPRECATED) To support Elasticsearch
PORTAL_SEARCH_QUERY_PARAM_NAME = 'query_string'
PORTAL_SEARCH_INDEX_IS_AUTOMATIC = True

SEARCH_PAGE_AUTO_SETUP = True

ES_AUTH = 'username:password'
ES_HOSTS = 'http://elasticsearch:9200'
ES_INDEX_PREFIX = 'cms-dev-{}'
Expand All @@ -34,5 +37,6 @@
ALDRYN_SEARCH_REGISTER_APPHOOK = True

_INSTALLED_APPS = [
'haystack', # search index
'haystack', # ElasticSearch
# 'search_page' # Google Search
]
2 changes: 2 additions & 0 deletions taccsite_cms/settings/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ def gettext(s): return s
# core TACC CMS
# HELP: If this were top of list, would TACC/Core-CMS/pull/169 fix break?
'taccsite_cms',
'apps.search_page',
'common_apps.email_management',

# django CMS Bootstrap
Expand Down Expand Up @@ -762,4 +763,5 @@ def get_subdirs_as_module_names(path):
'PORTAL_SOCIAL_SHARE_PLATFORMS',
'PORTAL_SEARCH_PATH',
'PORTAL_SEARCH_QUERY_PARAM_NAME',
'GOOGLE_SEARCH_ENGINE_ID',
]
5 changes: 3 additions & 2 deletions taccsite_cms/settings/settings_custom.example.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,11 @@
########################

# To support Google search
PORTAL_SEARCH_PATH = '/search/'
PORTAL_SEARCH_QUERY_PARAM_NAME = 'q'

# To disable Elasticsearch
PORTAL_SEARCH_INDEX_IS_AUTOMATIC = False
SEARCH_PAGE_AUTO_SETUP = True
GOOGLE_SEARCH_ENGINE_ID = ''

########################
# DJANGOCMS_BLOG
Expand Down
4 changes: 2 additions & 2 deletions taccsite_cms/templates/nav_search.raw.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{# @var settings #}

{% load static %}
{% 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. -->

Expand All @@ -10,7 +10,7 @@
</style>
<link rel="stylesheet" href="{% static 'site_cms/css/build/element.tacc-search-bar.css' %}">

<form part="form" method="get" action="{{ settings.PORTAL_SEARCH_PATH }}">
<form part="form" method="get" action="{% search_page_url %}">
<label for="header-search" class="u-hide--visually" part="label">
Search
</label>
Expand Down
10 changes: 10 additions & 0 deletions taccsite_cms/templatetags/search_tags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django import template
from cms.models import Page
from django.conf import settings
from apps.search_page.utils import get_page_url

register = template.Library()

@register.simple_tag
def search_page_url():
return get_page_url() or settings.PORTAL_SEARCH_PATH
1 change: 1 addition & 0 deletions taccsite_cms/urls_custom.example.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
custom_urls = [
# CUSTOM APP
re_path(r'^custom_test/', include('apps.custom_example.urls', namespace='custom_test')),

# DJANGOCMS_BLOG
re_path(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')),
]