All Projects → HauntedThemes → Ghost Search

HauntedThemes / Ghost Search

A simple but powerful search library for Ghost Blogging Platform.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Ghost Search

Ghost Theme Template
A project scaffold for building ghost themes using gulp, node-sass, & autoprefixer
Stars: ✭ 91 (-12.5%)
Mutual labels:  ghost
Compose
A Hugo theme for documentation sites. It's inspired by https://forestry.io/docs/welcome/
Stars: ✭ 95 (-8.65%)
Mutual labels:  search
Ghost Theme Moegi
An elegant & fresh ghost theme.
Stars: ✭ 101 (-2.88%)
Mutual labels:  ghost
Monster
The Art of Template MetaProgramming (TMP) in Modern C++♦️
Stars: ✭ 90 (-13.46%)
Mutual labels:  search
React Instantsearch
⚡️ Lightning-fast search for React and React Native applications, by Algolia.
Stars: ✭ 1,320 (+1169.23%)
Mutual labels:  search
Farbox Theme Anatole
This theme is desiged for FarBox,You can use it directly or modified it on FarBox
Stars: ✭ 99 (-4.81%)
Mutual labels:  ghost
Applied Ml
📚 Papers & tech blogs by companies sharing their work on data science & machine learning in production.
Stars: ✭ 17,824 (+17038.46%)
Mutual labels:  search
Cloudboost
Realtime JavaScript Backend.
Stars: ✭ 1,378 (+1225%)
Mutual labels:  search
Mongoose Fuzzy Searching
Mongoose Fuzzy Searching Plugin
Stars: ✭ 94 (-9.62%)
Mutual labels:  search
Node Sonic Channel
🦉 Sonic Channel integration for Node. Used in pair with Sonic, the fast, lightweight and schema-less search backend.
Stars: ✭ 101 (-2.88%)
Mutual labels:  search
Algoliasearch Client Android
Algolia Search API Client for Android
Stars: ✭ 92 (-11.54%)
Mutual labels:  search
Rxsuggestions
⌨️ RxJava library to fetch suggestions for keywords using Google Suggest API
Stars: ✭ 93 (-10.58%)
Mutual labels:  search
Javascript
A repository for All algorithms implemented in Javascript (for educational purposes only)
Stars: ✭ 16,117 (+15397.12%)
Mutual labels:  search
Searchwp Live Ajax Search
[WordPress Plugin] Enhance your search forms with live search (utilizes SearchWP if installed)
Stars: ✭ 91 (-12.5%)
Mutual labels:  search
Search
PHP search-systems made possible
Stars: ✭ 101 (-2.88%)
Mutual labels:  search
Npmarket
🛒 More efficient search for node packages.
Stars: ✭ 91 (-12.5%)
Mutual labels:  search
Logcatch
android adb logcat viewer for Linux/Mac/Windows
Stars: ✭ 95 (-8.65%)
Mutual labels:  search
Ghost Azure
Production ready Ghost for Azure 👻
Stars: ✭ 103 (-0.96%)
Mutual labels:  ghost
Redux Search
Redux bindings for client-side search
Stars: ✭ 1,377 (+1224.04%)
Mutual labels:  search
Simpleaudioindexer
Searching for the occurrence seconds of words/phrases or arbitrary regex patterns within audio files
Stars: ✭ 100 (-3.85%)
Mutual labels:  search

Min Ghost Version npm version

ghost-search

A simple but powerful search library for Ghost Blogging Platform.

Setup

Step 1 - Setup Content API Client Library

Get the latest version of Ghost Content API Client Library from unpkg.com.

<script src="https://unpkg.com/@tryghost/[email protected]{version}/umd/content-api.min.js"></script>

Add the script before the {{ghost_foot}} tag. This will, most likely, be in default.hbs.

Step 2 - Setup ghost-search

Open your theme directory and navigate to assets subdirectory.
Create a directory called js, if there isn't already one in there, and add the minified version of ghost-search in it.
Open default.hbs that is located at the root of your theme.
At the bottom of this file you should see {{ghost_foot}}.
Add the following code above it (after the content-api script at Step 1) and save it:

<script type="text/javascript" src="{{asset "js/ghost-search.min.js"}}"></script>

Add the following code, in a .hbs file, where you want to show the search input:

<input id="ghost-search-field">

Add the following code, in a .hbs file, where you want to show the search results:

<div id="ghost-search-results"></div>

You will need to initialize ghost-search to make the search functional.
Add the following js code after you included ghost-search.min.js:

<script>
    let ghostSearch = new GhostSearch({
        key: '22444f78447824223cefc48062', // This is just a demo key. Replace the key with a real one. See Step 3.
        url: 'https://demo.ghost.io', // This is just a demo host. Replace the demo url with a real one. See Step 3.
    })
</script>

Step 3 - Setup a Custom integration

Go in your Ghost's dashboard -> Integrations -> Add custom integration
Set a name: Haunted Themes Search
Get the Content API Key and replace the demo key with this one. More details.
Get the admin domain. This will be different in some cases. More details.

Use ghost-search from CDN

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ghost-search.min.js"></script>

npm

npm install ghost-search

Live Examples

Set a basic search
Display a message if there are no posts found
Search only through tags
Search posts from a custom collection
Search posts that are published after 01 Jan 2018
Search through the title and content of posts
Get the results when a button is clicked
Get proper results when your Ghost is on a sub-path
Set multiple instances of ghost-search on the same page
Add a loading icon when you have a lot of posts
Limit the results displayed

Default Options

{
    host: '',
    key: '',
    version: 'v2',
    input: '#ghost-search-field',
    results: '#ghost-search-results',
    button: '',
    development: false,
    defaultValue: '',
    template: function(result) {
        let url = [location.protocol, '//', location.host].join('');
        return '<a href="' + url + '/' + result.slug + '/">' + result.title + '</a>';  
    },
    trigger: 'focus',
    options: {
        keys: [
            'title'
        ],
        limit: 100,
        threshold: -3500,
        allowTypo: false
    },
    api: {
        resource: 'posts',
        parameters: { 
            limit: 'all',
            fields: ['title', 'slug'],
            filter: '',
            include: '',
            order: '',
            formats: '',
        },
    },
    on: {
        beforeDisplay: function(){},
        afterDisplay: function(results){},
        beforeFetch: function(){},
        afterFetch: function(){}
    }
}

Options

url

The url that needs to be set in order for Content API to properly authenticate. More details.

key

The key that needs to be set in order for Content API to properly authenticate. More details.

version

The version that needs to be set in order for Content API to properly authenticate. More details.

Default value: 'v3'

input

The ID of the input field that will be transformed into search filter.
You can set your own id if you want like this:

<input id="my-custom-input">
<script type="text/javascript">
    let ghostSearch = new GhostSearch({
        input: '#my-custom-input'
    })
</script>

Default value: '#ghost-search-field'

results

The ID of the element that will be transformed into search results.
You can set your own id if you want like this:

<div id="my-custom-results"></div>
<script type="text/javascript">
    let ghostSearch = new GhostSearch({
        results: '#my-custom-results'
    })
</script>

Default value: '#ghost-search-results'

button

The ID of the element that will trigger the search results after it's clicked.
By default, the button parameter is empty because ghost-search displays the results when you write in the input.
To make this work you need to add the input and the button in a form element:

<form>
    <input id="my-custom-input">
    <input type="submit" id="my-custom-button">
</form>
<div id="my-custom-results"></div>
<script type="text/javascript">
    let ghostSearch = new GhostSearch({
        input: '#my-custom-input',
        results: '#my-custom-results',
        button: '#my-custom-button'
    })
</script>

Default value: ''

defaultValue

A parameter that will set a default value for the input and performs the search.

<script type="text/javascript">
    let ghostSearch = new GhostSearch({
        defaultValue: 'ghost'
    })
</script>

Default value: ''

template

The template that will be used to render individual items in the search result.
The method has a parameter result that stores all the data that you can use inside the method.

Examples:

Make the results a list and wrap each result with <li>:

<div id="my-custom-input"></div>
<ul id="my-custom-results"></ul>
<script type="text/javascript">
    let ghostSearch = new GhostSearch({
        input: '#my-custom-input',
        results: '#my-custom-results',
        template: function(result) {
            let url = [location.protocol, '//', location.host].join('');
            return '<li><a href="' + url + '/' + result.slug + '">' + result.title + '</a></li>';  
        }
    })
</script>

Set url with sub-path:

<script type="text/javascript">
    let ghostSearch = new GhostSearch({
        input: '#my-custom-input',
        results: '#my-custom-results',
        template: function(result) {
            let url = [location.protocol, '//', location.host].join('') + '/sub-path/';
            return '<a href="' + url + '/' + result.slug + '">' + result.title + '</a>';  
        }
    })
</script>

Default value:

function(result) {
    let url = [location.protocol, '//', location.host].join('');
    return '<a href="' + url + '/' + result.slug + '">' + result.title + '</a>';  
}

trigger

Tells the script when to fetch the collection of data. The default value is focus, that means when a user clicks the input, all the data is fetched.
You can also use load. This will fetch the data when the page loads.

load might create a DDOS effect because it loads all the data every time a page loads. Use carefully.

Default value: 'focus'

options

ghost-search is using fuzzysort as an algorithm for search. The option parameter supports all the options from fuzzysort. By default, ghost-search is showing the first 10 results and searches only based on title.

Let's try another example that will show the first 3 results and searches both title and the content of a collection:

<script type="text/javascript">
    let ghostSearch = new GhostSearch({
        options: {
            keys: [
                'title',
                'plaintext'
            ],
            limit: 3,
        },
        api: {
            resource: 'posts',
            parameters: { 
                fields: ['title', 'slug', 'plaintext'],
                formats: 'plaintext',
            },
        },
    })
</script>

Default value:

{
    keys: [
        'title'
    ],
    limit: 10,
    threshold: -3500,
    allowTypo: false
}

api

The api parameter is an object that supports most of the resources and parameters by Content API.

Resources: posts, tags, authors
Parameters: fields, filter, include, order, formats, limit

Examples:

Search through tags:

<script type="text/javascript">
    let ghostSearch = new GhostSearch({
        options: {
            keys: [
                'name',
            ],
        },
        api: {
            resource: 'tags',
            parameters: { 
                fields: ['name', 'slug'],
            },
        },
        template: function(result) {
            let url = [location.protocol, '//', location.host].join('') + '/tag';
            return '<a href="' + url + '/' + result.slug + '/">' + result.name + '</a>';  
        },
    })
</script>

Search through a custom collection:

Let's say we have a routes.yaml like this:

routes:

collections:
  /themes/:
    permalink: /themes/{slug}/
    filter: tag:themes
    data: tag.themes
  /:
    permalink: /{slug}/
    filter: tag:-themes
    template:
      - index

taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

/themes/ is a collection that will show posts with tag themes. A post like this will have the url example.com/themes/post-slug.

Our ghost-search will become:

let ghostSearch = new GhostSearch({
    options: {
        keys: [
            'title',
        ],
    },
    api: {
        resource: 'posts',
        parameters: { 
            fields: ['title', 'slug'],
            filter: 'tags:[themes]',
            include: 'tags'
        },
    },
    template: function(result) {
        let collection = 'themes';
        let url = [location.protocol, '//', location.host].join('') + '/' + collection;
        return '<a href="' + url + '/' + result.slug + '/">' + result.title + '</a>';  
    },
})

on

This parameter has 4 methods in it: beforeDisplay, afterDisplay, beforeFetch, afterFetch.
afterDisplay and afterFetch have a parameter results that contains the results fetched.
They are useful to do things before results are visible to users.

Example:

let ghostSearch = new GhostSearch({
    on: {
        beforeFetch: function(){
            // Create a div that has a spinning icon
            console.log('Loading appears');
        },
        afterFetch: function(results){
            // Remove the spinning icon
            console.log('Loading disappears');
        }
    }
})

Contributing

All changes should be committed to src/ files only.

Known Issues

  • DDOS effect when trigger is set to load. If you have a lot of posts and set trigger to load you might get a DDOS effect because you are loading all the post everything a page loads. It would be better to just set trigger to focus.

Changelog

1.1.0 - 15 Nov 2019

  • Migrated to Ghost v3

1.0.1 - 28 Jan 2019

  • Editable limit parameter. 5

1.0.0 - 21 Jan 2019

  • Public API (deprecated) will not work anymore. The library is accessing Content API.

0.1.1 - 29 Nov 2018

  • Added defaultValue parameter.

0.1.0 - 17 Sep 2018

  • Initial release

Thank You

ghost-search is using as a search algorithm fuzzysort.
Thank you farzher for creating fuzzysort, a simple and usable search library.

Copyright & License

Copyright (c) 2019 Haunted Themes - Released under the MIT license.
Ghost is a trademark of The Ghost Foundation

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].