Compare commits

..

No commits in common. "develop" and "1.1.1" have entirely different histories.

222 changed files with 1724 additions and 7124 deletions

View File

@ -14,29 +14,18 @@
## I want to report a bug: ## I want to report a bug:
### What is the current behavior? **What is the current behavior?**
### What is your expected behavior?
### Git repository to reproduce the issue:
<!--
This will greatly help us reproduce the issue and fix it quickly.
If you don't have one or can't share it, screenshots or terminal output will
be very helpful.
-->
### Ruby version used:
<!-- `ruby -v` should give you this information -->
### Jekyll version used:
<!-- `bundle exec jekyll -v` should give you this one -->
**What is your expected behavior?**
**Steps to reproduce the issue:**
<!-- If you have a repo we can clone to try, or a screenshot, that is even
better! -->
## I want to suggest a feature: ## I want to suggest a feature:
### What is your use case for such a feature? **What is your use case for such a feature?**
<!-- The more you can tell us about WHY you want to do this, the easier is will be for us to tell you HOW to do it. --> <!-- The more you can tell us about WHY you want to do this, the easier is will be for us to tell you HOW to do it. -->
### What is your proposed API? Is this a new option? A new behavior? **What is your proposed API? Is this a new option? A new behavior?**

4
.gitignore vendored
View File

@ -1,14 +1,10 @@
Gemfile.lock Gemfile.lock
.envrc
pkg/ pkg/
coverage/ coverage/
docs-dev/ docs-dev/
gemfiles/*.lock gemfiles/*.lock
spec/site/_site spec/site/_site
spec/integration/site/_site
spec/site/.jekyll-cache/
.jekyll-cache/
.DS_Store .DS_Store
.*.sw[a-z] .*.sw[a-z]

View File

@ -3,9 +3,9 @@ cache: bundler
before_script: bundle update before_script: bundle update
script: bundle exec rake test script: bundle exec rake test
rvm: rvm:
- 2.6.2
- 2.4.2 - 2.4.2
- 2.3.5 - 2.3.5
- 2.3.0
notifications: notifications:
email: email:
on_success: never on_success: never

View File

@ -38,16 +38,6 @@ group :jekyll_plugins do
end end
``` ```
## Running integration tests
Integration tests will do a full jekyll run, and push data to an Algolia index,
checking that records and settings are correctly saved. It is the slowest
possible kind of tests, but also the one closest to a real implementation.
Running those tests requires a real Algolia plan. You need to define
`ALGOLIA_APPLICATION_ID`, `ALGOLIA_API_KEY` and `ALGOLIA_INDEX_NAME` (we suggest
using `direnv` for that), and then run `./scripts/test_integration`.
## Linting ## Linting
Run `rake lint` to check the style of all ruby files. Run `rake Run `rake lint` to check the style of all ruby files. Run `rake

View File

@ -1,14 +1,9 @@
# frozen_string_literal: true # Launch tests whenever a file in ./lib or ./spec changes
# Live-reload unit tests
guard :rspec, cmd: 'bundle exec rspec --color --format progress' do guard :rspec, cmd: 'bundle exec rspec --color --format progress' do
watch(%r{^spec/.+_spec\.rb$}) watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) do |match| watch(%r{^lib/(.+)\.rb$}) do |match|
"spec/#{match[1]}_spec.rb" "spec/#{match[1]}_spec.rb"
end end
watch(%r{^lib/jekyll/algolia/overwrites/jekyll-algolia-site\.rb$}) do
'spec/jekyll-algolia_spec.rb'
end
watch('spec/spec_helper.rb') { 'spec' } watch('spec/spec_helper.rb') { 'spec' }
end end

View File

@ -1,9 +0,0 @@
# frozen_string_literal: true
# Live-reload integration tests
guard :rspec, cmd: 'bundle exec rspec --color --format progress' do
watch(%r{^spec/integration/.+_spec\.rb$})
watch('spec/integration/spec_helper.rb') { 'spec/integration' }
end
notification :off

View File

@ -1,4 +0,0 @@
# Maintainers list to contact for any security issue
# You can find all contributors in the GitHub interface or the git log
Tim Carry (@pixelastic)

View File

@ -1,16 +1,13 @@
# Jekyll Algolia Plugin # Jekyll Algolia Plugin
[![gem version][1]][16] [![Gem Version][1]](http://badge.fury.io/rb/jekyll-algolia) [![Build
![ruby][2] Status][2]](https://travis-ci.org/algolia/jekyll-algolia) [![Coverage
![jekyll][3] Status][3]](https://coveralls.io/github/algolia/jekyll-algolia?branch=master)
[![build master][4]][17] [![Code Climate][4]](https://codeclimate.com/github/algolia/jekyll-algolia)
[![build develop][6]][17] ![Jekyll >= 3.6.0][5] ![Ruby >= 2.3.0][6]
[![coverage master][5]][18]
Add fast and relevant search to your Jekyll site. Add fast and relevant search to your Jekyll site.
> While this plugin was created by Algolia, it is not an officially supported API client. It is possible that future major versions of Jekyll break compatibility, or require changes.
## Usage ## Usage
```shell ```shell
@ -22,7 +19,7 @@ This will push the content of your Jekyll website to your Algolia index.
## Documentation ## Documentation
Full documentation can be found on Full documentation can be found on
[https://community.algolia.com/jekyll-algolia/][20] [https://community.algolia.com/jekyll-algolia/](https://community.algolia.com/jekyll-algolia/getting-started.html)
## Installation ## Installation
@ -43,89 +40,48 @@ Once this is done, download all dependencies with `bundle install`.
## Basic configuration ## Basic configuration
You need to provide certain Algolia credentials for this plugin to _index_ your You need to provide certain Algolia credentials for this plugin to *index* your
site. site.
_If you don't yet have an Algolia account, we suggest that you open a free *If you don't yet have an Algolia account, you can open a free [Community plan
[Community plan here][8]. You can find more information about the Algolia plans here][7]. Once signed in, you can get your credentials from
[in our FAQ][10]._ [your dashboard][8].*
Once signed in, you should get your application ID from [your dashboard][9] and Once you have your credentials, you should define your `application_id` and
define it inside your `_config.yml` file like this: `index_name` inside your `_config.yml` file like this:
```yaml ```yaml
# _config.yml # _config.yml
algolia: algolia:
application_id: 'your_application_id' application_id: 'your_application_id'
index_name: 'your_index_name'
``` ```
## Run it ## Run it
Once your application ID is setup, you can run the indexing by running the Once your credentials are setup, you can run the indexing by running the
following command: following command:
```shell ```shell
ALGOLIA_API_KEY='your_admin_api_key' bundle exec jekyll algolia ALGOLIA_API_KEY='{your_admin_api_key}' bundle exec jekyll algolia
``` ```
Note that `ALGOLIA_API_KEY` should be set to your admin API key. Note that `ALGOLIA_API_KEY` should be set to your admin API key.
## More about the Community plan
The Algolia [Community plan][11] lets you host up to 10k records and perform up
to 100k add/edit/delete operations per month (search operations are free). The
plan is entirely free, with no time limit.
What we ask in exchange is that you display a "Search by Algolia" logo next to
your search results. Our [InstantSearch libraries][12] have a simple boolean
option to toggle that on an off. If you want more flexibility, you can find
all versions of our logo [here][13].
If you need more information about the other Algolia plans, you can [check our
FAQ][10].
# Thanks # Thanks
Thanks to [Anatoliy Yastreb][14] for a [great tutorial][15] on creating Jekyll Thanks to [Anatoliy Yastreb][9] for a [great tutorial][10] on creating Jekyll
plugins. plugins.
[1]: https://badge.fury.io/rb/jekyll-algolia.svg [1]: https://badge.fury.io/rb/jekyll-algolia.svg
[2]: https://travis-ci.org/algolia/jekyll-algolia.svg?branch=master
[2]: https://img.shields.io/badge/ruby-%3E%3D%202.3.0-green.svg [3]: https://coveralls.io/repos/algolia/jekyll-algolia/badge.svg?branch=master&service=github
[4]: https://codeclimate.com/github/algolia/jekyll-algolia/badges/gpa.svg
[3]: https://img.shields.io/badge/jekyll-%3E%3D%203.6.0-green.svg [5]: https://img.shields.io/badge/jekyll-%3E%3D%203.6.0-green.svg
[6]: https://img.shields.io/badge/ruby-%3E%3D%202.3.0-green.svg
[4]: https://img.shields.io/badge/dynamic/json.svg?label=build%3Amaster&query=value&uri=https%3A%2F%2Fimg.shields.io%2Ftravis%2Falgolia%2Fjekyll-algolia.json%3Fbranch%3Dmaster [7]: https://www.algolia.com/users/sign_up/hacker
[8]: https://www.algolia.com/licensing
[5]: https://coveralls.io/repos/github/algolia/jekyll-algolia/badge.svg?branch=master [9]: https://github.com/ayastreb/
[10]: https://ayastreb.me/writing-a-jekyll-plugin/
[6]: https://img.shields.io/badge/dynamic/json.svg?label=build%3Adevelop&query=value&uri=https%3A%2F%2Fimg.shields.io%2Ftravis%2Falgolia%2Fjekyll-algolia.json%3Fbranch%3Ddevelop
[7]: https://coveralls.io/repos/github/algolia/jekyll-algolia/badge.svg?branch=develop
[8]: #more-about-the-community-plan
[9]: https://www.algolia.com/api-keys
[10]: https://community.algolia.com/jekyll-algolia/faq.html#how-many-records-will-the-plugin-need
[11]: https://www.algolia.com/users/sign_up/hacker
[12]: https://community.algolia.com/instantsearch.js/
[13]: https://www.algolia.com/press/?section=brand-guidelines
[14]: https://github.com/ayastreb/
[15]: https://ayastreb.me/writing-a-jekyll-plugin/
[16]: https://rubygems.org/gems/jekyll-algolia
[17]: https://travis-ci.org/algolia/jekyll-algolia
[18]: https://coveralls.io/github/algolia/jekyll-algolia?branch=master
[19]: https://coveralls.io/github/algolia/jekyll-algolia?branch=develop
[20]: https://community.algolia.com/jekyll-algolia/getting-started.html

130
Rakefile
View File

@ -9,14 +9,10 @@ rescue Bundler::BundlerError => e
warn 'Run `bundle install` to install missing gems' warn 'Run `bundle install` to install missing gems'
exit e.status_code exit e.status_code
end end
require 'algoliasearch'
require 'rake' require 'rake'
require 'rspec/core'
require 'rspec/core/rake_task'
require 'rubocop/rake_task'
# LINT # LINT
desc 'Check files for linting issues' require 'rubocop/rake_task'
RuboCop::RakeTask.new(:lint) do |task| RuboCop::RakeTask.new(:lint) do |task|
task.patterns = [ task.patterns = [
'lib/**/*.rb', 'lib/**/*.rb',
@ -29,7 +25,9 @@ RuboCop::RakeTask.new(:lint) do |task|
end end
# TEST # TEST
desc 'Run unit tests' require 'rspec/core'
require 'rspec/core/rake_task'
desc 'Run tests (with simple progress)'
RSpec::Core::RakeTask.new(:test) do |task| RSpec::Core::RakeTask.new(:test) do |task|
task.rspec_opts = '--color --format progress' task.rspec_opts = '--color --format progress'
task.pattern = [ task.pattern = [
@ -37,76 +35,35 @@ RSpec::Core::RakeTask.new(:test) do |task|
'spec/jekyll/**/*.rb' 'spec/jekyll/**/*.rb'
] ]
end end
namespace 'test' do desc 'Run tests (with full details)'
desc 'Run tests in all Ruby versions' RSpec::Core::RakeTask.new(:test_details) do |task|
task :all_ruby_versions do task.rspec_opts = '--color --format documentation'
puts 'Please, run ./scripts/test_all_ruby_versions manually' task.pattern = [
end 'spec/*.rb',
'spec/jekyll/**/*.rb'
# Generate locally browsable coverage files ]
task :coverage do end
ENV['COVERAGE'] = 'true' desc 'Run tests in all Ruby versions (with full details)'
Rake::Task['test'].execute task :test_all_ruby_versions do
end puts 'Please, run ./scripts/test_all_ruby_versions manually'
end
desc 'Live-reload unit tests'
task :watch do # COVERAGE
# We specifically watch for ./lib and ./spec and not the whole dir because: desc 'Generate locally browsable coverage files'
# 1. It's the only directories we are interested in task :coverage do
# 2. Listening to the whole parent dir might throw Guard errors if we have ENV['COVERAGE'] = 'true'
# symlink Rake::Task['test'].execute
sh 'bundle exec guard --clear --watchdir lib spec' end
end
# WATCH
# Integration tests need to run `bundle exec jekyll build/algolia`. Using desc 'Watch for changes in files and reload tests'
# bundle from inside a Rakefile does not seem to work, so the scripts have to task :watch do
# be run manually. Each script run the needed commands to prepare the test # We specifically watch for ./lib and ./spec and not the whole dir because:
# site, then actually run the _run and _watch_run tasks below. # 1. It's the only directories we are interested in
desc 'Run integration tests' # 2. Listening to the whole parent dir might throw Guard errors if we have
task :integration do # symlink
puts 'Please, run ./scripts/test_integration manually' sh 'bundle exec guard --clear --watchdir lib spec'
end
namespace 'integration' do
desc 'Live-reload integration tests'
task :watch do
puts 'Please, run ./scripts/test_integration_watch manually'
end
# Delete the test indices
task :_delete_indices do
Algolia.init(
application_id: ENV['ALGOLIA_APPLICATION_ID'],
api_key: ENV['ALGOLIA_API_KEY']
)
Algolia::Index.new(ENV['ALGOLIA_INDEX_NAME']).delete_index!
Algolia::Index
.new("#{ENV['ALGOLIA_INDEX_NAME']}_object_ids").delete_index!
end
# Run only the integration tests
desc ''
RSpec::Core::RakeTask.new(:_run) do |task|
task.rspec_opts = '--color --format progress'
task.pattern = [
# Check that the default build has the expected results
'spec/integration/main_spec.rb',
# Check various config and its impact on the settings
'spec/integration/settings_spec.rb',
# Check that object ids are stored in dedicated index
'spec/integration/object_ids_spec.rb'
]
end
# Live-reloading integration tests
# It will reload the tests whenever they are changed. It will not
# live-rebuild everything, you still have to run rake
# ./scripts/test_integration_prepare for that
task :_watch_run do
sh 'bundle exec guard '\
'--clear '\
'--watchdir lib spec/integration '\
'--guardfile Guardfile_integration'
end
end
end end
task watch: 'test:watch'
# GEM RELEASE # GEM RELEASE
desc 'Release a new version of the gem' desc 'Release a new version of the gem'
@ -118,14 +75,14 @@ task release: %i[lint test] do
Rake::Task['release:update_master_from_develop'].invoke Rake::Task['release:update_master_from_develop'].invoke
end end
namespace 'release' do namespace 'release' do
# Getting up to date from master desc 'Getting up to date from master'
task :update_develop_from_master do task :update_develop_from_master do
sh 'git checkout master --quiet' sh 'git checkout master --quiet'
sh 'git pull --rebase origin master --quiet' sh 'git pull --rebase origin master --quiet'
sh 'git checkout develop --quiet' sh 'git checkout develop --quiet'
sh 'git rebase master --quiet' sh 'git rebase master --quiet'
end end
# Update current version desc 'Update current version'
task :update_version do task :update_version do
version_file_path = 'lib/jekyll/algolia/version.rb' version_file_path = 'lib/jekyll/algolia/version.rb'
require_relative version_file_path require_relative version_file_path
@ -143,24 +100,15 @@ namespace 'release' do
# Commit it in git # Commit it in git
sh "git commit -a -m 'release #{new_version}'" sh "git commit -a -m 'release #{new_version}'"
# Create the git tag # Create the git tag
last_tag = `git describe --tags --abbrev=0`.strip sh "git tag -am 'tag v#{new_version}' #{new_version}"
changelog = `git log #{last_tag}..HEAD --format=%B`.gsub("\n\n", "\n")
tag_name = new_version
sh 'git tag '\
"-a #{tag_name} "\
"-m \"#{changelog}\""\
' 2>/dev/null'
sh "git tag #{tag_name} #{tag_name} -f -a"
end end
# Build the gem desc 'Build the gem'
task :build do task :build do
sh 'bundle install' sh 'bundle install'
sh 'gem build jekyll-algolia.gemspec' sh 'gem build jekyll-algolia.gemspec'
end end
# Push the gem to rubygems desc 'Push the gem to rubygems'
task :push do task :push do
# This will throw a warning because we're redefining a constant. That's ok. # This will throw a warning because we're redefining a constant. That's ok.
load 'lib/jekyll/algolia/version.rb' load 'lib/jekyll/algolia/version.rb'
@ -169,7 +117,7 @@ namespace 'release' do
sh "rm jekyll-algolia-#{current_version}.gem" sh "rm jekyll-algolia-#{current_version}.gem"
sh "git push origin #{current_version}" sh "git push origin #{current_version}"
end end
# Update master desc 'Update master'
task :update_master_from_develop do task :update_master_from_develop do
sh 'git checkout master --quiet' sh 'git checkout master --quiet'
sh 'git rebase develop --quiet' sh 'git rebase develop --quiet'
@ -196,7 +144,7 @@ namespace 'docs' do
Rake::Task['docs:build'].invoke Rake::Task['docs:build'].invoke
sh 'git add ./docs' sh 'git add ./docs'
sh "git commit -m 'Updating documentation website' || true" sh "git commit -m 'Updating documentation website'"
sh 'git checkout master --quiet' sh 'git checkout master --quiet'
sh 'git rebase develop --quiet' sh 'git rebase develop --quiet'

View File

@ -27,7 +27,6 @@ const sidebarMenu = [
items: [ items: [
{ title: 'Getting Started', url: 'getting-started.html' }, { title: 'Getting Started', url: 'getting-started.html' },
{ title: 'How it works', url: 'how-it-works.html' }, { title: 'How it works', url: 'how-it-works.html' },
{ title: 'FAQ', url: 'faq.html' },
], ],
}, },
{ {
@ -43,7 +42,6 @@ const sidebarMenu = [
items: [ items: [
{ title: 'Deploying on Netlify', url: 'netlify.html' }, { title: 'Deploying on Netlify', url: 'netlify.html' },
{ title: 'Deploying on Github Pages', url: 'github-pages.html' }, { title: 'Deploying on Github Pages', url: 'github-pages.html' },
{ title: 'Themes', url: 'themes.html' },
{ title: 'Migration guide', url: 'migration-guide.html' }, { title: 'Migration guide', url: 'migration-guide.html' },
], ],
}, },

View File

@ -35,7 +35,7 @@
"hasha": "3.0.0", "hasha": "3.0.0",
"http-server": "0.10.0", "http-server": "0.10.0",
"jstransformer-markdown-it": "2.0.0", "jstransformer-markdown-it": "2.0.0",
"lodash": "4.17.5", "lodash": "4.17.4",
"markdown-it": "8.4.0", "markdown-it": "8.4.0",
"markdown-it-anchor": "4.0.0", "markdown-it-anchor": "4.0.0",
"metalsmith": "2.3.0", "metalsmith": "2.3.0",
@ -45,7 +45,7 @@
"metalsmith-sass": "1.4.0", "metalsmith-sass": "1.4.0",
"ms-webpack": "2.0.0", "ms-webpack": "2.0.0",
"node-sass": "4.7.2", "node-sass": "4.7.2",
"nodemon": "1.18.7", "nodemon": "1.12.5",
"postcss": "6.0.14", "postcss": "6.0.14",
"postcss-loader": "2.0.9", "postcss-loader": "2.0.9",
"postcss-scss": "1.0.2", "postcss-scss": "1.0.2",
@ -66,8 +66,8 @@
"webpack-hot-middleware": "2.21.0" "webpack-hot-middleware": "2.21.0"
}, },
"engines": { "engines": {
"node": ">=9.2.0", "node": "^9.2.0",
"yarn": ">=1.3.2" "yarn": "^1.3.2"
}, },
"renovate": { "renovate": {
"extends": [ "extends": [

0
docs-src/src/assets/fonts/algolia-brands-iconfont.eot Normal file → Executable file
View File

0
docs-src/src/assets/fonts/algolia-brands-iconfont.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 214 KiB

After

Width:  |  Height:  |  Size: 214 KiB

0
docs-src/src/assets/fonts/algolia-brands-iconfont.ttf Normal file → Executable file
View File

0
docs-src/src/assets/fonts/algolia-brands-iconfont.woff Normal file → Executable file
View File

0
docs-src/src/assets/fonts/algolia-website-iconfont.eot Normal file → Executable file
View File

0
docs-src/src/assets/fonts/algolia-website-iconfont.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

0
docs-src/src/assets/fonts/algolia-website-iconfont.ttf Normal file → Executable file
View File

View File

0
docs-src/src/assets/images/github-icon.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 848 B

After

Width:  |  Height:  |  Size: 848 B

0
docs-src/src/assets/js/activateClipboard.js Normal file → Executable file
View File

0
docs-src/src/assets/js/main.js Normal file → Executable file
View File

View File

@ -15,7 +15,6 @@ already have pushed all your data, following our [getting started][2] guide.
[![Search in the minima theme][3]](https://community.algolia.com/jekyll-algolia-example/) [![Search in the minima theme][3]](https://community.algolia.com/jekyll-algolia-example/)
In this tutorial we'll add a search on the front page that will let you search In this tutorial we'll add a search on the front page that will let you search
into all your posts (both titles and content), in a fast and relevant manner. into all your posts (both titles and content), in a fast and relevant manner.
@ -74,17 +73,11 @@ exist yet.
In that file, we'll add the following content. It's a lot of code in one go, but In that file, we'll add the following content. It's a lot of code in one go, but
don't worry, we'll explain it all right after. don't worry, we'll explain it all right after.
_Note that for the sake of readability we will be using JavaScript features
that might not be available in all browsers (namely [const][5], [template
literals][6] and [arrow functions][7]). If you need compatibility with browsers
that do not ship those features, we recommend you use [Babel][8] to
automatically transpile your code._
```html ```html
<!-- Including InstantSearch.js library and styling --> <!-- Including InstantSearch.js library and styling -->
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@2.6.0/dist/instantsearch.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@2.3.3/dist/instantsearch.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.6.0/dist/instantsearch.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.3.3/dist/instantsearch.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.6.0/dist/instantsearch-theme-algolia.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.3.3/dist/instantsearch-theme-algolia.min.css">
<script> <script>
// Instanciating InstantSearch.js with Algolia credentials // Instanciating InstantSearch.js with Algolia credentials
@ -98,8 +91,7 @@ const search = instantsearch({
search.addWidget( search.addWidget(
instantsearch.widgets.searchBox({ instantsearch.widgets.searchBox({
container: '#search-searchbar', container: '#search-searchbar',
placeholder: 'Search into posts...', placeholder: 'Search into posts...'
poweredBy: true // This is required if you're on the free Community plan
}) })
); );
search.addWidget( search.addWidget(
@ -115,9 +107,9 @@ search.start();
### Including the InstantSearch.js library ### Including the InstantSearch.js library
The first lines will include the [InstantSearch.js][9] library as well as The first lines will include the [InstantSearch.js][5] library as well as
minimal styling, directly from the jsDeliver CDN. Those files are also available minimal styling, directly from the jsDeliver CDN. Those files are also available
through [Yarn][10]/[NPM][11] if you need them locally. through [Yarn][6]/[NPM][7] if you need them locally.
### Instanciating the library ### Instanciating the library
@ -129,7 +121,7 @@ Both `application_id` and `index_name` should already be in your `_config.yml`
file. The `search_only_api_key` should be new, though. file. The `search_only_api_key` should be new, though.
Add a new entry in your `_config.yml` file, under the `algolia` namespace with Add a new entry in your `_config.yml` file, under the `algolia` namespace with
the value of your Search API Key (you can find it in your [Dashboard][12]): the value of your Search API Key (you can find it in your [Dashboard][8]):
```yml ```yml
# _config.yml # _config.yml
@ -159,7 +151,7 @@ InstantSearch loads, it will replace the list with its own results.
This is what it should look like at this stage. We have a search bar, but This is what it should look like at this stage. We have a search bar, but
results are displayed in a raw JSON format. Let's work on styling this. results are displayed in a raw JSON format. Let's work on styling this.
![Minimal InstantSearch.js styling][13] ![Minimal InstantSearch.js styling][9]
## Templating ## Templating
@ -189,7 +181,7 @@ search.addWidget(
); );
``` ```
![InstantSearch.js styling][14] ![InstantSearch.js styling][10]
This looks much better already. By using a template, we managed to make the This looks much better already. By using a template, we managed to make the
result look close to what the initial display was. In the next section, we'll result look close to what the initial display was. In the next section, we'll
@ -204,7 +196,7 @@ default we display it exactly as it was saved in the Algolia index: as a UNIX
timestamp. timestamp.
Because our template is a JavaScript function, we can reformat data before Because our template is a JavaScript function, we can reformat data before
rendering it. Here we will use the [moment.js][15] library to format our date. rendering it. Here we will use the [moment.js][11] library to format our date.
Using `moment.unix(hit.date).format('MMM D, YYYY');` we'll transform Using `moment.unix(hit.date).format('MMM D, YYYY');` we'll transform
`1513764761` into `Dec 20, 2017`. `1513764761` into `Dec 20, 2017`.
@ -234,38 +226,42 @@ All HTML nodes added by InstantSearch.js come with a custom `.ais-*` class added
to them. This makes altering the styling of the elements to match your overall to them. This makes altering the styling of the elements to match your overall
theme easy to achieve. theme easy to achieve.
### Headings ### Edge-case handling
With the current configuration, we will sometimes end up with results that look With the current configuration, we will sometimes end up with results that look
irrelevant: nothing is highlighted neither in the title or the content. irrelevant: nothing is highlighted neither in the title or the content.
This is because by default the plugin is searching not only in the content and This is because by default the plugin is searching into different fields
the title, but also in the headings (`<h1>` to `<h6>` of the page). Because we (including `tags`, `categories` and the parent heading hierarchy of each
currently only display the title and content, it make some perfectly relevant paragraph). Because we chose to only display the title and content, it means that
result look odd, because nothing is highlighted. when a match in another attribute is occurring, we have no way to visually signal
it to the user. It makes the result look irrelevant, while it is actually
relevant (but we're not explaining why).
To fix that, we'll add the highlighted headings to the display when they are One way to work around this issue is to manually tell the API in which field it
matching. We'll create a new variable called `breadcrumbs`, filled with the should search, by using the [restrictSearchableAttributes][12] option.
highlighted headings, and add it to our template only when not empty.
We also update the url to include the `#` anchor that will point the link
directly to the closest matching heading.
### Final code ### Final code
Here is the complete new version of the `_includes/algolia.html` file. Here is the complete new version of the `_includes/algolia.html` file.
```html ```html
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@2.6.0/dist/instantsearch.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@2.3.3/dist/instantsearch.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.6.0/dist/instantsearch.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.3.3/dist/instantsearch.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.6.0/dist/instantsearch-theme-algolia.min.css"> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/instantsearch.js@2.3.3/dist/instantsearch-theme-algolia.min.css">
<script> <script>
const search = instantsearch({ const search = instantsearch({
appId: '{{ site.algolia.application_id }}', appId: '{{ site.algolia.application_id }}',
apiKey: '{{ site.algolia.search_only_api_key }}', apiKey: '{{ site.algolia.search_only_api_key }}',
indexName: '{{ site.algolia.index_name }}' indexName: '{{ site.algolia.index_name }}',
searchParameters: {
restrictSearchableAttributes: [
'title',
'content'
]
}
}); });
const hitTemplate = function(hit) { const hitTemplate = function(hit) {
@ -273,25 +269,14 @@ const hitTemplate = function(hit) {
if (hit.date) { if (hit.date) {
date = moment.unix(hit.date).format('MMM D, YYYY'); date = moment.unix(hit.date).format('MMM D, YYYY');
} }
const url = hit.url;
let url = `{{ site.baseurl }}${hit.url}#${hit.anchor}`;
const title = hit._highlightResult.title.value; const title = hit._highlightResult.title.value;
let breadcrumbs = '';
if (hit._highlightResult.headings) {
breadcrumbs = hit._highlightResult.headings.map(match => {
return `<span class="post-breadcrumb">${match.value}</span>`
}).join(' > ')
}
const content = hit._highlightResult.html.value; const content = hit._highlightResult.html.value;
return ` return `
<div class="post-item"> <div class="post-item">
<span class="post-meta">${date}</span> <span class="post-meta">${date}</span>
<h2><a class="post-link" href="${url}">${title}</a></h2> <h2><a class="post-link" href="${url}">${title}</a></h2>
{{#breadcrumbs}}<a href="${url}" class="post-breadcrumbs">${breadcrumbs}</a>{{/breadcrumbs}}
<div class="post-snippet">${content}</div> <div class="post-snippet">${content}</div>
</div> </div>
`; `;
@ -301,8 +286,7 @@ const hitTemplate = function(hit) {
search.addWidget( search.addWidget(
instantsearch.widgets.searchBox({ instantsearch.widgets.searchBox({
container: '#search-searchbar', container: '#search-searchbar',
placeholder: 'Search into posts...', placeholder: 'Search into posts...'
poweredBy: true // This is required if you're on the free Community plan
}) })
); );
@ -331,49 +315,31 @@ search.start();
font-style: normal; font-style: normal;
text-decoration: underline; text-decoration: underline;
} }
.post-breadcrumbs {
color: #424242;
display: block;
}
.post-breadcrumb {
font-size: 18px;
color: #424242;
}
.post-breadcrumb .ais-Highlight {
font-weight: bold;
font-style: normal;
}
.post-snippet .ais-Highlight { .post-snippet .ais-Highlight {
color: #2a7ae2; color: #2a7ae2;
font-style: normal; font-style: normal;
font-weight: bold; font-weight: bold;
} }
.post-snippet img {
display: none;
}
</style> </style>
``` ```
## Final result ## Final result
You can check the [final result live here][16], and have a look at all the code You can check the [final result live here][13], and have a look at all the code from
from the [GitHub repository][17]. the [GitHub repository][14].
[1]: https://github.com/jekyll/minima [1]: https://github.com/jekyll/minima
[2]: ./getting-started.html [2]: ./getting-started.html
[3]: ./assets/images/minima-search.gif [3]: ./assets/images/minima-search.gif
[4]: https://raw.githubusercontent.com/jekyll/minima/master/_layouts/home.html [4]: https://raw.githubusercontent.com/jekyll/minima/master/_layouts/home.html
[5]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const [5]: https://community.algolia.com/instantsearch.js/
[6]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals [6]: https://yarnpkg.com/en/package/instantsearch.js
[7]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions [7]: https://www.npmjs.com/package/instantsearch.js
[8]: https://babeljs.io/ [8]: https://www.algolia.com/api-keys
[9]: https://community.algolia.com/instantsearch.js/ [9]: ./assets/images/instantsearch-nostyling.png
[10]: https://yarnpkg.com/en/package/instantsearch.js [10]: ./assets/images/instantsearch-styling.png
[11]: https://www.npmjs.com/package/instantsearch.js [11]: https://momentjs.com/docs/
[12]: https://www.algolia.com/api-keys [12]: https://www.algolia.com/doc/api-reference/api-parameters/restrictSearchableAttributes/
[13]: ./assets/images/instantsearch-nostyling.png [13]: https://community.algolia.com/jekyll-algolia-example/
[14]: ./assets/images/instantsearch-styling.png [14]: https://github.com/algolia/jekyll-algolia-example
[15]: https://momentjs.com/docs/
[16]: https://community.algolia.com/jekyll-algolia-example/
[17]: https://github.com/algolia/jekyll-algolia-example

View File

@ -17,9 +17,11 @@ Here is the list of command line options you can pass to the `jekyll algolia` co
| Flag | Description | | Flag | Description |
| ---- | ----- | | ---- | ----- |
| `--config ./_config.yml` | You can here specify the config file to use. Default is `_config.yml` | | `--config ./_config.yml` | You can here specify the config file to use. Default is `_config.yml` |
| `--future` | With this flag, the command will also index posts with a future date |
| `--limit_posts 10` | Limits the number of posts to parse and index |
| `--drafts` | Index drafts in the `_drafts` folder as well |
| `--dry-run` or `-n` | Do a dry run, do not actually push anything to your index | | `--dry-run` or `-n` | Do a dry run, do not actually push anything to your index |
| `--verbose` | Display more information about what is going to be indexed | | `--verbose` | Display more information about what is going to be indexed |
| `--force-settings` | Force update of the index settings |
## Environment variables ## Environment variables
@ -30,9 +32,10 @@ to overwrite those values.
key | value key | value
---------------------- | ---------------------- ---------------------- | ----------------------
ALGOLIA_APPLICATION_ID | Your Application ID, available in [your dashboard](https://www.algolia.com/api-keys). ALGOLIA_APPLICATION_ID | `your_application_id`
ALGOLIA_INDEX_NAME | Your Index name, any string will work ALGOLIA_INDEX_NAME | `your_index_name`
ALGOLIA_API_KEY | Your Admin API Key, available in [your dashboard](https://www.algolia.com/api-keys). ALGOLIA_API_KEY | `your_api_key`
## `_algolia_api_key` file ## `_algolia_api_key` file

View File

@ -1,100 +0,0 @@
---
title: Frequently Asked Questions
layout: content-with-menu.pug
---
# Frequently Asked Questions
## How many records will the plugin need?
The plugin will not create an exact mapping of `1 page = 1 record`. Instead, it
will split all pages into smaller chunks, and each chunk will be saved as a
record. Splitting into small chunks is key to offer the best relevance of
results.
The default chunking mechanism is to create one chunk per paragraph of content.
So, for a blog post that is made up of 10 paragraphs of text, it will create 10
records.
Estimating the number of records you will need can be tricky as it depends on
both the number of pages you have, and on the average length of them. Some
configuration options (such as [nodes_to_index][1]) can also influence the final
result.
The following table should give you a ballpark estimate of what to expect. All
calculations were done with an average of **15 paragraphs per page**, on a
timeline of **one year**.
| update frequency | # of new pages | # of records | Algolia plan |
| --------------------------- | -------------- | ------------ | -------------- |
| ~1 new page per week | ~50 | ~750 | [Community][2] |
| ~1 new page per day | ~400 | ~6.000 | [Community][3] |
| ~2 new pages per day | ~700 | ~10.500 | [Essential][4] |
| ~1 new page per hour | ~8800 | ~132.000 | [Essential][5] |
| ~1 new page every 5 minutes | ~105.000 | ~1.575.000 | [Plus][6] |
| More? | More? | More? | [Business][7] |
## One of my records is too big. What can I do?
If you get an error about one of your records being too big, be sure to update
the plugin to the latest version. We keep improving the plugin with ways of
making the records smaller.
If you're still having an error, you should check the `.json` log file that has
been created in your source directory. This will contain the content of the
record that has been rejected. It might give you hints about what went wrong.
A common cause for this issue often lies in the page HTML. Maybe the HTML is
malformed (a tag is not closed for example), or instead of several small
paragraphs there is only one large paragraph. This can cause the parser to take
the whole page content (instead of small chunks of it) to create the records.
If you don't find where the issue is coming from, feel free to open a [GitHub
issue][8] with a copy of the log file and we'll be happy to help you.
## How can I tweak the relevance ranking?
The plugin default configuration will rank results based on their textual
relevance. You can adapt the ranking to fit your needs by using a
combination of front-matter and Algolia index settings.
For example, if you know some of your blog posts are popular, you might want to
give them a boost in their ranking. To do so, add a `popular: true` entry to the
front-matter of such posts. Any custom key added to a front-matter is
automatically pushed to their corresponding records.
Then, you would have to edit your `_config.yml` file to pass a custom
`settings.customRanking` value. The `customRanking` is one of the way ranking
can be configured in an Algolia index and follows a tie-breaking algorithm. You
can find more information about the way it works either in the [official
documentation][9] or in [this video][10].
The default `customRanking` used by the plugin is [defined here][11] and use the
date, weight of the header and position in the page by default. You can
overwrite it to also take the `popular` flag into account like:
```yml
algolia:
settings:
customRanking:
- desc(popular)
- desc(date)
- desc(custom_ranking.heading)
- asc(custom_ranking.position)
```
This will rank popular posts matching your keywords before other posts. You can
use either boolean or numeric values for the `customRanking`.
[1]: options.html#nodes-to-index
[2]: https://www.algolia.com/pricing
[3]: https://www.algolia.com/pricing
[4]: https://www.algolia.com/pricing
[5]: https://www.algolia.com/pricing
[6]: https://www.algolia.com/pricing
[7]: https://www.algolia.com/pricing
[8]: https://github.com/algolia/jekyll-algolia/issues
[9]: https://community.algolia.com/jekyll-algolia/options.html#settings
[10]: https://www.youtube.com/watch?v=H6crAohtUBw
[11]:
https://github.com/algolia/jekyll-algolia/blob/develop/lib/jekyll/algolia/configurator.rb#L27-L30

View File

@ -10,8 +10,6 @@ layout: content-with-menu.pug
`jekyll-algolia` is a Jekyll plugin that lets you push all your content in an `jekyll-algolia` is a Jekyll plugin that lets you push all your content in an
Algolia index. Algolia index.
> While this plugin was created by Algolia, it is not an officially supported API client. It is possible that future major versions of Jekyll break compatibility, or require changes.
## Requirements ## Requirements
You'll need: You'll need:
@ -58,7 +56,7 @@ Once you have your credentials, you should define your `application_id` and
algolia: algolia:
application_id: your_application_id application_id: your_application_id
index_name: jekyll # You can replace that with whatever name you want index_name: your_index_name
``` ```
## Usage ## Usage
@ -67,7 +65,7 @@ Once your credentials are setup, you can run the indexing by running the
following command: following command:
```shell ```shell
ALGOLIA_API_KEY='your_admin_api_key' bundle exec jekyll algolia ALGOLIA_API_KEY='{your_admin_api_key}' bundle exec jekyll algolia
``` ```
Note that `ALGOLIA_API_KEY` should be set to your admin API key. This key has Note that `ALGOLIA_API_KEY` should be set to your admin API key. This key has
@ -87,26 +85,25 @@ The plugin only takes care of extracting your data and pushing it to an Algolia
index. Building the front-end that will allow your users to search into that index. Building the front-end that will allow your users to search into that
data is not part of the plugin. data is not part of the plugin.
As it would depend too much on the theme you applied to Jekyll, we could not As it would depend too much on the theming you applied to Jekyll, we could not
create a one-size-fits-all solution. Instead, the best solution is to use our create a one-size-fits-all solution. Instead, the best solution is to use our
[InstantSearch.js][9] library (also available for [Vue.js][10], [React][11] and [InstantSearch.js][9] library (also available for [Vue.js][10] and [React][11]).
[Angular][12]). It's an easy-to-use set of UI widgets you can use to build your It's an easy-to-use set of UI widgets you can use to build your own search in
own search in a matter of minutes. a matter of minutes.
You can follow [this tutorial][13] to see how to add search on the default blog You can follow [this tutorial][12] to see how to add search on the default blog
theme. theme.
[1]: https://jekyllrb.com/ [1]: https://jekyllrb.com/
[2]: https://www.ruby-lang.org/en/ [2]: https://www.ruby-lang.org/en/
[3]: http://bundler.io/ [3]: http://bundler.io/
[4]: https://www.algolia.com/users/sign_up/hacker [4]: https://www.algolia.com/users/sign_up/hacker
[5]: https://www.algolia.com/api-keys [5]: https://www.algolia.com/licensing
[6]: ./assets/images/getting-started.gif [6]: ./assets/images/getting-started.gif
[7]: ./commandline.html#algolia-api-key-file [7]: ./commandline.html#algolia-api-key-file
[8]: https://github.com/rvm/rubygems-bundler [8]: https://github.com/rvm/rubygems-bundler
[9]: https://community.algolia.com/instantsearch.js/ [9]: https://community.algolia.com/instantsearch.js/
[10]: https://community.algolia.com/vue-instantsearch/ [10]: https://community.algolia.com/vue-instantsearch/
[11]: https://community.algolia.com/react-instantsearch/ [11]: https://community.algolia.com/react-instantsearch/
[12]: https://community.algolia.com/angular-instantsearch/ [12]: ./blog.html
[13]: ./blog.html
[14]: https://www.algolia.com/press#resources

View File

@ -30,11 +30,11 @@ your GitHub Pages is done.
Here are the steps to follow to setup your Travis account for your project: Here are the steps to follow to setup your Travis account for your project:
- Go to [travis-ci.org][5] and open an account - Go to [travis-ci.org][5] and open an account
- Click on your avatar and "Profile" - Click on your avatar and "Accounts"
- Find your GitHub repository in the list and activate it - Find your GitHub repository in the list and activate it
_You should also uncheck the "Build pull request updates" in the options. _You should also uncheck the "Build pull request updates" in the options.
This will avoid re-indexing your data every time you receive a pull request._ This will avoid re-indexing your date every time you receive a pull request._
![Travis configuration](./assets/images/travis-config.png) ![Travis configuration](./assets/images/travis-config.png)
@ -50,8 +50,6 @@ keeping track of the configuration easier.
# This file should be at the root of your project # This file should be at the root of your project
language: ruby language: ruby
cache: bundler cache: bundler
before_install:
- gem install bundler
script: script:
- bundle exec jekyll algolia - bundle exec jekyll algolia
branches: branches:
@ -70,16 +68,6 @@ You might have to edit the `branches.only` value to either `master` or
`gh-pages`, depending on which branch is configured to be deployed in your `gh-pages`, depending on which branch is configured to be deployed in your
GitHub Pages configuration. GitHub Pages configuration.
### Ignoring vendors
Travis bundles all gems in the `vendor` directory on its servers, which Jekyll
will mistakenly read. This will likely make the process fail. To avoid this,
add `vendor` to the `exclude` list in your `_config.yml` file.
```yml
exclude: [vendor]
```
## Adding the API Key ## Adding the API Key
The plugin will need your Admin API key to push data. Because you don't want to The plugin will need your Admin API key to push data. Because you don't want to

View File

@ -67,21 +67,20 @@ end
## `before_indexing_each` ## `before_indexing_each`
This hook will be called on every single record before indexing them. It gives This hook will be called on every single record before indexing them. It gives you
you a way to edit the record before pushing it. You can use this hook to add, a way to edit the record before pushing it. You can use this hook to add, edit
edit or delete keys from the record. If the hook returns `nil`, the record will or delete keys from the record. If the hook returns `nil`, the
not be indexed. record will not be indexed.
The hook will receive three arguments: `record`, `node` and `context`. `record` The hook will receive two arguments: `record` and `node`. `record` is the hash
is the hash of the record, ready to be pushed to Algolia. `node` is of the record, ready to be pushed to Algolia. `node` is a [Nokogiri][5]
a [Nokogiri][5] representation of the HTML node the record was extracted from representation of the HTML node the record was extracted from (as specified in
(as specified in [nodes_to_index][6]). `context` gives more information about [nodes_to_index][6].
the whole indexing process (check the following table for more details).
| Key | Value | | Key | Value |
| ---- | ---- | | ---- | ---- |
| Signature | `before_indexing_each(record, node, context)` | | Signature | `before_indexing_each(record, node)` |
| Arguments | <ul><li>`record`: A hash of the record that will be pushed</li><li>`node`: A [Nokogiri][7] representation of the HTML node used to extract the content</li><li>`context`: More information about the whole website. <ul><li>`context.data`: Any data defined in the `_data` folder</li><li>`context.config`: Settings defined in `_config.yml`</li><li>`data.collections`: Custom collections and posts</li></ul></li></ul> | | Arguments | <ul><li>`record`: A hash of the record that will be pushed</li><li>`node`: A [Nokogiri][7] representation of the HTML node it was extracted from</li></ul> |
| Expected returns | <ul><li>A hash of the record to be indexed</li><li>`nil` if the record should not be indexed</li></ul> | | Expected returns | <ul><li>A hash of the record to be indexed</li><li>`nil` if the record should not be indexed</li></ul> |
### Example ### Example
@ -90,9 +89,9 @@ the whole indexing process (check the following table for more details).
module Jekyll module Jekyll
module Algolia module Algolia
module Hooks module Hooks
def self.before_indexing_each(record, node, context) def self.before_indexing_each(record, node)
# Do not index deprecation warnings # Do not index deprecation warnings
return nil if node.matches?('.deprecation-notice') return nil if node.attr('class') =~ 'deprecation-notice'
# Add my name as an author to each record # Add my name as an author to each record
record[:author] = 'Myself' record[:author] = 'Myself'
@ -105,22 +104,20 @@ end
## `before_indexing_all` ## `before_indexing_all`
This hook is similar to [before_index_each][8], but instead of being called This hook is very similar to [before_index_each][8], but instead of being called
on every record, it is called only once, on the full list of record, right on every record, it is called only once, on the full list of record, right
before pushing them. before pushing them.
It will be called with two arguments: `records` will be the full list of records It will be called with one argument, `records`, being the full list of records
to be pushed, and `context` will contain more information about the current to be pushed, and expects a list of records to be returned.
indexing (check the following table for more details). The method expects a list
of records to be returned.
You can use this hook to add, edit or delete complete records from the list, You can use this hook to add, edit or delete complete records from the list,
knowing the full context of what is going to be pushed. knowing the full context of what is going to be pushed.
| Key | Value | | Key | Value |
| ---- | ---- | | ---- | ---- |
| Signature | `before_indexing_all(records, context)` | | Signature | `before_indexing_all(records)` |
| Arguments | <ul><li>`records`: An array of hashes representing the records that are going to be pushed</li><li>`context`: More information about the whole website. <ul><li>`context.data`: Any data defined in the `_data` folder</li><li>`context.config`: Settings defined in `_config.yml`</li><li>`data.collections`: Custom collections and posts</li></ul></li></ul> | | Arguments | <ul><li>`records`: An array of hashes representing the records that are going to be pushed</li></ul> |
| Expected returns | <ul><li>An array of hashes to be pushed as records</li></ul> | | Expected returns | <ul><li>An array of hashes to be pushed as records</li></ul> |
### Example ### Example
@ -129,7 +126,7 @@ knowing the full context of what is going to be pushed.
module Jekyll module Jekyll
module Algolia module Algolia
module Hooks module Hooks
def self.before_indexing_all(records, context) def self.before_indexing_all(records)
# Add a tags array to each record # Add a tags array to each record
records.each do |record| records.each do |record|
record[:tags] = [] record[:tags] = []
@ -146,12 +143,11 @@ module Jekyll
end end
``` ```
[1]: ./options.html [1]: ./options.html
[2]: https://jekyllrb.com/docs/plugins/#installing-a-plugin [2]: https://jekyllrb.com/docs/plugins/#installing-a-plugin
[3]: ./options.html#extensions-to-index [3]: ./options.html#extensions-to-index
[4]: ./options.html#files-to-exclude [4]: ./options.html#files-to-exclude
[5]: http://www.nokogiri.org [5]: http://www.nokogiri.org
[6]: ./options.html#nodes-to-index [6]: ./options.html#nodes-to-index
[7]: https://github.com/sparklemotion/nokogiri/wiki/Cheat-sheet [7]: http://www.nokogiri.org
[8]: hooks.html#hook-before-indexing-each [8]: hooks.html#hook-before-indexing-each

View File

@ -6,8 +6,8 @@ layout: content-with-menu.pug
# How does this work? # How does this work?
This page will give you a bit more insight about how the internals of the plugin This page will give you a bit more insight about how the internals of the plugin
are working. This should give you more context to better understand the options are working. This should give you more context to better understand the various
you can configure. options you can configure.
## Extracting data ## Extracting data
@ -28,6 +28,9 @@ Here is an example of what a record looks like:
"title": "New experimental version of Hacker News Search built with Algolia", "title": "New experimental version of Hacker News Search built with Algolia",
"type": "post", "type": "post",
"url": "/2015/01/12/try-new-experimental-version-hn-search.html", "url": "/2015/01/12/try-new-experimental-version-hn-search.html",
"draft": false,
"layout": "post",
"ext": ".md",
"date": 1421017200, "date": 1421017200,
"excerpt_html": "<p>Exactly a year ago, we began to power […]</p>", "excerpt_html": "<p>Exactly a year ago, we began to power […]</p>",
"excerpt_text": "Exactly a year ago, we began to power […]", "excerpt_text": "Exactly a year ago, we began to power […]",
@ -35,12 +38,14 @@ Here is an example of what a record looks like:
"html": "<p>We've learned a lot from your comments […]</p>", "html": "<p>We've learned a lot from your comments […]</p>",
"content": "We've learned a lot from your comments […]", "content": "We've learned a lot from your comments […]",
"headings": [ "tag_name": "p",
"Applying more UI best practices", "hierarchy": {
"Focus on readability" "lvl0": null,
], "lvl1": "Applying more UI best practices",
"lvl2": "Focus on readability",
},
"anchor": "focus-on-readability", "anchor": "focus-on-readability",
"custom_ranking": { "weight": {
"position": 8, "position": 8,
"heading": 70 "heading": 70
} }
@ -50,37 +55,30 @@ Here is an example of what a record looks like:
Each record created that way will contain a mix of shared data and specific Each record created that way will contain a mix of shared data and specific
data. Shared data is the metadata of the page it was extracted from (`title`, data. Shared data is the metadata of the page it was extracted from (`title`,
`slug`, `url`, `tags`, etc, as well as any custom field added to the `slug`, `url`, `tags`, etc, as well as any custom field added to the
front-matter). Specific data is the paragraph content and, if applicable, the front-matter). Specific data is the paragraph content, and information
list of parent headings (based on the `<h1>` and `<h6>` of the page). about its position in the page (where its situated in the hierarchy of headings
in the page).
Using the [distinct setting][1] of the Algolia API, the best matching Using the [distinct setting][1] of the Algolia API, only the best matching
paragraph of each page is returned for a specific query. This greatly improves paragraph of each page is returned for a specific query. This greatly improves
the perceived relevance of the search results as you can highlight specifically the perceived relevance of the search results as you can highlight specifically
the part that was matching. the part that was matching.
Also note that the response you'll get from the API might be enriched with
[\_highlightResult][2] and [\_snippetResult][3] keys. Those keys are
automatically added when performing a search and are not part of the saved
record.
## Pushing data ## Pushing data
The plugin tries to be smart by using as less operations as possible, to be The plugin tries to be smart by using as less operations as possible, to be
mindful of your Algolia quota. Whenever you run `jekyll algolia`, records mindful of your Algolia quota. Whenever you run `jekyll algolia`, only records
that changed since your last push will be updated. that changed since your last push will be updated.
This is made possible because each record is attributed a unique `objectID`, This is made possible because each record is attributed a unique `objectID`,
computed as a hash of the actual content of the record. Whenever the content of computed as a hash of the actual content of the record. Whenever the content of
the record changes, its `objectID` will change as well. This allows us to the record changes, its `objectID` will change as well. This allows us to compare
compare what is available in your index and what is about to be what is current available in your index and what is about to be pushed, to only
pushed, to update what actually changed. update what actually changed.
Previous outdated records will be deleted, and new updated records will be added Previous outdated records will be deleted, and new updated records will be added
instead. All those operations are grouped into a batch call, making sure that instead. All those operations are grouped into a batch call, making sure that
the changes are done atomically: your index will never be in an inconsistent the changes are done atomically: your index will never be in an inconsistent
state where records are partially updated. state where records are only partially updated.
[1]: https://www.algolia.com/doc/guides/ranking/distinct/?language=ruby#distinct-to-index-large-records [1]: https://www.algolia.com/doc/guides/ranking/distinct/?language=ruby#distinct-to-index-large-records
[2]: https://www.algolia.com/doc/api-reference/api-methods/search/?language=ruby#method-response-_highlightresult
[3]: https://www.algolia.com/doc/api-reference/api-methods/search/?language=ruby#method-response-_snippetresult

View File

@ -17,7 +17,7 @@ section.footer-new-cta.footer-new.h300.pos-rel
.button-holder.h200.p-r-large .button-holder.h200.p-r-large
.spacer16.hidden-md.hidden-sm .spacer16.hidden-md.hidden-sm
span.inline.pos-rel span.inline.pos-rel
a.btn.btn-static-primary.btn-static-shadow-dark(href='https://www.algolia.com/users/sign_up/hacker') a.btn.btn-static-primary.btn-static-shadow-dark(href='https://algolia.com/users/sign_up')
| Get Started | Get Started
i.icon.icon-arrow-right.color-bunting.m-l-small i.icon.icon-arrow-right.color-bunting.m-l-small

View File

@ -86,6 +86,9 @@ Here is an example of a record extracted by the plugin:
"title": "New experimental version of Hacker News Search built with Algolia", "title": "New experimental version of Hacker News Search built with Algolia",
"type": "post", "type": "post",
"url": "/2015/01/12/try-new-experimental-version-hn-search.html", "url": "/2015/01/12/try-new-experimental-version-hn-search.html",
"draft": false,
"layout": "post",
"ext": ".md",
"date": 1421017200, "date": 1421017200,
"excerpt_html": "<p>Exactly a year ago, we began to power […]</p>", "excerpt_html": "<p>Exactly a year ago, we began to power […]</p>",
"excerpt_text": "Exactly a year ago, we began to power […]", "excerpt_text": "Exactly a year ago, we began to power […]",
@ -93,12 +96,14 @@ Here is an example of a record extracted by the plugin:
"html": "<p>We've learned a lot from your comments […]</p>", "html": "<p>We've learned a lot from your comments […]</p>",
"content": "We've learned a lot from your comments […]", "content": "We've learned a lot from your comments […]",
"headings": [ "tag_name": "p",
"Applying more UI best practices", "hierarchy": {
"Focus on readability" "lvl0": null,
], "lvl1": "Applying more UI best practices",
"lvl2": "Focus on readability",
},
"anchor": "focus-on-readability", "anchor": "focus-on-readability",
"custom_ranking": { "weight": {
"position": 8, "position": 8,
"heading": 70 "heading": 70
} }

View File

@ -26,21 +26,16 @@ you might want to update the value like this:
```yml ```yml
algolia: algolia:
# Also index AsciiDoc and Textile files # Also index AsciiDoc and Textile files
extensions_to_index: extensions_to_index: 'html,md,adoc,textile'
- html
- md
- adoc
- textile
``` ```
## `files_to_exclude` ## `files_to_exclude`
This option lets you define a list of source files you don't want to index. This option lets you define a blacklist of source files you don't want to index.
By default it will exclude the `index.html` and `index.md` files found at the By default it will exclude all the `index.html` and `index.md` files. Those
root. Those files are usually not containing much text (landing pages) or files are usually not containing much text (landing pages) or containing
containing redundant text (latest blog articles) so they are not included by redundant text (latest blog articles) so they are not included by default.
default.
If you want to index those files, you should set the value to an empty array. If you want to index those files, you should set the value to an empty array.
@ -51,7 +46,7 @@ algolia:
``` ```
If you want to exclude more files, you should add them to the array. Note that If you want to exclude more files, you should add them to the array. Note that
you can use glob patterns (`*` and `**`) to exclude several files at once. you can use glob patterns to exclude several files at once.
```yml ```yml
algolia: algolia:
@ -62,7 +57,6 @@ algolia:
- excluded-file.html - excluded-file.html
- _posts/2017-01-20-date-to-forget.md - _posts/2017-01-20-date-to-forget.md
- subdirectory/*.html - subdirectory/*.html
- **/*.tmp.html
``` ```
_Note that some files (pagination pages, static assets, etc) will **always** be _Note that some files (pagination pages, static assets, etc) will **always** be
@ -106,17 +100,7 @@ algolia:
``` ```
Settings defined here will take precedence over any setting you manually defined Settings defined here will take precedence over any setting you manually defined
through the [Algolia dashboard][5] UI, though. If you'd like this not to happen through the [Algolia dashboard][5] UI, though.
at all, and only take the dashboard settings in account, pass `false` to the
settings configuration.
```yml
algolia:
settings: false
```
We suggest users to at least run with the default settings once, so that the default
relevance settings are set, which you can override via the dashboard after.
## `indexing_batch_size` ## `indexing_batch_size`
@ -136,24 +120,6 @@ algolia:
indexing_batch_size: 500 indexing_batch_size: 500
``` ```
## `max_record_size`
**This is an advanced option. It has no effect on Community plans.**
If you're using a paid Algolia plan, you can push records that weight up to 20Kb
(as opposed to 10Kb with the free Community plan). This option allows you to
adjust the maximum size of one record (in bytes).
```yml
algolia:
# Recommended setting for paid plans
max_record_size: 20000
```
_Note that if you push a record that is larger than your allowed limit,
the push will be rejected by the API. This might result in incomplete data being
uploaded._
[1]: ./how-it-works.html [1]: ./how-it-works.html
[2]: http://www.methods.co.nz/asciidoc/ [2]: http://www.methods.co.nz/asciidoc/

View File

@ -127,7 +127,11 @@ $offset-height: 64px;
li { li {
line-height: 26px; line-height: 26px;
} } } &:before {
content: '-';
float: left;
margin-right: 6px;
color: $logan; } } } }
.content { .content {
position: relative; position: relative;

0
docs-src/src/stylesheets/vendors/bootstrap/_alerts.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_badges.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_breadcrumbs.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_button-groups.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_buttons.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_carousel.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_close.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_code.scss vendored Normal file → Executable file
View File

View File

0
docs-src/src/stylesheets/vendors/bootstrap/_dropdowns.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_forms.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_glyphicons.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_grid.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_input-groups.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_jumbotron.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_labels.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_list-group.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_media.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_mixins.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_modals.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_navbar.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_navs.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_normalize.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_pager.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_pagination.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_panels.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_popovers.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_print.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_progress-bars.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_responsive-embed.scss vendored Normal file → Executable file
View File

View File

0
docs-src/src/stylesheets/vendors/bootstrap/_scaffolding.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_tables.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_theme.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_thumbnails.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_tooltip.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_type.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_utilities.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_variables.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/_wells.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_alerts.scss vendored Normal file → Executable file
View File

View File

View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_buttons.scss vendored Normal file → Executable file
View File

View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_clearfix.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_forms.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_gradients.scss vendored Normal file → Executable file
View File

View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_grid.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_hide-text.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_image.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_labels.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_list-group.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_nav-divider.scss vendored Normal file → Executable file
View File

View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_opacity.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_pagination.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_panels.scss vendored Normal file → Executable file
View File

View File

View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_resize.scss vendored Normal file → Executable file
View File

View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_size.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_tab-focus.scss vendored Normal file → Executable file
View File

0
docs-src/src/stylesheets/vendors/bootstrap/mixins/_table-row.scss vendored Normal file → Executable file
View File

View File

Some files were not shown because too many files have changed in this diff Show More