Guides answer the search box, and proofing catches what spellcheck cannot
A guide was invisible to global search. Core search has a hardcoded block per domain rather than a hook, so a new plugin stays unreachable until someone adds one - which is the same shape as the gap this test file already documents for USB devices and printed parts: records with a list page, labels in the world, and no way to find them from the search box. Guides are searched by title, summary, tags AND body. The body matters more here than elsewhere: people look for a procedure by something written halfway down it, not by a title they never read. PUBLISHED ONLY - a draft is deliberately invisible to readers, and search is exactly where that rule leaks if nobody writes it down. The test proves it with a draft sharing a tag and a body word with a published guide, so a missing filter would show up as a ride-along. PROOFING catches what a spellchecker cannot, because none of these are spelling: a smart quote in a command so it will not run, a checklist item with no text so a step is silently missing, a heading left with nothing under it after a reorganise, an image with no alt text, a TODO published by accident. Warnings, never blocks - somebody publishing at 14:40 with one empty bullet should be told, not stopped, and a procedure that exists imperfectly beats one nobody wrote. The smart-character issue reports once per block with a one-click fix, rather than once per offending character: an opening and a closing quote are one problem, and listing both makes the panel look like it is nagging. The character table itself is written as escapes. The style gate forbids non-ASCII in source, and a file whose job is detecting smart quotes cannot contain any - which the gate caught, correctly.
This commit is contained in:
@@ -255,6 +255,55 @@ def _search_applications(query, search_term):
|
||||
return results
|
||||
|
||||
|
||||
def _search_guides(query, search_term):
|
||||
"""Search guides by title, summary, tags and BODY.
|
||||
|
||||
The body matters more here than in most domains. People look for a procedure
|
||||
by something written halfway down it - "the one about the drive letter" -
|
||||
not by a title they never read. The body is a JSON blob of blocks, so this
|
||||
is a LIKE against it: crude, but it finds the guide, and a guide corpus is
|
||||
tens of documents rather than millions of rows.
|
||||
|
||||
PUBLISHED ONLY. A draft is deliberately invisible to readers, and search is
|
||||
the one place that rule would otherwise leak - somebody would find a
|
||||
half-written procedure through the search box and follow it.
|
||||
"""
|
||||
results = []
|
||||
try:
|
||||
_require_enabled('guides')
|
||||
from plugins.guides.models import Guide
|
||||
|
||||
rows = Guide.query.filter(
|
||||
Guide.isactive == True,
|
||||
Guide.publishedrevisionid.isnot(None),
|
||||
_word_match(query, Guide.title, Guide.summary, Guide.tags,
|
||||
Guide.blocksjson)
|
||||
).order_by(Guide.modifieddate.desc()).limit(20).all()
|
||||
|
||||
for guide in rows:
|
||||
# A title match outranks a body match: someone searching "marker"
|
||||
# wants the guide called that, not every guide mentioning one.
|
||||
relevance = 10
|
||||
if query.lower() in (guide.title or '').lower():
|
||||
relevance += 20
|
||||
if guide.tags and query.lower() in guide.tags.lower():
|
||||
relevance += 15
|
||||
|
||||
results.append({
|
||||
'type': 'guide',
|
||||
'id': guide.guideid,
|
||||
'title': guide.title,
|
||||
'subtitle': guide.summary,
|
||||
'url': f"/guides/{guide.slug}",
|
||||
'relevance': relevance
|
||||
})
|
||||
except ImportError:
|
||||
pass # guides plugin absent or disabled
|
||||
except Exception as e:
|
||||
logger.error(f"Guides search failed: {e}")
|
||||
return results
|
||||
|
||||
|
||||
def _search_knowledgebase(query, search_term):
|
||||
"""Search Knowledge Base by description and keywords.
|
||||
|
||||
@@ -1148,6 +1197,7 @@ def global_search():
|
||||
# Run all search domains
|
||||
results.extend(_search_applications(query, search_term))
|
||||
results.extend(_search_knowledgebase(query, search_term))
|
||||
results.extend(_search_guides(query, search_term))
|
||||
results.extend(_search_employees(query, search_term))
|
||||
results.extend(_search_assets(query, search_term))
|
||||
results.extend(_search_measuringtools(query, search_term))
|
||||
|
||||
Reference in New Issue
Block a user