Compare commits

..

No commits in common. "653847df6a55fc03a0108d00bb930ebf81db9982" and "d75ea17b32e4d46334ea74abf7d05e772b78c9f2" have entirely different histories.

8 changed files with 59 additions and 166 deletions

View File

@ -7,7 +7,6 @@ from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from modelcluster.contrib.taggit import ClusterTaggableManager
from modelcluster.fields import ParentalKey
from taggit.models import TaggedItemBase
from wagtail.search import index
def _get_env_int(name, default):
value = os.environ.get(name)
@ -273,12 +272,6 @@ class ArticlePage(Page):
trending = models.BooleanField("Trending", default=False, help_text="在熱門區塊顯示")
tags = ClusterTaggableManager(through="home.ArticlePageTag", blank=True)
search_fields = Page.search_fields + [
index.SearchField("intro", partial_match=True),
index.SearchField("body_search_text", partial_match=True),
index.SearchField("tag_names_search_text", partial_match=True),
]
content_panels = Page.content_panels + [
FieldPanel("trending"),
FieldPanel("cover_image"),
@ -306,25 +299,3 @@ class ArticlePage(Page):
context["related_articles"] = related_articles
return context
@property
def body_search_text(self):
if not self.body:
return ""
excluded_types = {"image", "embed", "hr", "html"}
chunks = []
for block in self.body:
if block.block_type in excluded_types:
continue
# Each block decides how to expose searchable text
block_content = block.block.get_searchable_content(block.value)
if block_content:
chunks.extend(block_content)
return " ".join(text for text in chunks if isinstance(text, str))
@property
def tag_names_search_text(self):
return " ".join(self.tags.values_list("name", flat=True))

View File

@ -19,7 +19,7 @@
<span>Hashtags:</span>
<ul>
{% for tag in tags %}
<li><a href="{% url 'hashtag_search' tag.slug %}">#{{ tag }}</a></li>
<li>#{{ tag }}</li>
{% endfor %}
</ul>
</div>

View File

@ -1,19 +0,0 @@
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% block content %}
<nav class="breadcrumbs" aria-label="breadcrumb">
<ol>
<li>
{% if site_root %}
<a href="{{ site_root.url }}">首頁</a>
{% else %}
<a href="/">首頁</a>
{% endif %}
</li>
<li><span>標籤</span></li>
<li><span>#{{ tag.name }}</span></li>
</ol>
</nav>
{% include "home/includes/page-article-list.html" %}
{% endblock %}

View File

@ -1,44 +0,0 @@
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.shortcuts import get_object_or_404, render
from taggit.models import Tag
from wagtail.models import Site
from .models import ArticlePage, PAGE_SIZE
def hashtag_search(request, slug):
tag = get_object_or_404(Tag, slug=slug)
articles = (
ArticlePage.objects.live()
.filter(tags__slug=slug)
.order_by("-date")
)
paginator = Paginator(articles, PAGE_SIZE)
page_number = request.GET.get("page")
try:
page_obj = paginator.page(page_number)
except PageNotAnInteger:
page_obj = paginator.page(1)
except EmptyPage:
page_obj = paginator.page(paginator.num_pages)
site = Site.find_for_request(request)
site_root = site.root_page if site else None
context = {
"tag": tag,
"category_sections": [
{
"title": f"#{tag.name}",
"items": page_obj,
"url": request.path,
}
],
"site_root": site_root,
"page": site_root.specific if site_root else None,
}
return render(request, "home/hashtag_page.html", context)

View File

@ -56,15 +56,5 @@
{% endif %}
</ul>
</nav>
<form class="header-search" action="{% url 'search' %}" method="get" role="search">
<input
type="search"
name="query"
placeholder="搜尋文章"
value="{{ request.GET.query|default:'' }}"
aria-label="搜尋文章">
<button type="submit">搜尋</button>
</form>
</div>
</header>

View File

@ -7,14 +7,11 @@ from wagtail import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
from search import views as search_views
from home import views as home_views
urlpatterns = [
path("django-admin/", admin.site.urls),
path("admin/", include(wagtailadmin_urls)),
path("documents/", include(wagtaildocs_urls)),
# use <str:slug> so Unicode tag slugs (e.g. 台北美食) still resolve
path("tags/<str:slug>/", home_views.hashtag_search, name="hashtag_search"),
path("search/", search_views.search, name="search"),
]

View File

@ -1,38 +1,38 @@
{% extends "base.html" %}
{% load wagtailcore_tags %}
{% load static wagtailcore_tags %}
{% block body_class %}template-searchresults{% endblock %}
{% block title %}
{% if search_query %}搜尋:{{ search_query }}{% else %}搜尋{% endif %}
{% endblock %}
{% block title %}Search{% endblock %}
{% block content %}
<nav class="breadcrumbs" aria-label="breadcrumb">
<ol>
<h1>Search</h1>
<form action="{% url 'search' %}" method="get">
<input type="text" name="query"{% if search_query %} value="{{ search_query }}"{% endif %}>
<input type="submit" value="Search" class="button">
</form>
{% if search_results %}
<ul>
{% for result in search_results %}
<li>
{% if site_root %}
<a href="{{ site_root.url }}">首頁</a>
{% else %}
<a href="/">首頁</a>
<h4><a href="{% pageurl result %}">{{ result }}</a></h4>
{% if result.search_description %}
{{ result.search_description }}
{% endif %}
</li>
<li><span>搜尋</span></li>
{% if search_query %}
<li><span>{{ search_query }}</span></li>
{% endif %}
</ol>
</nav>
{% endfor %}
</ul>
<section class="search-results">
{% if search_query %}
{% if results_count %}
{% include "home/includes/page-article-list.html" %}
{% else %}
<p>找不到與「{{ search_query }}」相關的文章。</p>
{% endif %}
{% else %}
<p>請輸入關鍵字後再進行搜尋。</p>
{% endif %}
</section>
{% if search_results.has_previous %}
<a href="{% url 'search' %}?query={{ search_query|urlencode }}&amp;page={{ search_results.previous_page_number }}">Previous</a>
{% endif %}
{% if search_results.has_next %}
<a href="{% url 'search' %}?query={{ search_query|urlencode }}&amp;page={{ search_results.next_page_number }}">Next</a>
{% endif %}
{% elif search_query %}
No results found
{% endif %}
{% endblock %}

View File

@ -1,48 +1,46 @@
from urllib.parse import urlencode
from django.core.paginator import Paginator
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.template.response import TemplateResponse
from wagtail.models import Site
from wagtail.models import Page
from home.models import ArticlePage, PAGE_SIZE
# To enable logging of search queries for use with the "Promoted search results" module
# <https://docs.wagtail.org/en/stable/reference/contrib/searchpromotions.html>
# uncomment the following line and the lines indicated in the search function
# (after adding wagtail.contrib.search_promotions to INSTALLED_APPS):
# from wagtail.contrib.search_promotions.models import Query
def search(request):
search_query = (request.GET.get("query") or "").strip()
page_number = request.GET.get("page", 1)
category_sections = []
results_page = None
results_count = 0
search_query = request.GET.get("query", None)
page = request.GET.get("page", 1)
# Search
if search_query:
search_queryset = ArticlePage.objects.live().search(search_query)
paginator = Paginator(search_queryset, PAGE_SIZE)
results_page = paginator.get_page(page_number)
results_count = paginator.count
search_results = Page.objects.live().search(search_query)
if results_count:
query_string = urlencode({"query": search_query})
category_sections = [
{
"title": f"搜尋:{search_query}",
"items": results_page,
"url": f"{request.path}?{query_string}",
}
]
# To log this query for use with the "Promoted search results" module:
site = Site.find_for_request(request)
site_root = site.root_page if site else None
# query = Query.get(search_query)
# query.add_hit()
else:
search_results = Page.objects.none()
# Pagination
paginator = Paginator(search_results, 10)
try:
search_results = paginator.page(page)
except PageNotAnInteger:
search_results = paginator.page(1)
except EmptyPage:
search_results = paginator.page(paginator.num_pages)
return TemplateResponse(
request,
"search/search.html",
{
"search_query": search_query,
"category_sections": category_sections,
"results_page": results_page,
"results_count": results_count,
"site_root": site_root,
"page": site_root.specific if site_root else None,
"search_results": search_results,
},
)