Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formating ais-highlight attribute with markdown content #597

Open
adhamfarrag opened this issue Nov 11, 2021 · 6 comments
Open

Formating ais-highlight attribute with markdown content #597

adhamfarrag opened this issue Nov 11, 2021 · 6 comments
Labels
needs investigation Needs to take more time to understand the issue

Comments

@adhamfarrag
Copy link

Description
Using Strapi, strapi-meilisearch-plugin and instant-meilisearch here.

Trying to render results from a search bar, typical article model (title, body, etc). And as strapi uses markdown, results come back with markdown syntanx. Tried to modify ais-highlight to render article body using markdown-it.

Is there anyway around my problem ?

 <ais-highlight
        attribute="body"
        :hit="hit"
        class="block text-xs font-medium  text-primary line-clamp-3"
   >

 <ais-highlight
        :attribute="$md.render(body)"
        :hit="hit"
        class="block text-xs font-medium  text-primary line-clamp-3"
      >

Expected behavior
I expected it to allow me to render readable markdown content.

Current behavior
I get Input data should be a String error.

Screenshots or Logs

Screen Shot 2021-11-12 at 12 47 37 AM

Environment (please complete the following information):

  • OS: macOS 11.6
  • Browser: Brave V1.31.91
  • MeiliSearch version: Latest
  • instant-meilisearch version: ^0.5.9
  • instantsearch.js version: vue-instantsearch ^4.1.1
@adhamfarrag adhamfarrag changed the title Formating markdown attribute Formating ais-highlight attribute with markdown content Nov 11, 2021
@bidoubiwa
Copy link
Contributor

Hey @adhamfarrag
Could you show me one of the documents in MeiliSearch? So I can try it out and debug!

@adhamfarrag
Copy link
Author

Hey @bidoubiwa Thanks for checking this out.

{
  "id": 2,
  "title": "Demo Article in second section",
  "slug": "demo-article-in-second-section",
  "body": "Yes. New [link](https://www.google.com/) Culpa aperiam accusamus consectetur rerum. Omnis esse officia aperiam reiciendis laudantium. Iste dolor nulla incidunt. Atque tempore ipsum itaque. Earum molestiae impedit nobis ex itaque accusamus. Maxime cum quae. Ut repellendus modi in officia. Aut tempora error iusto et maiores id blanditiis voluptatem. Eum et tenetur autem fugiat repudiandae sed nihil illo. Eveniet alias et qui omnis odio pariatur voluptatem corrupti ratione. Dolores nisi libero. Alias et tempore maiores odio. Illum sed odit corporis enim dolore laudantium non.",
  "Author": {
    "id": 4,
    "username": "adhamfarrag",
    "email": "[email protected]",
    "provider": "local",
    "confirmed": true,
    "blocked": false,
    "role": 1,
    "created_at": "2021-10-26T14:25:35.086Z",
    "updated_at": "2021-11-04T14:39:33.937Z",
    "Rank": "Owner",
    "firstName": "Adham",
    "lastName": "Farrag"
  },
  "section": {
    "id": 2,
    "title": "X second section",
    "slug": "x-second-section",
    "published_at": "2021-10-27T19:29:29.032Z",
    "created_at": "2021-10-27T19:29:02.724Z",
    "updated_at": "2021-11-02T18:32:21.336Z",
    "organization": 4,
    "description": null
  },
  "published_at": "2021-10-27T19:29:24.345Z",
  "created_at": "2021-10-27T16:07:10.382Z",
  "updated_at": "2021-11-01T18:51:02.503Z",
  "Attachments": []
}

It's and index for articles and this is a single article. Is this is what you're asking for ?

@bidoubiwa
Copy link
Contributor

Yes thanks you :) Could you also provide your whole instant-search component?

@adhamfarrag
Copy link
Author

Here you are :)


<template>
  <div>
    <ais-instant-search
      :index-name="selectedIndex"
      :search-client="searchClient"
    >
      <ais-configure
        :attributesToSnippet="['bodyPlainText']"
        :htos-per-page.camel="5"
      >
        <ais-autocomplete>
          <div slot-scope="{ currentRefinement, indices, refine }">
            <div class="group">
              <div
                class="relative flex items-center w-full h-12 duration-200 bg-white border-2 rounded-lg  group-focus-within:border-accent border-shade"
              >
                <IconSearch
                  class="absolute left-0 w-5 h-5 ml-5 text-gray-400 fill-current  group-focus-within:text-accent"
                />
                <input
                  type="search"
                  ref="searchInput"
                  class="w-full ml-12 mr-5 outline-none  ring-0 focus:border-accent border-shade focus:outline-none focus:ring-0"
                  placeholder="Search"
                  :value="currentRefinement"
                  @input="refine($event.currentTarget.value)"
                  autocomplete="off"
                />

                <div class="absolute right-0 flex flex-row">
                  <span
                    v-if="!currentRefinement"
                    class="py-1 pr-5 text-gray-400  group-focus-within:text-accent md:inline-block"
                  >
                    /
                  </span>
                </div>
              </div>
            </div>

            <div
              v-show="currentRefinement.length"
              class="absolute z-10 w-screen max-w-lg px-2 mt-3 transform  sm:px-0"
            >
              <div
                class="overflow-hidden rounded-lg shadow-lg  ring-1 ring-black ring-opacity-5"
              >
                <div
                  v-if="currentRefinement"
                  class="relative flex flex-col px-5 py-6 bg-white  text-primary sm:gap-8 sm:p-8"
                >
                  <div
                    v-for="section in indices"
                    :key="section.ObjectID"
                    class="divide-y divide-accent"
                  >
                    <nuxt-link
                      :to="
                        selectedIndex == 'article'
                          ? `/organization/${$strapi.user.organizations[0].slug}/section/${hit.section.slug}/article/${hit.slug}`
                          : `/organization/${$strapi.user.organizations[0].slug}/dailyUpdate/${hit.slug}/`
                      "
                      v-for="(hit, index) in section.hits"
                      :key="index"
                      class="py-2 text-sm transition ease-in-out duration 200"
                    >
                      <div
                        v-if="
                          hit.section.organization ==
                          $strapi.user.organizations[0].id
                        "
                        class="w-full px-2 py-3"
                      >
                        <ais-highlight
                          attribute="title"
                          :hit="hit"
                          class="block text-lg font-medium text-accent"
                        />

                        <ais-highlight
                          attribute="body"
                          :hit="hit"
                          class="block text-xs line-clamp-2 text-primary"
                        />
                      </div>
                    </nuxt-link>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </ais-autocomplete>
      </ais-configure>
    </ais-instant-search>

    <div class="flex flex-row mt-4 space-x-2">
      <div v-for="index in indexes" :key="index.id">
        <span
          @click="updateIndex(index.indexName)"
          :class="
            selectedIndex == index.indexName
              ? ' bg-accent text-white border-accent '
              : 'border-shade text-primary  '
          "
          class="
            px-2
            py-1.5
            text-xs
            duration-200
            transform
            border-2
            rounded-lg
            cursor-pointer
          "
        >
          {{ index.label }}
        </span>
      </div>
    </div>
  </div>
</template>

<script>
import { instantMeiliSearch } from '@meilisearch/instant-meilisearch'

export default {
  data() {
    return {
      searchClient: instantMeiliSearch(
        'url',
        'key'
      ),
      selectedIndex: 'article',
      indexes: [
        {
          label: 'Articles',
          indexName: 'article',
        },
        {
          label: 'Daily Updates',
          indexName: 'daily-update',
        },
      ],
    }
  },
  methods: {
    searchFocusListener(event) {
      if (event.keyCode === 47 && !(event.target instanceof HTMLInputElement)) {
        event.preventDefault()
        this.focusSearchInput()
      }
    },
    focusSearchInput() {
      this.$refs.searchInput.focus()
    },
    updateIndex(index) {
      this.selectedIndex = index
    },
  },
  beforeMount() {
    window.addEventListener('keypress', this.searchFocusListener)
  },
  beforeDestroy() {
    window.removeEventListener('keypress', this.searchFocusListener)
  },
}
</script>


@adhamfarrag
Copy link
Author

Hi @bidoubiwa! I tried using marked.js to generate plain text. Worked inside terminal but gave me the same error with ais-highlight component. Tried using span tag and it worked. I guess the problem is with binding attribute and strict checking of content type.

const marked = require('marked').marked
const PlainTextRenderer = require('marked-plaintext')
const renderer = new PlainTextRenderer()

function convertToPlainText(content) {
  return marked(content, { renderer: renderer })
}

export { convertToPlainText }

@bidoubiwa
Copy link
Contributor

Hey @adhamfarrag I will be looking into your bug as soon as I have time. We are very busy for the moment. I'll get back to you asap

@bidoubiwa bidoubiwa added the needs investigation Needs to take more time to understand the issue label Mar 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs investigation Needs to take more time to understand the issue
Projects
None yet
Development

No branches or pull requests

3 participants