Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions docs/userGuide/syntax/cardstacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Each `card` contains `tag` and `keyword` field:

<box type="info">

The search feature searches the `card` components of `cardstack` by header, tags and keywords specified within each card component.
The search feature searches the `card` components of `cardstack` by header, body text, tags, and keywords specified within each card component.

Specifying them can help improve searchability of the `cardstack` component!

Expand Down Expand Up @@ -60,7 +60,7 @@ For example, if a card is about "Machine Learning," you might tag it as `AI` and
As shown in the above example,
- a `card` can be given a `header` attribute (optional).
- tags can be added to cards using the `tag` attribute, which can then be used to filter cards.
- the `searchable` attribute can be used to make the Card Stack searchable based on tags and headers.
- the `searchable` attribute can be used to make the Card Stack searchable based on card content, tags, and headers.

In the example given below, a Card Stack is used to show a list of questions and answers, by including `question` components inside `card` components.

Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/Page/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ export class Page {
* https://markbind.org/userGuide/makingTheSiteSearchable.html#keywords
*/
this.keywords = {};
/**
* Normalized page body text used for search indexing.
*/
this.body = '';
/**
* The title of the page.
* This is initially set to the title specified in the site configuration,
Expand Down Expand Up @@ -291,6 +295,13 @@ export class Page {
*/
collectHeadingsAndKeywords(pageContent: string) {
this.collectHeadingsAndKeywordsInContent(pageContent, null, false, []);
this.collectBodyText(pageContent);
}

collectBodyText(content: string) {
const $ = cheerio.load(content);
$('modal, panel, script, style, noscript').remove();
this.body = $.root().text().replace(/\s+/g, ' ').trim();
}

/**
Expand Down
7 changes: 5 additions & 2 deletions packages/vue-components/src/cardstack/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<slot name="header"></slot>
</h6>
</div>
<div class="card-text">
<div ref="content" class="card-text">
<slot></slot>
</div>
<br />
Expand Down Expand Up @@ -61,6 +61,7 @@ export default {
exposedTags: [],
headerText: '',
hasHeader: true,
bodyText: '',
cardStack: null,
};
},
Expand Down Expand Up @@ -125,7 +126,8 @@ export default {
const matchesTags = this.computeTags.some(tag => selectedTags.includes(tag));

// Check if the card mateches the search terms
const searchTarget = (this.computeTags.join(' ') + this.keywords + this.headerText).toLowerCase();
const searchTarget = (this.computeTags.join(' ')
+ this.keywords + this.headerText + this.bodyText).toLowerCase();
const matchesSearch = searchTerms.length === 0
|| searchTerms.every(term => searchTarget.toLowerCase().includes(term.toLowerCase()));

Expand All @@ -141,6 +143,7 @@ export default {
this.isMounted = true;
this.headerText = this.computeHeaders;
this.hasHeader = this.headerText !== '';
this.bodyText = this.$refs.content?.innerText || '';

this.cardStack.updateRawTags(this.computeTags);
this.cardStack.updateTagMapping();
Expand Down
5 changes: 3 additions & 2 deletions packages/vue-components/src/cardstack/CardStack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ function createCardStackRef(props) {
const rawTags = child.computeTags;
const keywords = child.computeKeywords;
const header = child.headerText;
const searchTarget = rawTags.join(' ') + keywords + header;
const body = child.bodyText || '';
const searchTarget = rawTags.join(' ') + keywords + header + body;

primitiveMap.set(searchTarget, child);
});
Expand Down Expand Up @@ -186,7 +187,7 @@ export default {
if (child.disabled) return;
const searchTerms = this.cardStackRef.searchTerms || [];
const searchTarget = (child.computeTags.join(' ')
+ child.keywords + child.headerText).toLowerCase();
+ child.keywords + child.headerText + (child.bodyText || '')).toLowerCase();
const matchesSearch = searchTerms.length === 0
|| searchTerms.every(term => searchTarget.includes(term.toLowerCase()));
if (matchesSearch) {
Expand Down
Loading