Ghost를 위한 순수 자바스크립트, 가볍고 브라우저 내 전체 텍스트 검색 플러그인(블로그)
SearchinGhost는 Ghost 블로그 플랫폼 전용의 가볍고 확장 가능한 검색 엔진입니다. 핵심적으로 Ghost Content API를 사용하여 블로그 콘텐츠를 로드하고 강력한 FlexSearch 라이브러리를 사용하여 검색 쿼리를 색인화하고 실행합니다.
모든 작업은 클라이언트 브라우저에서 이루어지며, 이는 매우 빠른 검색 결과를 제공하고 이를 사용자에게 실시간으로 표시하는 데 도움이 됩니다("입력에 따른 검색"이라고도 함). 또한 필요한 경우에만 요청을 보내는 localStorage
브라우저를 사용하여 네트워크 부하를 최소화하는 데에도 주의를 기울입니다.
귀하의 블로그는 키릴 문자, 중국어, 한국어, 그리스어, 인도어 또는 기타 비라틴어 언어로 작성되어 있습니까? 걱정하지 마세요. 지원됩니다. 전용 섹션을 참조하세요.
보너스 : 컨셉이 마음에 들지만 빠르고 쉽게 설치하고 싶다면(정말 3분도 안 걸려요!) SearchinGhostEasy 프로젝트를 방문하세요.
설치 및 구성을 시작하기 전에 이 라이브 데모를 통해 직접 시도해 보십시오.
이 데모에서 검색 가능한 콘텐츠는 공식 Ghost 데모 API(예: https://demo.ghost.io)에서 제공됩니다. 옵션은 기본값으로 설정되어 각 입력 단어가 게시물 제목, 태그, 발췌 및 주요 내용으로 검색됩니다.
예를 들어 "마멀레이드"라는 단어를 검색해 보세요. 게시물 제목, 발췌문 또는 태그에는 존재하지 않지만 "Down The Rabbit Hole" 기사에서는 한 번 사용되었으므로 결과적으로 얻을 수 있습니다.
먼저 검색 결과를 표시하기 위한 입력 필드와 출력 요소를 포함하도록 테마의 default.hbs
파일을 업데이트합니다. 그런 다음 SearchinGhost 스크립트에 링크를 추가하고 자신만의 CONTENT_API_KEY
로 초기화하세요. 콘텐츠 API 키를 얻으려면 공식 Ghost 설명서를 참조하세요.
< input id =" search-bar " >
< ul id =" search-results " > </ ul >
< script src =" https://cdn.jsdelivr.net/npm/[email protected]/dist/searchinghost.min.js " > </ script >
< script >
var searchinGhost = new SearchinGhost ( {
key : 'CONTENT_API_KEY'
} ) ;
</ script >
그게 다야, 모든 것이 끝났어! 보다 세분화된 구성이 필요한 경우 다음 섹션을 읽어보세요.
다양한 방법을 사용하여 SearchinGhost를 설치할 수 있습니다. 가능한 방법은 다음과 같습니다.
이는 SearchinGhost를 설치하는 가장 쉽고 선호되는 방법입니다. 이러한 스크립트 중 하나를 테마 default.hbs
에 추가하세요. 또한 안정성과 성능을 위해 unpkg보다 jsdelivr을 사용하는 것이 좋습니다.
< script src =" https://cdn.jsdelivr.net/npm/[email protected]/dist/searchinghost.min.js " > </ script >
<!-- OR -->
< script src =" https://unpkg.com/[email protected]/dist/searchinghost.min.js " > </ script >
자체 서버에서 SearchinGhost를 제공하거나 빌드 프로세스에 포함시키려면 릴리스 페이지 자산에서 가져오거나 dist/searchinghost.min.js
파일을 다운로드할 수 있습니다.
SearchinGhost를 프로젝트 종속성으로 설치합니다.
$ npm install searchinghost
# OR
$ yarn add searchinghost
그런 다음 Javascript 파일에서 로드합니다.
import SearchinGhost from 'searchinghost' ;
// OR
var SearchinGhost = require ( 'searchinghost' ) ;
유일한 필수 구성 필드는 key
입니다. 다른 모든 필드에는 기본값이 있으며 선택 사항이 되었습니다.
SearchinGhost는 기본적으로 작동하도록 설계되었으며 이 최소한의 구성은 아직 강력합니다! 각 키를 누를 때마다 게시물 제목, 태그, 발췌문 및 내용을 검색합니다. 이는 가장 일반적인 것으로 보이는 기본 동작입니다.
// SearchinGhost minimal configuration
var searchinGhost = new SearchinGhost ( {
key : '<CONTENT_API_KEY>'
} ) ;
그럼에도 불구하고 귀하의 필요에 맞게 약간의 추가 구성을 수행하는 것이 좋습니다. title
만 검색하고 찾은 각 게시물에 대한 title
및 published_at
필드만 표시한다고 가정해 보겠습니다. 다음 구성을 사용할 수 있습니다.
var searchinGhost = new SearchinGhost ( {
key : '<CONTENT_API_KEY>' ,
postsFields : [ 'title' , 'url' , 'published_at' ] ,
postsExtraFields : [ ] ,
postsFormats : [ ] ,
indexedFields : [ 'title' ] ,
template : function ( post ) {
return `<a href=" ${ post . url } "> ${ post . published_at } - ${ post . title } </a>`
}
} ) ;
SearchinGhost는 구성을 통해 쉽게 사용자 정의하고 확장할 수 있습니다. 시간을 내어 다음 섹션에서 각 옵션을 살펴보세요.
{
key : '' ,
url : window . location . origin ,
version : 'v3' ,
loadOn : 'focus' ,
searchOn : 'keyup' ,
limit : 10 ,
inputId : [ 'search-bar' ] ,
outputId : [ 'search-results' ] ,
outputChildsType : 'li' ,
postsFields : [ 'title' , 'url' , 'excerpt' , 'custom_excerpt' , 'published_at' , 'feature_image' ] ,
postsExtraFields : [ 'tags' ] ,
postsFormats : [ 'plaintext' ] ,
indexedFields : [ 'title' , 'string_tags' , 'excerpt' , 'plaintext' ] ,
template : function ( post ) {
var o = `<a href=" ${ post . url } ">`
if ( post . feature_image ) o += `<img src=" ${ post . feature_image } ">`
o += '<section>'
if ( post . tags . length > 0 ) {
o += `<header>
<span class="head-tags"> ${ post . tags [ 0 ] . name } </span>
<span class="head-date"> ${ post . published_at } </span>
</header>`
} else {
o += `<header>
<span class="head-tags">UNKNOWN</span>
<span class="head-date"> ${ post . published_at } </span>
</header>`
}
o += `<h2> ${ post . title } </h2>`
o += `</section></a>`
return o ;
} ,
emptyTemplate : function ( ) { } ,
customProcessing : function ( post ) {
if ( post . tags ) post . string_tags = post . tags . map ( o => o . name ) . join ( ' ' ) . toLowerCase ( ) ;
return post ;
} ,
date : {
locale : document . documentElement . lang || "en-US" ,
options : { year : 'numeric' , month : 'short' , day : 'numeric' }
} ,
cacheMaxAge : 1800 ,
onFetchStart : function ( ) { } ,
onFetchEnd : function ( posts ) { } ,
onIndexBuildStart : function ( ) { } ,
onIndexBuildEnd : function ( index ) { } ,
onSearchStart : function ( ) { } ,
onSearchEnd : function ( posts ) { } ,
indexOptions : { } ,
searchOptions : { } ,
debug : false
} ) ;
블로그 데이터에 액세스하기 위한 공개 콘텐츠 API 키입니다.
예:
'22444f78447824223cefc48062'
Ghost API의 전체 도메인 이름입니다.
예:
'https://demo.ghost.io'
기본값:
window.location.origin
Ghost API 버전을 설정하세요.
'v2'
와'v3'
모두 사용하세요.기본값:
'v3'
라이브러리 로딩 전략을 설정합니다. HTML 페이지가 로드될 때, 사용자가 검색 창을 클릭할 때 요청 시 또는 전혀 클릭하지 않을 때 트리거될 수 있습니다.
검색창 초기화를 직접 실행하려면 이 값을
false
(부울)로 설정하세요. 이렇게 하면 나머지 코드가 준비되면searchinGhost.loadData()
호출할 수 있습니다.예상 값:
'page'
,'focus'
또는false
기본값:
'focus'
검색 쿼리를 실행해야 하는 시기를 선택합니다. 각 사용자 키 입력 및 양식 제출 시 검색하려면
'keyup'
사용하세요. 사용자가 버튼을 통해 양식을 제출하거나 'Enter' 키를 입력한 경우에만 검색하려면'submit'
사용하십시오. 자신의 자바스크립트 코드에서 이를 완전히 제어하려면false
(부울)를 사용하고searchinGhost.search("...")
사용하여 직접 검색을 실행하세요.예상 값:
'keyup'
,'submit'
또는false
기본값:
'keyup'
검색어에 의해 반환되는 최대 게시물 수를 설정합니다.
1
에서50
사이의 값은 매우 빠르며1000
보다 낮은 값은 성능을 크게 저하시키지 않습니다. 그러나 검색 엔진이 이 제한에 도달하면 검색을 중지하고 결과를 반환한다는 점을 기억하십시오. 즉, 낮을수록 좋습니다.권장되지 않지만 사용 가능한 모든 결과를 표시하려면 이 값을
0
으로 설정하십시오.기본값:
10
[더 이상 사용되지 않음]
v1.6.0
이전에는 이 필드가string
이었으므로 이 동작은 더 이상 사용되지 않습니다.귀하의 웹사이트에는 하나 이상의 검색창이 있을 수 있으며 각 검색창에는 고유한 HTML
id
속성이 있어야 합니다. 각 검색창id
이 배열에 넣으세요. 이름에 '#'을 포함하지 마세요.입력 필드가 필요하지 않은 경우 값을
[]
(빈 배열)로 설정하고searchOn
도false
(부울)로 설정합니다. 그런 다음searchinGhost.search("<your query>")
사용하여 검색을 실행하세요.기본값:
['search-bar']
[더 이상 사용되지 않음]
v1.6.0
이전에는 이 필드가string
이었으므로 이 동작은 더 이상 사용되지 않습니다.귀하의 웹사이트는 하나 이상의 HTML 요소를 사용하여 검색 결과를 표시할 수 있습니다. 이 배열은 이러한 모든 출력 요소의
id
속성을 참조합니다. 이러한 요소 중 하나에 이미 콘텐츠가 있는 경우 검색 결과가 콘텐츠를 덮어씁니다.JS 프레임워크를 사용하여 검색 결과를 표시하는 경우 이 값을
[]
(빈 배열)로 설정합니다.searchinGhost.search("<your query>")
함수에 의해 반환된 값으로 찾은 게시물을 얻을 수 있습니다.기본값:
['search-results']
[더 이상 사용되지 않음]
v1.6.0
이전에는 이 필드가string
이었습니다. 이는 더 이상 사용되지 않습니다.각 검색 결과는
outputId
상위 요소에 추가되기 전에 하위 요소 내에 래핑됩니다. 기본 유형은li
이지만 유효한 HTML 요소로 설정할 수 있습니다(MDN 문서 참조).
template
및emptyTemplate
의 결과를 출력 요소에 직접 추가하기 위해 래핑 요소를 사용하지 않으려면 값을false
(부울)로 설정하십시오.기본값:
'li'
원하는 모든 게시물 필드의 배열입니다. 유용한 게시물 정보를 표시하기 위해 이러한 모든 필드를
template
기능에서 사용할 수 있습니다."필드" 공식 문서를 참조하세요.
참고:
'custom_excerpt'
사용하면 템플릿 작성을 더 쉽게 하기 위해 해당 내용이 자동으로'excerpt'
에 추가됩니다.기본값:
['title', 'url', 'excerpt', 'custom_excerpt', 'published_at', 'feature_image']
이 배열을 사용하면
tags
또는authors
와 같은 추가 필드를 사용할 수 있습니다. 개인적으로 왜 다른 "필드"가 없는지 모르겠지만 Ghost API는 이런 방식으로 설계되었습니다.완전히 비활성화하려면 해당 값을
[]
(빈 배열)로 설정합니다."include" 공식 문서를 참조하세요.
기본값:
['tags']
이는 HTML 또는 일반 텍스트로 게시물 콘텐츠를 가져오는 데 사용할 수 있는 "형식" Ghost API에 해당합니다.
완전히 비활성화하려면 해당 값을
[]
(빈 배열)로 설정합니다."형식" 공식 문서를 참조하세요.
기본값:
['plaintext']
색인이 생성된 필드 목록입니다. 이러한 모든 필드의 내용은 검색 가능합니다.
이 목록의 모든 값은 게시물에 정의되어야 합니다 . 그렇지 않으면 검색 결과가 정확하지 않지만 앱이 충돌하지 않습니다!
postsFields
,postsExtraFields
및postsFormats
값을 다시 확인하세요.참고 :
'string_tags'
이상한 필드가customProcessing
옵션에 추가되었습니다. 태그를 사용하려면 FlexSearch가 배열을 제대로 처리할 수 없기 때문에 이 추악한 작업이 필요합니다(현재로서는). 원하지 않거나 마음에 들지 않으면customProcessing
재정의하여 추가 수정 없이posts
만 반환하세요. 태그를 사용하기로 결정한 경우 여기에서'string_tags'
도 사용하세요.기본값:
['title', 'string_tags', 'excerpt', 'plaintext']
자신만의 결과 템플릿을 정의하세요. 이 템플릿은 결과를 생성하기 위해 찾은 각 게시물에 사용되며 출력 요소에 하위 요소로 추가됩니다. 템플릿 엔진은 없으며
post
개체를 인수로 사용하는 기본 자바스크립트 함수만 있습니다.이 템플릿 옵션은 예상보다 훨씬 강력합니다. 검색 결과에 대해 호출되는 사용자 정의 처리 기능으로 생각할 수도 있습니다. 예를 들어 필터링을 수행하려면 아무것도 반환하지 않거나(예:
return;
) 빈 문자열(예:return "";
)을 반환하여 항목을 삭제합니다.작은따옴표/큰따옴표 대신 백틱 (예: '`')을 사용하는 점에 유의하세요. 이는 매우 유용한 자바스크립트 변수 보간을 활성화하는 데 필요합니다.
사용 가능한 변수는
postsFields
옵션에 정의된 변수입니다.예:
template: function ( post ) { return `<a href=" ${ post . url } "># ${ post . tags } - ${ post . published_at } - ${ post . title } </a>` }
결과가 없을 때 자신만의 결과 템플릿을 정의하세요.
예:
emptyTemplate: function ( ) { return '<p>Sorry, nothing found...</p>' }
Ghost에서 가져온 게시물 데이터를 추가로 수정해야 합니까? 이 기능을 사용하여 필요한 모든 작업을 수행하세요. 이 함수는 각 게시물에서 호출되며
onFetchEnd()
이후 및onIndexBuildStart()
이전에 실행됩니다.게시물을 삭제하려면 JS 거짓 값(예:
null
,undefined
,false
,""
, ...)을 반환하세요.입력/출력을 쉽게 디버깅하려면
onFetchEnd()
및onIndexBuildEnd()
사용하여console.log()
로 결과를 표시하세요. 고급 사용자라면 디버거를 사용하는 것이 가장 좋습니다. 또한 테스트할 때 로컬 캐시를 정리하는 것을 잊지 마세요!참고 : 기본적으로 이 옵션은 게시물에서 "태그" 필드를 더 쉽게 사용할 수 있도록 도우미 기능으로 이미 채워져 있습니다.
indexedFields
옵션을 참조하세요.예:
customProcessing: function ( post ) { post . extra_field = "hello" ; return post ; }
게시물에서 가져온 날짜 형식을 정의합니다.
자세한 내용은 MDN 참조를 참조하세요.
예:
date: { locale : "fr-FR" , options : { weekday : 'long' , year : 'numeric' , month : 'long' , day : 'numeric' } }
캐시 최대 수명을 초 단위로 설정합니다. 이 시간 동안 로컬 저장소에 이미 존재하는 인덱스가 발견되면 유효성을 확인하기 위한 추가 HTTP 요청 없이 인덱스가 로드됩니다. 캐시가 제거되면 값이 재설정됩니다.
이는 서버의 광대역 및 네트워크 부하를 절약하는 데 특히 유용합니다. 기본값은 30분으로 설정되어 있습니다. 이 값은 Google Analytics에서 사용하는 기본 사용자 세션 기간에서 가져옵니다.
기본값:
1800
Ghost API에서 데이터를 가져오기 전에 콜백 함수를 정의하세요.
이 함수는 인수를 사용하지 않습니다.
예:
onFetchStart: function ( ) { console . log ( "before data fetch" ) ; }
가져오기가 완료되면 콜백 함수를 정의합니다.
posts
에 대한 수정 사항이 유지되더라도 이를 수행하려면customProcessing()
함수를 사용하는 것이 좋습니다.이 함수는 하나의 인수, 즉 Ghost 자체가 반환한 모든 게시물의 배열을 사용합니다.
예:
onFetchEnd: function ( posts ) { console . log ( "Total posts found on Ghost:" , posts . length ) ; }
검색 색인 작성을 시작하기 전에 콜백 함수를 정의하십시오.
이 함수는 인수를 사용하지 않습니다.
예:
onIndexBuildStart: function ( ) { console . log ( "before building the index" ) ; }
검색 색인 구축이 완료되면 콜백 함수를 정의합니다.
이 함수는 빌드 FlexSearch 인덱스 개체라는 하나의 인수를 사용합니다.
예:
onIndexBuildEnd: function ( index ) { console . log ( "index built:" , index ) ; }
검색어 실행을 시작하기 전에 콜백 함수를 정의하세요. 예를 들어
onSearchEnd
완료를 기다리는 동안 결과 HTML 요소를 숨기거나 멋진 전환 효과를 추가하는 데 사용할 수 있습니다. 하지만 대부분의 경우 검색 기능이 눈에 쏙 들어올 만큼 빠르기 때문에 그럴 필요가 없습니다.이 함수는 인수를 사용하지 않습니다.
예:
onSearchStart: function ( ) { console . log ( "before executing the search query" ) ; }
검색 결과가 준비되면 콜백 함수를 정의합니다.
이 함수는 1개의 인수, 즉 일치하는 게시물의 배열을 사용합니다.
예:
onSearchEnd: function ( posts ) { console . log ( "search complete, posts found:" , posts ) ; }
추가 검색 색인 구성을 추가하거나 기본 구성을 재정의합니다. 이러한 옵션은 이미 제공된 옵션과 병합됩니다.
{ doc : { id : "id" , field : this . config . indexedFields } , encode : "simple" , tokenize : "forward" , threshold : 0 , resolution : 4 , depth : 0 }또한 이 매개변수를 사용하여 비라틴어 지원을 활성화합니다. 이 섹션을 참조하세요.
기본:
{}
고급 사용자를 위해 제작되었으며 검색어를 세부적으로 조정할 수 있습니다. 이 FlexSearch 설명서를 참조하세요.
우리는
index.search("your query", searchOptions)
라는 특정 쿼리 구성을 사용하므로searchOptions
에 추가된 모든 항목이 이 방식으로 FlexSearch에 전달됩니다.이 매개변수는 태그를 기반으로 게시물을 필터링할 때 매우 유용할 수 있습니다. 예를 들면:
searchOptions: { where : { string_tags : "getting started" } }또한 Searchinghost
limit
옵션은 자동으로searchOptions
에 병합됩니다. 우리의 경우 최종적으로는 다음과 같습니다.searchOptions: { where : { string_tags : "getting started" } , limit : 10 }기본:
{}
예상대로 작동하지 않는 경우
true
로 설정하여 애플리케이션 로그를 표시합니다.기본값:
false
블로그에서 라틴 알파벳 언어(예: 영어, 프랑스어, 스페인어) 또는 북부/동유럽 언어(예: 독일어, 스웨덴어, 헝가리어, 슬로베니아어, 에스토니아어)를 사용하는 경우 기본 구성이 제대로 작동합니다. 다른 경우에는 적절한 indexOptions
값을 찾아서 기본 SearchinGhost 구성에 추가하세요.
자신만의 특정 설정을 만들려면 FlexSearch README와 이 세 가지 문제를 참조하세요.
아무런 효과가 없거나 결과적으로 동작이 올바르지 않은 경우 자유롭게 문제를 만들어 보세요.
indexOptions: {
encode : false ,
rtl : true ,
split : / s+ /
}
indexOptions: {
encode : false ,
tokenize : function ( str ) {
return str . replace ( / [x00-x7F] / g , "" ) . split ( "" ) ;
}
}
이 옵션은 복합 문자를 사용하는 공백으로 구분된 모든 단어 언어에서 사용할 수 있습니다.
indexOptions: {
encode : false ,
split : / s+ /
}
여러 언어 유형(예: 키릴어/영어 또는 인도어/스페인어)을 사용해야 하는 경우 아래 전용 구성을 사용하세요. 알아요, 처음에는 무섭게 보일 수 있지만 그냥 복사해서 붙여넣고 저를 믿으세요.
indexOptions: {
split : / s+ / ,
encode : function ( str ) {
var regexp_replacements = {
"a" : / [àáâãäå] / g ,
"e" : / [èéêë] / g ,
"i" : / [ìíîï] / g ,
"o" : / [òóôõöő] / g ,
"u" : / [ùúûüű] / g ,
"y" : / [ýŷÿ] / g ,
"n" : / ñ / g ,
"c" : / [ç] / g ,
"s" : / ß / g ,
" " : / [-/] / g ,
"" : / ['!"#$%&\()*+,-./:;<=>?@[]^_`{|}~] / g ,
" " : / s+ / g ,
}
str = str . toLowerCase ( ) ;
for ( var key of Object . keys ( regexp_replacements ) ) {
str = str . replace ( regexp_replacements [ key ] , key ) ;
}
return str === " " ? "" : str ;
}
}
처음에는 Lunr.js, minisearch 및 퓨즈.js와 같은 다른 솔루션도 시도했습니다. 결국 FlexSearch는 빠르고 정확한 결과, 충분히 작은 번들 크기, 설정/구성도 쉬운 최상의 결과를 제공했습니다. 선택해야 할 모든 것이 있습니다!
걱정하지 마세요. 정상입니다. SearchinGhost는 캐시 시스템을 사용하여 블로그 데이터를 브라우저에 저장하여 네트워크 상호 작용을 제한합니다. 기본적으로 30분 이내에 저장된 캐시된 데이터는 여전히 유효한 것으로 간주됩니다. 그 이후에는 새 기사를 사용할 수 있습니다.
다른 사용자는 마지막으로 조사한 시간에 따라 30분을 기다릴 필요가 없을 수도 있다는 점을 명심하세요. 1시간 전이었다면 캐시가 제거되고 갱신되어 기사가 표시됩니다.
사용자가 항상 최신 상태를 유지하도록 하려면 cacheMaxAge
0
으로 설정하세요. 이때 loadOn
'focus'
로 설정하여 HTTP 요청 수를 제한해야 합니다.
기본적으로 feature_image
URL 변수를 사용하여 검색 결과에 이미지를 표시하면 항상 원본/전체 크기 이미지를 얻게 되며 일반적으로 요구 사항에 비해 너무 크므로(크기 및 무게) 미니어처가 더 좋습니다. 맞다.
Ghost V3부터 미디어 처리 엔진이 내장되어 반응형 이미지를 생성합니다. 기본적으로 Ghost는 주어진 이미지의 6가지 다른 이미지를 다시 생성합니다. 사용 가능한 크기는 w30
, w100
, w300
, w600
, w1000
, w2000
입니다.
우리의 경우 이미지를 더 빠르게 로드하는 가장 쉬운 방법은 더 작은 이미지를 사용하는 것입니다. 기본적으로 우리는 이 URL https://www.example.fr/content/images/2020/05/picture.jpg
API에서 가져온 기본 URL)를 https://www.example.fr/content/images/size/w600/2020/05/picture.jpg
로 만들고 싶습니다. https://www.example.fr/content/images/size/w600/2020/05/picture.jpg
(600px 너비).
이렇게 하려면 다음 코드 예제와 함께 "customProcessing"
필드를 추가하여 구성을 업데이트하세요. 물론 w600
대신 위에서 언급한 사용 가능한 크기를 모두 사용할 수 있습니다.
customProcessing: function ( post ) {
if ( post . tags ) post . string_tags = post . tags . map ( o => o . name ) . join ( ' ' ) . toLowerCase ( ) ;
if ( post . feature_image ) post . feature_image = post . feature_image . replace ( '/images/' , '/images/size/w600/' ) ; // reduce image size to w600
return post ;
}
이 수정은 즉각적이지 않으므로 실제로 차이점을 확인하려면 캐시 새로 고침이 필요합니다.
ID가 "search-counter"
인 HTML 요소를 생성하고 onSearchEnd()
함수를 활용하여 결과를 채웁니다. 예는 다음과 같습니다.
< p id =" search-counter " > </ p >
onSearchEnd: function ( posts ) {
var counterEl = document . getElementById ( 'search-counter' ) ;
counterEl . textContent = ` ${ posts . length } posts found` ;
}
예, SearchinGhost 내부 방법을 사용하면 가능합니다. 마치 마법처럼 보일 수도 있지만 현재 구성에 아래 코드를 추가하세요. 여기서 searchinGhost
new SearchinGhost(...)
로 생성된 자신의 인스턴스를 나타냅니다.
emptyTemplate: function ( ) {
var allPostsArray = Object . values ( searchinGhost . index . l ) ;
var latestPosts = allPostsArray . slice ( 0 , 6 ) ;
searchinGhost . display ( latestPosts ) ;
}
React, Vue 또는 Angular와 같은 프레임워크를 사용하는 경우 SearchinGhost가 DOM을 자체적으로 조작하는 것을 원하지 않을 것입니다. 프레임워크 내에서 콘텐츠 업데이트를 유지해야 하므로 사용해야 하는 구성은 다음과 같습니다.
var searchinGhost = new SearchinGhost ( {
key : '<CONTENT_API_KEY>' ,
inputId : false ,
outputId : false ,
[ ... ]
} ) ;
이제 검색 쿼리를 실행하려면 다음 SearchinGhost 메서드를 호출하세요.
var postsFound = searchinGhost . search ( "my query" ) ;
// Where 'postsFound' content looks like:
[
{
"title" : "A Full and Comprehensive Style Test" ,
"published_at" : "Sep 1, 2012" ,
[ ... ]
} ,
{
"title" : "Publishing options" ,
"published_at" : "Aug 20, 2018" ,
[ ... ]
}
]
이렇게 하면 뒤에서 아무것도 렌더링되지 않으며 모든 것이 ShadowDom에서 제어됩니다.
debug: true
onFetchStart()
, onSearchStart()
, ...와 같은 콜백을 추가하세요. 이제부터 모든 수정 사항은 이 전용 CHANGELOG.md 파일에서 추적됩니다.
어떤 기여라도 환영합니다! 버그를 발견했거나 코드를 개선하고 싶다면 언제든지 이슈나 PR을 작성해 주세요.
모든 코드 업데이트는 src
디렉터리에서 수행되어야 합니다.
프로젝트를 직접 빌드하려면 다음을 실행하세요.
$ npm install
$ npm run build
개발할 때 대신 watch 명령을 사용하면 각 파일 수정 시 더 빠르게 다시 빌드되고 소스 맵에 대한 링크가 포함되어 디버깅이 더 쉬워집니다.
$ npm run watch
참고: 이 프로젝트를 생성하는 동안 NPM v6.14.4와 함께 Node v12.16.2를 사용하고 있지만 이전/최신 버전에서도 작동해야 합니다.
SearchinGhost는 Ghost 검색 플러그인 분야에서 혼자가 아닙니다. 다음은 기타 관련 프로젝트의 간단한 목록입니다. 귀하의 요구 사항에 더 잘 맞는지 확인하기 위해 반드시 시도해 보아야 합니다.
GhostHunter(v0.6.0 - 101kB, 26kB gzip)
장점:
- 가장 유명하고 이에 대한 많은 기사와 튜토리얼
- localStorage 기반의 강력한 캐시 시스템
- 전체 텍스트 색인화(게시물 제목뿐만 아니라)
단점:
- jQuery에 의존
- 현재는 Ghost v2 API에서만 작동합니다.
- 시간이 지나면서 소스 코드가 지저분해졌습니다.
유령 검색(v1.1.0 - 12kB, 4.2kB gzip)
장점:
- 잘 작성되고 읽기 쉬운 코드 기반
- '퍼지' 기능 활용
단점:
- 긴 단어를 검색할 때 브라우저가 지연됩니다.
- API 요청을 너무 많이 보낼 수 있음
- 최상의 결과를 먼저 표시하기 위해 채점 시스템을 사용하지 않습니다.
Ghost Finder(v3.1.2 - 459kB, 116kB gzip)
장점:
- 순수 자바스크립트 라이브러리
단점:
- 대규모 최종 번들 크기
- 누른 각 키에 대해 HTTP 요청을 보냅니다!
- 검색 엔진을 사용하지 않고 게시물 제목의 하위 문자열만 찾습니다.
- 강조 표시된 문자를 올바르게 색인화하지 않습니다(예: 'é'는 'e'와 함께 찾아야 함).