Ghost博客搜索功能

Ghost博客搜索功能

05 三月 2019 设计 分享

昨天下午闲来无事去Ghost的主题市场逛了圈,本来想着看看能不能找个好点的文字主题扒来用,无意间看到了https://purus.golem.io 这个主题对于Ghost搜索功能的实现,作者采用采用的推特的typeahead.js 实现了Ghost博客系统里的搜索功能,不同于之间我某篇文章里提到的ghostHunter,只能对Rss里的文章进行搜索。

作者的做法是直接预读取所有文章的title+slug,然后配合Bloodhound 做数据分析(不知道能不能加全文搜索,有懂的大佬后续研究完可以交流一下)。不知道这样会不会影响网站加载效率,不知道有没有数据缓存的功能,英文苦手就不去研究了。

手册说的不清楚我也看不懂,不怎么好diy,索性就直接把他的所有代码全部拿来用了,基本上没啥变动,各位根据自己博客的情况自行修改吧...。(能力有限,不提供后续解答,任何问题请自行解决)

先引入typeahead库,这个貌似要搭配jquery哈,注意引入顺序

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js&#10;"></script>

在后的head code里添加

<script>
            //Wait for other things to be loaded so the site doesn't wait on the search
            $(document).ready(function() {
                //Go grab all the posts on the blog, but only the slug and title fields
                //That helps limit the amount of data sent and stored locally
                $.get(ghost.url.api('posts', {limit: "all", fields: "slug,title"})).done(function(data) {
                    //add all the data returned to a variable
                    var searchData = data.posts; 

                    //New bloodhound to make it searchable
                    var search = new Bloodhound({
                      datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title'),
                      queryTokenizer: Bloodhound.tokenizers.whitespace,
                      local: searchData
                    });

                    //Build the typeahead
                    $('#site-search .typeahead').typeahead(null, {
                          name: 'search',
                          //source is the bloodhound variable
                          source: search,
                          templates: {
                            empty: [
                                '<div class="empty-message">',
                                'unable to find any post that match the current query',
                                '</div>'
                            ].join('\n'),
                            suggestion: function(data) {
                                return '<a href="/' + data.slug + '"><h2>' + data.title + '</h2></a>';
                            }
                        }
                    }); 

                    //Now show the search bar since getting data was successful
                    $('#site-search').show();
                }).fail(function() {
                    //If the get request errors out, put an error in the console
                    console.log("Error getting Ghost API Data");
                });
            });
        </script>

添加模版代码

            <div id="site-search" style="background-image: url(&quot;/assets/img/search.png?v=8efd075636&quot;);">
                <!--Hide this until getting data is successful-->
                <span class="twitter-typeahead" style="position: relative; display: inline-block;">
                    <input class="typeahead tt-hint" type="text" readonly="" autocomplete="off" spellcheck="false" tabindex="-1" dir="ltr"
                        style="position: absolute; top: 0px; left: 0px; border-color: transparent; box-shadow: none; opacity: 1; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255);">
                    <input id="search-field" class="typeahead tt-input" type="text" placeholder="Search" autocomplete="off" spellcheck="false"
                        dir="auto" style="position: relative; vertical-align: top; background-color: transparent;">
                    <pre aria-hidden="true" style="position: absolute; visibility: hidden; white-space: pre; font-family: &quot;Open Sans&quot;, sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 300; word-spacing: 0px; letter-spacing: 0px; text-indent: 0px; text-rendering: auto; text-transform: none;"></pre>
                    <div class="tt-menu" style="position: absolute; top: 100%; left: 0px; z-index: 100; display: none;">
                        <div class="tt-dataset tt-dataset-search"></div>
                    </div>
                    <button type="button" class="-search-reset" title="Close">×</button>
                </span>
                
            </div>

再添加css

/* Search results */
#site-search .tt-menu {
    display: block !important;
    margin: 4rem auto;
    padding: 1rem 0;
    width: 100%;
    color: #999;
    font-family: 'Open Sans', sans-serif;
    font-size: 1.4rem;
    text-transform: uppercase;
    letter-spacing: 0.02rem;
    text-align: center;
}

#site-search .tt-menu a {
    display: block;
    width: 100%;
    max-height: 90px;
    text-align: center;
    background: #f0f0f0;
    border-radius: 20px;
    margin: 2rem 0;
    color: #333;
    padding: 0 0 2.5rem;
}

#site-search .tt-menu a:last-child { margin-bottom: 8rem;}

#site-search .tt-menu a h2 {
    font-size: 2.2rem;
    font-weight: 300;
    padding: 3.2rem 2rem 1rem;
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-transform: lowercase;
}

#site-search .tt-menu a h2:first-letter { text-transform: capitalize; }

#site-search .tt-menu a:hover {
    background: #ff5722;
    color: #fff;
}