arctic-vendor 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +51 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +2 -3
- data/documentation/CHANGELOG.md +137 -0
- data/documentation/CODE_OF_CONDUCT.md +46 -0
- data/documentation/Gemfile +11 -0
- data/documentation/Gemfile.lock +130 -0
- data/documentation/LICENSE +13 -0
- data/documentation/Procfile +1 -0
- data/documentation/README.md +118 -0
- data/documentation/build/fonts/slate.eot +0 -0
- data/documentation/build/fonts/slate.svg +14 -0
- data/documentation/build/fonts/slate.ttf +0 -0
- data/documentation/build/fonts/slate.woff +0 -0
- data/documentation/build/fonts/slate.woff2 +0 -0
- data/documentation/build/images/logo.png +0 -0
- data/documentation/build/images/navbar.png +0 -0
- data/documentation/build/index.html +564 -0
- data/documentation/build/javascripts/all.js +131 -0
- data/documentation/build/javascripts/all_nosearch.js +31 -0
- data/documentation/build/stylesheets/print.css +1 -0
- data/documentation/build/stylesheets/screen.css +1 -0
- data/documentation/config.rb +57 -0
- data/documentation/deploy.sh +215 -0
- data/documentation/font-selection.json +148 -0
- data/documentation/lib/multilang.rb +16 -0
- data/documentation/lib/nesting_unique_head.rb +22 -0
- data/documentation/lib/toc_data.rb +30 -0
- data/documentation/lib/unique_head.rb +24 -0
- data/documentation/source/fonts/slate.eot +0 -0
- data/documentation/source/fonts/slate.svg +14 -0
- data/documentation/source/fonts/slate.ttf +0 -0
- data/documentation/source/fonts/slate.woff +0 -0
- data/documentation/source/fonts/slate.woff2 +0 -0
- data/documentation/source/images/logo.png +0 -0
- data/documentation/source/images/navbar.png +0 -0
- data/documentation/source/includes/_errors.md +17 -0
- data/documentation/source/index.html.md +150 -0
- data/documentation/source/javascripts/all.js +2 -0
- data/documentation/source/javascripts/all_nosearch.js +16 -0
- data/documentation/source/javascripts/app/_lang.js +164 -0
- data/documentation/source/javascripts/app/_search.js +98 -0
- data/documentation/source/javascripts/app/_toc.js +114 -0
- data/documentation/source/javascripts/lib/_energize.js +169 -0
- data/documentation/source/javascripts/lib/_imagesloaded.min.js +7 -0
- data/documentation/source/javascripts/lib/_jquery.highlight.js +108 -0
- data/documentation/source/javascripts/lib/_jquery.js +9831 -0
- data/documentation/source/javascripts/lib/_lunr.js +1910 -0
- data/documentation/source/layouts/layout.erb +116 -0
- data/documentation/source/stylesheets/_icon-font.scss +38 -0
- data/documentation/source/stylesheets/_normalize.scss +427 -0
- data/documentation/source/stylesheets/_rtl.scss +140 -0
- data/documentation/source/stylesheets/_variables.scss +103 -0
- data/documentation/source/stylesheets/_variables2.scss +147 -0
- data/documentation/source/stylesheets/print.css.scss +148 -0
- data/documentation/source/stylesheets/screen.css.scss +712 -0
- data/lib/arctic/vendor/api.rb +38 -4
- data/lib/arctic/vendor/product.rb +47 -0
- data/lib/arctic/vendor/vendor.rb +7 -6
- data/lib/arctic/vendor/version.rb +1 -1
- data/vendor.gemspec +1 -1
- metadata +57 -16
@@ -0,0 +1,16 @@
|
|
1
|
+
module Multilang
|
2
|
+
def block_code(code, full_lang_name)
|
3
|
+
if full_lang_name
|
4
|
+
parts = full_lang_name.split('--')
|
5
|
+
rouge_lang_name = (parts) ? parts[0] : "" # just parts[0] here causes null ref exception when no language specified
|
6
|
+
super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match|
|
7
|
+
match + " tab-" + full_lang_name
|
8
|
+
end
|
9
|
+
else
|
10
|
+
super(code, full_lang_name)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
require 'middleman-core/renderers/redcarpet'
|
16
|
+
Middleman::Renderers::MiddlemanRedcarpetHTML.send :include, Multilang
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Nested unique header generation
|
2
|
+
require 'middleman-core/renderers/redcarpet'
|
3
|
+
|
4
|
+
class NestingUniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@@headers_history = {} if !defined?(@@headers_history)
|
8
|
+
end
|
9
|
+
|
10
|
+
def header(text, header_level)
|
11
|
+
friendly_text = text.parameterize
|
12
|
+
@@headers_history[header_level] = text.parameterize
|
13
|
+
|
14
|
+
if header_level > 1
|
15
|
+
for i in (header_level - 1).downto(1)
|
16
|
+
friendly_text.prepend("#{@@headers_history[i]}-") if @@headers_history.key?(i)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
return "<h#{header_level} id='#{friendly_text}'>#{text}</h#{header_level}>"
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
def toc_data(page_content)
|
4
|
+
html_doc = Nokogiri::HTML::DocumentFragment.parse(page_content)
|
5
|
+
|
6
|
+
# get a flat list of headers
|
7
|
+
headers = []
|
8
|
+
html_doc.css('h1, h2, h3').each do |header|
|
9
|
+
headers.push({
|
10
|
+
id: header.attribute('id').to_s,
|
11
|
+
content: header.children,
|
12
|
+
level: header.name[1].to_i,
|
13
|
+
children: []
|
14
|
+
})
|
15
|
+
end
|
16
|
+
|
17
|
+
[3,2].each do |header_level|
|
18
|
+
header_to_nest = nil
|
19
|
+
headers = headers.reject do |header|
|
20
|
+
if header[:level] == header_level
|
21
|
+
header_to_nest[:children].push header if header_to_nest
|
22
|
+
true
|
23
|
+
else
|
24
|
+
header_to_nest = header if header[:level] < header_level
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
headers
|
30
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Unique header generation
|
2
|
+
require 'middleman-core/renderers/redcarpet'
|
3
|
+
require 'digest'
|
4
|
+
class UniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@head_count = {}
|
8
|
+
end
|
9
|
+
def header(text, header_level)
|
10
|
+
friendly_text = text.gsub(/<[^<]+>/,"").parameterize
|
11
|
+
if friendly_text.strip.length == 0
|
12
|
+
# Looks like parameterize removed the whole thing! It removes many unicode
|
13
|
+
# characters like Chinese and Russian. To get a unique URL, let's just
|
14
|
+
# URI escape the whole header
|
15
|
+
friendly_text = Digest::SHA1.hexdigest(text)[0,10]
|
16
|
+
end
|
17
|
+
@head_count[friendly_text] ||= 0
|
18
|
+
@head_count[friendly_text] += 1
|
19
|
+
if @head_count[friendly_text] > 1
|
20
|
+
friendly_text += "-#{@head_count[friendly_text]}"
|
21
|
+
end
|
22
|
+
return "<h#{header_level} id='#{friendly_text}'>#{text}</h#{header_level}>"
|
23
|
+
end
|
24
|
+
end
|
Binary file
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg">
|
4
|
+
<metadata>Generated by IcoMoon</metadata>
|
5
|
+
<defs>
|
6
|
+
<font id="slate" horiz-adv-x="1024">
|
7
|
+
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
8
|
+
<missing-glyph horiz-adv-x="1024" />
|
9
|
+
<glyph unicode=" " d="" horiz-adv-x="512" />
|
10
|
+
<glyph unicode="" d="M438.857 877.714q119.429 0 220.286-58.857t159.714-159.714 58.857-220.286-58.857-220.286-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857zM512 165.143v108.571q0 8-5.143 13.429t-12.571 5.429h-109.714q-7.429 0-13.143-5.714t-5.714-13.143v-108.571q0-7.429 5.714-13.143t13.143-5.714h109.714q7.429 0 12.571 5.429t5.143 13.429zM510.857 361.714l10.286 354.857q0 6.857-5.714 10.286-5.714 4.571-13.714 4.571h-125.714q-8 0-13.714-4.571-5.714-3.429-5.714-10.286l9.714-354.857q0-5.714 5.714-10t13.714-4.286h105.714q8 0 13.429 4.286t6 10z" />
|
11
|
+
<glyph unicode="" d="M585.143 164.571v91.429q0 8-5.143 13.143t-13.143 5.143h-54.857v292.571q0 8-5.143 13.143t-13.143 5.143h-182.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h54.857v-182.857h-54.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h256q8 0 13.143 5.143t5.143 13.143zM512 676.571v91.429q0 8-5.143 13.143t-13.143 5.143h-109.714q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h109.714q8 0 13.143 5.143t5.143 13.143zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
|
12
|
+
<glyph unicode="" d="M733.714 531.428q0 16-10.286 26.286l-52 51.429q-10.857 10.857-25.714 10.857t-25.714-10.857l-233.143-232.571-129.143 129.143q-10.857 10.857-25.714 10.857t-25.714-10.857l-52-51.429q-10.286-10.286-10.286-26.286 0-15.429 10.286-25.714l206.857-206.857q10.857-10.857 25.714-10.857 15.429 0 26.286 10.857l310.286 310.286q10.286 10.286 10.286 25.714zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
|
13
|
+
<glyph unicode="" d="M658.286 475.428q0 105.714-75.143 180.857t-180.857 75.143-180.857-75.143-75.143-180.857 75.143-180.857 180.857-75.143 180.857 75.143 75.143 180.857zM950.857 0q0-29.714-21.714-51.429t-51.429-21.714q-30.857 0-51.429 21.714l-196 195.429q-102.286-70.857-228-70.857-81.714 0-156.286 31.714t-128.571 85.714-85.714 128.571-31.714 156.286 31.714 156.286 85.714 128.571 128.571 85.714 156.286 31.714 156.286-31.714 128.571-85.714 85.714-128.571 31.714-156.286q0-125.714-70.857-228l196-196q21.143-21.143 21.143-51.429z" horiz-adv-x="951" />
|
14
|
+
</font></defs></svg>
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Errors
|
2
|
+
|
3
|
+
> Example error response
|
4
|
+
|
5
|
+
```json
|
6
|
+
{
|
7
|
+
"error": "Unauthorized",
|
8
|
+
"description": "Invalid or missing Bearer token Authentication header"
|
9
|
+
}
|
10
|
+
```
|
11
|
+
|
12
|
+
The Arctic Core API uses the [HTTP status codes](httpstatuses.com) list. Here is some additional explenations for some of the HTTP status codes.
|
13
|
+
|
14
|
+
Error Code | Meaning
|
15
|
+
---------- | -------
|
16
|
+
401 | Unauthorized -- Your Vendor token is incorrect or missing.
|
17
|
+
403 | Forbidden -- Your Vendor token doesn't have the proper permissions for the action.
|
@@ -0,0 +1,150 @@
|
|
1
|
+
---
|
2
|
+
title: API Reference
|
3
|
+
|
4
|
+
language_tabs: # must be one of https://git.io/vQNgJ
|
5
|
+
- ruby
|
6
|
+
|
7
|
+
toc_footers:
|
8
|
+
- <a href='https://arctic-project.dk/vendor/register' target="_blank">Register a Vendor</a>
|
9
|
+
- <a href='https://arctic-project.io' target="_blank">Core API documentation</a>
|
10
|
+
- <a href='https://github.com/YouWeApS/arctic-vendor/issues' target="_blank">Found a bug?</a>
|
11
|
+
|
12
|
+
includes:
|
13
|
+
- errors
|
14
|
+
|
15
|
+
search: true
|
16
|
+
---
|
17
|
+
|
18
|
+
# Introduction
|
19
|
+
|
20
|
+
The Arctic Vendor project is a wrapper around the [Arcic Core API](https://arctic-project.io).
|
21
|
+
|
22
|
+
An Arctic Vendor is an application that connects a marketplace to the Arctic platform.
|
23
|
+
|
24
|
+
This project looks to simplify setting up these vendors and thus simplifying the onboarding of new marketplaces for the merchangs on the Arctic platform.
|
25
|
+
|
26
|
+
An Arctic Vendor has two aspects to it: Collection and distribution.
|
27
|
+
|
28
|
+
**Collecting products** means tranforming (possibly) unstructured product data
|
29
|
+
from the marketplace into structured data.
|
30
|
+
|
31
|
+
**Distributing products** means sending structured products onto the connected
|
32
|
+
marketplace.
|
33
|
+
|
34
|
+
# Setup
|
35
|
+
|
36
|
+
> To install in your project
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
gem 'arctic-vendor', '~> 2.2'
|
40
|
+
```
|
41
|
+
|
42
|
+
First you must [register your Vendor](https://arctic-project.dk/vendor/register)
|
43
|
+
with the Core API to obtain a Vendor Token.
|
44
|
+
|
45
|
+
In order to connect to the Arctici Core API, you need to have a Vendor Token,
|
46
|
+
and you need to store this token in the `ARCTIC_CORE_API_TOKEN` environment
|
47
|
+
variable.
|
48
|
+
|
49
|
+
If you need to run your application against another environment you can override
|
50
|
+
the URL by setting the `ARCTIC_CORE_API_URL` environment variable.
|
51
|
+
|
52
|
+
# Object descriptions
|
53
|
+
|
54
|
+
### Shop
|
55
|
+
|
56
|
+
A single object.
|
57
|
+
|
58
|
+
Parameter | Description
|
59
|
+
--------- | -----------
|
60
|
+
id | Shop ID
|
61
|
+
name | Human friendly shop name
|
62
|
+
synced_at | [ISO 8601 HTTP date](https://en.wikipedia.org/wiki/ISO_8601)
|
63
|
+
auth_config | Sensitive marketplace authentication information
|
64
|
+
config | Non-sensitive, general configuration set for the shop
|
65
|
+
format_config | JSON formatting instructions
|
66
|
+
|
67
|
+
<aside class="notice">
|
68
|
+
All <code>*config</code> fields are filled or enhanced by the merchant when
|
69
|
+
configuring the Vendor to distribute products through the Vendor's marketplace.
|
70
|
+
When registering the vendor with the Core API, JSON schema definitions for these
|
71
|
+
fields must be supplied by the Vendor developer.
|
72
|
+
</aside>
|
73
|
+
|
74
|
+
### Products
|
75
|
+
|
76
|
+
An array of product objects.
|
77
|
+
|
78
|
+
Parameter | Description
|
79
|
+
--------- | -----------
|
80
|
+
id | Product ID
|
81
|
+
characteristics | Normalized product characteristics
|
82
|
+
master | Product is master. Will have a Product ID value if this product is a variant of another.
|
83
|
+
state | Last known product state. Can be <code>created</code>, <code>updated</code>, or <code>deleted</code>
|
84
|
+
|
85
|
+
### Product characteristics
|
86
|
+
|
87
|
+
Name | Description
|
88
|
+
---- | -----------
|
89
|
+
name | Human readable product name
|
90
|
+
description | Human readable description of the product
|
91
|
+
color | Color
|
92
|
+
size | Size
|
93
|
+
ean | EAN number
|
94
|
+
price | Price without currency
|
95
|
+
currency | [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code
|
96
|
+
stock | Stock count
|
97
|
+
images | Array of image URLs
|
98
|
+
|
99
|
+
# Collecting products
|
100
|
+
|
101
|
+
> Collect products from the marketplace
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
Arctic::Vendor.collect_products do |shop|
|
105
|
+
# 1. Connect to the marketplace and retrieve the products for the shop
|
106
|
+
|
107
|
+
# 2. Format each of the products according to the shop's format_config
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
First, initialize the `Vendor.collect_products` method to receive each of the
|
112
|
+
shops that your vendor should process.
|
113
|
+
|
114
|
+
Then retrieve the products for that shop, and return them to the block, and the
|
115
|
+
Vendor Project will send them to the Core API.
|
116
|
+
|
117
|
+
The products you return to the block should be a JSON array of products, each
|
118
|
+
formatted according to the `shop`s `format_config` block.
|
119
|
+
|
120
|
+
# Distributing products
|
121
|
+
|
122
|
+
> Distribute products to the marketplace
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
Arctic::Vendor.distribute_products(batch_size: 300) do |shop, product_batch|
|
126
|
+
# 1. Connect to the marketplace and publish the products to the shop
|
127
|
+
product_batch.each do |product|
|
128
|
+
# 2. As each of the products are published, update the state
|
129
|
+
product.update_state 'created'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
First, initialize the `Vendor.distribute_products` method to receive each of the
|
135
|
+
shops and batches of related products to distribute to the marketplace.
|
136
|
+
|
137
|
+
Then connect to the marketplace and distribute the products to the shop.
|
138
|
+
|
139
|
+
<aside class="notice">
|
140
|
+
<code>Arctic::Vendor.distribute_products</code> returns products in batches of 100 by default.
|
141
|
+
</aside>
|
142
|
+
|
143
|
+
# Going live
|
144
|
+
|
145
|
+
When you have fully developed your Vendor, you will have to go through a
|
146
|
+
verification and testing process with the Arctic Team.
|
147
|
+
|
148
|
+
Once you pass this verification process your Vendor will be released into
|
149
|
+
production and merchants can distribute their products through your Vendor to
|
150
|
+
the marketplace.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
//= require ./lib/_energize
|
2
|
+
//= require ./app/_toc
|
3
|
+
//= require ./app/_lang
|
4
|
+
|
5
|
+
$(function() {
|
6
|
+
loadToc($('#toc'), '.toc-link', '.toc-list-h2', 10);
|
7
|
+
setupLanguages($('body').data('languages'));
|
8
|
+
$('.content').imagesLoaded( function() {
|
9
|
+
window.recacheHeights();
|
10
|
+
window.refreshToc();
|
11
|
+
});
|
12
|
+
});
|
13
|
+
|
14
|
+
window.onpopstate = function() {
|
15
|
+
activateLanguage(getLanguageFromQueryString());
|
16
|
+
};
|
@@ -0,0 +1,164 @@
|
|
1
|
+
//= require ../lib/_jquery
|
2
|
+
|
3
|
+
/*
|
4
|
+
Copyright 2008-2013 Concur Technologies, Inc.
|
5
|
+
|
6
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
7
|
+
not use this file except in compliance with the License. You may obtain
|
8
|
+
a copy of the License at
|
9
|
+
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
|
12
|
+
Unless required by applicable law or agreed to in writing, software
|
13
|
+
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
14
|
+
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
15
|
+
License for the specific language governing permissions and limitations
|
16
|
+
under the License.
|
17
|
+
*/
|
18
|
+
;(function () {
|
19
|
+
'use strict';
|
20
|
+
|
21
|
+
var languages = [];
|
22
|
+
|
23
|
+
window.setupLanguages = setupLanguages;
|
24
|
+
window.activateLanguage = activateLanguage;
|
25
|
+
window.getLanguageFromQueryString = getLanguageFromQueryString;
|
26
|
+
|
27
|
+
function activateLanguage(language) {
|
28
|
+
if (!language) return;
|
29
|
+
if (language === "") return;
|
30
|
+
|
31
|
+
$(".lang-selector a").removeClass('active');
|
32
|
+
$(".lang-selector a[data-language-name='" + language + "']").addClass('active');
|
33
|
+
for (var i=0; i < languages.length; i++) {
|
34
|
+
$(".highlight.tab-" + languages[i]).hide();
|
35
|
+
$(".lang-specific." + languages[i]).hide();
|
36
|
+
}
|
37
|
+
$(".highlight.tab-" + language).show();
|
38
|
+
$(".lang-specific." + language).show();
|
39
|
+
|
40
|
+
window.recacheHeights();
|
41
|
+
|
42
|
+
// scroll to the new location of the position
|
43
|
+
if ($(window.location.hash).get(0)) {
|
44
|
+
$(window.location.hash).get(0).scrollIntoView(true);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
// parseURL and stringifyURL are from https://github.com/sindresorhus/query-string
|
49
|
+
// MIT licensed
|
50
|
+
// https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license
|
51
|
+
function parseURL(str) {
|
52
|
+
if (typeof str !== 'string') {
|
53
|
+
return {};
|
54
|
+
}
|
55
|
+
|
56
|
+
str = str.trim().replace(/^(\?|#|&)/, '');
|
57
|
+
|
58
|
+
if (!str) {
|
59
|
+
return {};
|
60
|
+
}
|
61
|
+
|
62
|
+
return str.split('&').reduce(function (ret, param) {
|
63
|
+
var parts = param.replace(/\+/g, ' ').split('=');
|
64
|
+
var key = parts[0];
|
65
|
+
var val = parts[1];
|
66
|
+
|
67
|
+
key = decodeURIComponent(key);
|
68
|
+
// missing `=` should be `null`:
|
69
|
+
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
|
70
|
+
val = val === undefined ? null : decodeURIComponent(val);
|
71
|
+
|
72
|
+
if (!ret.hasOwnProperty(key)) {
|
73
|
+
ret[key] = val;
|
74
|
+
} else if (Array.isArray(ret[key])) {
|
75
|
+
ret[key].push(val);
|
76
|
+
} else {
|
77
|
+
ret[key] = [ret[key], val];
|
78
|
+
}
|
79
|
+
|
80
|
+
return ret;
|
81
|
+
}, {});
|
82
|
+
};
|
83
|
+
|
84
|
+
function stringifyURL(obj) {
|
85
|
+
return obj ? Object.keys(obj).sort().map(function (key) {
|
86
|
+
var val = obj[key];
|
87
|
+
|
88
|
+
if (Array.isArray(val)) {
|
89
|
+
return val.sort().map(function (val2) {
|
90
|
+
return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
|
91
|
+
}).join('&');
|
92
|
+
}
|
93
|
+
|
94
|
+
return encodeURIComponent(key) + '=' + encodeURIComponent(val);
|
95
|
+
}).join('&') : '';
|
96
|
+
};
|
97
|
+
|
98
|
+
// gets the language set in the query string
|
99
|
+
function getLanguageFromQueryString() {
|
100
|
+
if (location.search.length >= 1) {
|
101
|
+
var language = parseURL(location.search).language;
|
102
|
+
if (language) {
|
103
|
+
return language;
|
104
|
+
} else if (jQuery.inArray(location.search.substr(1), languages) != -1) {
|
105
|
+
return location.search.substr(1);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
return false;
|
110
|
+
}
|
111
|
+
|
112
|
+
// returns a new query string with the new language in it
|
113
|
+
function generateNewQueryString(language) {
|
114
|
+
var url = parseURL(location.search);
|
115
|
+
if (url.language) {
|
116
|
+
url.language = language;
|
117
|
+
return stringifyURL(url);
|
118
|
+
}
|
119
|
+
return language;
|
120
|
+
}
|
121
|
+
|
122
|
+
// if a button is clicked, add the state to the history
|
123
|
+
function pushURL(language) {
|
124
|
+
if (!history) { return; }
|
125
|
+
var hash = window.location.hash;
|
126
|
+
if (hash) {
|
127
|
+
hash = hash.replace(/^#+/, '');
|
128
|
+
}
|
129
|
+
history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash);
|
130
|
+
|
131
|
+
// save language as next default
|
132
|
+
localStorage.setItem("language", language);
|
133
|
+
}
|
134
|
+
|
135
|
+
function setupLanguages(l) {
|
136
|
+
var defaultLanguage = localStorage.getItem("language");
|
137
|
+
|
138
|
+
languages = l;
|
139
|
+
|
140
|
+
var presetLanguage = getLanguageFromQueryString();
|
141
|
+
if (presetLanguage) {
|
142
|
+
// the language is in the URL, so use that language!
|
143
|
+
activateLanguage(presetLanguage);
|
144
|
+
|
145
|
+
localStorage.setItem("language", presetLanguage);
|
146
|
+
} else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) {
|
147
|
+
// the language was the last selected one saved in localstorage, so use that language!
|
148
|
+
activateLanguage(defaultLanguage);
|
149
|
+
} else {
|
150
|
+
// no language selected, so use the default
|
151
|
+
activateLanguage(languages[0]);
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
// if we click on a language tab, activate that language
|
156
|
+
$(function() {
|
157
|
+
$(".lang-selector a").on("click", function() {
|
158
|
+
var language = $(this).data("language-name");
|
159
|
+
pushURL(language);
|
160
|
+
activateLanguage(language);
|
161
|
+
return false;
|
162
|
+
});
|
163
|
+
});
|
164
|
+
})();
|