مكون إضافي للبحث عن النص الكامل لجافا سكريبت وخفيف الوزن وداخل المتصفح لـ Ghost (مدونة)
SearchinGhost هو محرك بحث خفيف الوزن وقابل للتوسيع مخصص لمنصة التدوين Ghost. في جوهره، يستخدم Ghost Content API لتحميل محتوى مدونتك ومكتبة FlexSearch القوية لفهرسة استعلامات البحث وتنفيذها.
كل شيء يحدث في متصفح العميل، فهو يساعدنا على تقديم نتائج بحث سريعة للغاية ويعرضها للمستخدمين في الوقت الفعلي (المعروف أيضًا باسم "البحث أثناء الكتابة"). كما نهتم بتقليل أحمال الشبكة من خلال الاعتماد على المتصفح localStorage
فقط في إرسال الطلبات عند الضرورة.
هل مدونتك باللغة السيريلية أو الصينية أو الكورية أو اليونانية أو الهندية أو أي لغة أخرى غير اللاتينية؟ لا تقلق، فهو مدعوم، راجع القسم المخصص.
علاوة : إذا أعجبك المفهوم ولكنك ترغب في تثبيته بسرعة وسهولة (في أقل من 3 دقائق، حقًا!)، يرجى زيارة مشروع SearchinGhostEasy.
قبل الغوص في عملية التثبيت والتكوين، قم بتجربتها بنفسك باستخدام هذا العرض التجريبي المباشر .
في هذا العرض التوضيحي، يأتي المحتوى القابل للبحث من واجهة برمجة تطبيقات Ghost التجريبية الرسمية (أي https://demo.ghost.io). يتم تعيين الخيارات على الوضع الافتراضي بحيث يتم البحث عن كل كلمة إدخال في عنوان المنشورات والعلامات والمقتطفات والمحتوى الرئيسي.
على سبيل المثال، ابحث عن كلمة "مربى البرتقال". إنه غير موجود في أي عنوان مقال أو مقتطف أو علامة ولكن يتم استخدامه مرة واحدة في مقالة "Down The Rabbit Hole"، ولهذا السبب ستحصل عليه نتيجة لذلك.
أولاً، قم بتحديث ملف default.hbs
الخاص بموضوعك ليشمل حقل إدخال وعنصر إخراج لعرض نتائج البحث. ثم أضف رابطًا إلى البرنامج النصي SearchinGhost وقم بتهيئته باستخدام CONTENT_API_KEY
الخاص بك. للحصول على مفتاح Content 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
. نوصي أيضًا باستخدام jsdelivr عبر unpkg لموثوقيته وأدائه.
< 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
ثم قم بتحميله من أي ملف جافا سكريبت.
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'
. للبحث فقط عندما يقوم المستخدم بإرسال النموذج عبر زر أو إدخال مفتاح "إدخال"، استخدم'submit'
. إذا كنت تريد التحكم الكامل فيه من خلال كود جافا سكريبت الخاص بك، فاستخدمfalse
(منطقي) وقم بتنفيذ البحث بنفسك باستخدامsearchinGhost.search("...")
.القيم المتوقعة:
'keyup'
أو'submit'
أوfalse
الافتراضي:
'keyup'
قم بتعيين الحد الأقصى لعدد المشاركات التي يتم إرجاعها بواسطة استعلام البحث. أي قيمة تتراوح بين
1
و50
ستكون سريعة للغاية، ويجب ألا تؤدي القيم الأقل من1000
إلى انخفاض الأداء كثيرًا. لكن تذكر، عندما يصل محرك البحث إلى هذا الحد فإنه يتوقف عن البحث ويعيد النتائج: كلما كان أقل، كلما كان ذلك أفضل.على الرغم من عدم تشجيع ذلك بشدة، قم بتعيين هذه القيمة إلى
0
لعرض كافة النتائج المتوفرة.الافتراضي:
10
[مهمل] قبل
v1.6.0
، كان هذا الحقل عبارة عنstring
، وقد تم إهمال هذا السلوك.قد يحتوي موقع الويب الخاص بك على شريط بحث واحد أو أكثر، ويجب أن يكون لكل واحد منهم سمة
id
HTML فريدة. ضع كل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 مصممة بهذه الطريقة...اضبط قيمته على
[]
(مصفوفة فارغة) لتعطيله تمامًا.ارجع إلى الوثائق الرسمية "التضمين".
الافتراضي:
['tags']
يتوافق هذا مع Ghost API "التنسيقات" والذي يسمح باستخدامه لجلب محتوى المنشورات باستخدام HTML أو نص عادي.
اضبط قيمته على
[]
(مصفوفة فارغة) لتعطيله تمامًا.يرجى الرجوع إلى الوثائق الرسمية "التنسيقات".
الافتراضي:
['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 إضافي لتأكيد صلاحيته. عندما يتم مسح ذاكرة التخزين المؤقت، تتم إعادة تعيين القيمة.
يعد هذا مفيدًا بشكل خاص لحفظ أحمال النطاق العريض والشبكة لخادمك. يتم تعيين القيمة الافتراضية إلى نصف ساعة. تأتي هذه القيمة من مدة جلسة المستخدم الافتراضية التي تستخدمها 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 ) ; }
حدد وظيفة رد الاتصال قبل البدء في تنفيذ استعلام البحث. على سبيل المثال، يمكن استخدامه لإخفاء عنصر HTML للنتائج أثناء انتظار اكتمال
onSearchEnd
أو إضافة أي تأثيرات انتقالية رائعة. ولكن في معظم الحالات، هذا ليس ضروريًا لأن وظيفة البحث سريعة بما يكفي لتكون لطيفة على العين.لا تأخذ الدالة أي وسيطة.
مثال:
onSearchStart: function ( ) { console . log ( "before executing the search query" ) ; }
تحديد وظيفة رد الاتصال عندما تكون نتائج البحث جاهزة.
تأخذ الدالة وسيطة واحدة: مجموعة المنشورات المطابقة.
مثال:
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" } }لاحظ أيضًا أن خيار
limit
Searchinghost يتم دمجه تلقائيًا فيsearchOptions
. وفي حالتنا، سيصبح في النهاية:searchOptions: { where : { string_tags : "getting started" } , limit : 10 }تقصير:
{}
عندما لا يعمل شيء ما كما هو متوقع، اضبطه على
true
لعرض سجلات التطبيق.الافتراضي:
false
إذا كانت مدونتك تستخدم لغة أبجدية لاتينية (مثل الإنجليزية والفرنسية والإسبانية) أو إحدى لغات أوروبا الشمالية/الشرقية (مثل الألمانية والسويدية والمجرية والسلوفينية والإستونية)، فسيعمل التكوين الافتراضي بشكل جيد. في الحالات الأخرى، ابحث عن قيمة indexOptions
المناسبة وأضفها إلى تكوين SearchinGhost الرئيسي لديك.
لإنشاء إعداداتك الخاصة، راجع الملف التمهيدي الخاص بـ FlexSearch وهذه المشكلات الثلاثة.
إذا لم ينجح أي شيء بالنسبة لك أو إذا كان السلوك الناتج غير صحيح، فلا تتردد في إنشاء مشكلة.
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، وfuse.js. في النهاية، قدم FlexSearch أفضل النتائج الإجمالية مع نتائج سريعة ودقيقة ، وحجم حزمة صغير بما يكفي ، وكان من السهل أيضًا الإعداد/التهيئة. حصلت على كل شيء ليتم اختياره!
لا داعي للقلق، فهذا أمر طبيعي. يستخدم SearchinGhost نظام ذاكرة التخزين المؤقت لتخزين بيانات مدونتك في المتصفح مما يحد من تفاعل الشبكة. افتراضيًا، تظل البيانات المخزنة مؤقتًا والمخزنة منذ أقل من 30 دقيقة صالحة. وبعد ذلك الوقت، ستكون المقالة الجديدة متاحة لك.
ضع في اعتبارك أن المستخدمين الآخرين قد لا يحتاجون إلى الانتظار لمدة 30 دقيقة اعتمادًا على آخر مرة قاموا فيها بإجراء بحث. إذا كنت قد مضت ساعة واحدة، فسيتم مسح ذاكرة التخزين المؤقت الخاصة بهم وتجديدها حتى تظهر المقالة.
إذا كنت تريد أن يكون المستخدمون لديك على اطلاع تام دائمًا، فاضبط cacheMaxAge
على 0
. عند القيام بذلك، يجب عليك أيضًا ضبط loadOn
على 'focus'
للحد من عدد طلبات HTTP.
افتراضيًا، عند استخدام متغير عنوان URL feature_image
لعرض الصور في نتائج البحث الخاصة بك، ستحصل دائمًا على الحجم الأصلي/الكامل وتكون بشكل عام كبيرة جدًا (في الحجم والوزن) لاحتياجاتنا، وسيكون التصغير أفضل ملائم.
منذ Ghost V3، تم تضمين محرك معالجة الوسائط لإنشاء صور سريعة الاستجابة. بشكل افتراضي، يقوم Ghost بإعادة إنشاء 6 صور مختلفة للصورة المحددة. المقاسات المتوفرة هي: w30
، w100
، w300
، w600
، w1000
، w2000
.
في حالتنا، أسهل طريقة لتحميل الصور بشكل أسرع هي ببساطة استخدام صور أصغر. في الأساس، نريد أن يصبح عنوان URL هذا https://www.example.fr/content/images/2020/05/picture.jpg
(العنوان الافتراضي الذي تم جلبه من Ghost API) هو https://www.example.fr/content/images/size/w600/2020/05/picture.jpg
(عرض 600 بكسل واحد).
للقيام بذلك، قم بتحديث التكوين عن طريق إضافة حقل "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 ;
}
هذا التعديل ليس فوريًا، فأنت بحاجة إلى تحديث ذاكرة التخزين المؤقت لرؤية الفرق فعليًا.
قم بإنشاء عنصر HTML بالمعرف "search-counter"
واستخدم وظيفة 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 ,
[ ... ]
} ) ;
الآن، لتشغيل استعلام بحث، اتصل بطريقة SearchingGhost التالية:
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 المخصص هذا.
أي مساهمة هي أكثر من موضع ترحيب! إذا وجدت خطأ ما أو كنت ترغب في تحسين الكود، فلا تتردد في إنشاء مشكلة أو علاقة عامة.
يجب إجراء جميع تحديثات التعليمات البرمجية ضمن دليل src
.
لبناء المشروع بنفسك، قم بتشغيل:
$ npm install
$ npm run build
عند التطوير، استخدم أمر المراقبة بدلاً من ذلك، حيث سيتم إعادة البناء بشكل أسرع عند كل تعديل للملف ويتضمن رابطًا إلى الخريطة المصدر مما يجعل تصحيح الأخطاء أسهل.
$ npm run watch
ملاحظة: أثناء إنشاء هذا المشروع، أستخدم Node v12.16.2 مع NPM v6.14.4 ولكن يجب أن يعمل أيضًا مع الإصدارات الأقدم/الأحدث
SearchinGhost ليس وحده في مجال المكونات الإضافية لبحث Ghost. فيما يلي قائمة قصيرة بالمشاريع الأخرى ذات الصلة. يجب عليك بالتأكيد تجربتها لمعرفة ما إذا كانت تناسب احتياجاتك بشكل أفضل:
GhostHunter (الإصدار 0.6.0 - 101 كيلو بايت، 26 كيلو بايت بتنسيق gzip)
الايجابيات:
- وأشهرها، الكثير من المقالات والبرامج التعليمية حول هذا الموضوع
- نظام ذاكرة تخزين مؤقت قوي يعتمد على التخزين المحلي
- فهرسة النص الكامل (ليس فقط عنوان المشاركات)
السلبيات:
- يعتمد على مسج
- يعمل فقط مع Ghost v2 API (في الوقت الحالي)
- أصبح كود المصدر فوضويًا بمرور الوقت
بحث الأشباح (الإصدار 1.1.0 - 12 كيلو بايت، 4.2 كيلو بايت gzip)
الايجابيات:
- قاعدة تعليمات برمجية مكتوبة بشكل جيد وسهلة القراءة
- الاستفادة من القدرات "الغامضة".
السلبيات:
- يتأخر المتصفح عند البحث عن كلمات طويلة
- قد يتم إرسال عدد كبير جدًا من طلبات واجهة برمجة التطبيقات
- لا يستخدم نظام التسجيل لعرض أفضل النتائج أولاً
Ghost Finder (الإصدار 3.1.2 - 459 كيلو بايت، 116 كيلو بايت بتنسيق gzip)
الايجابيات:
- مكتبة جافا سكريبت النقية
السلبيات:
- حجم الحزمة النهائية الضخمة
- أرسل طلب HTTP لكل مفتاح يتم الضغط عليه!
- لا يستخدم محرك بحث، بل يبحث فقط عن السلاسل الفرعية في عناوين المشاركات
- لا يتم فهرسة الأحرف المميزة بشكل صحيح (على سبيل المثال، يجب العثور على "é" مع "e")