Initial version

This commit is contained in:
Clement G 2017-07-22 16:07:01 +02:00
parent e20ab188ba
commit 0c0f11370c
73 changed files with 583 additions and 2 deletions

50
CHANGELOG.md Normal file
View File

@ -0,0 +1,50 @@
# v1.4.0
## 06/29/2017
1. [](#new)
* Added the `untranslated_pages_behavior` option to determine what to do with a language link when the current page doesn't exist in that language or it exists but it's not published
1. [](#bugfix)
* Fixed generated URLs when `append_url_extension` is set, via PR [#22](https://github.com/getgrav/grav-plugin-langswitcher/pull/22)
# v1.3.0
## 02/17/2017
1. [](#new)
* Added support for `hreflang` annotations via PR [#19](https://github.com/getgrav/grav-plugin-langswitcher/pull/19)
# v1.2.1
## 05/28/2016
1. [](#bugfix)
* Display all language names, even those with non supported locales
# v1.2.0
## 05/03/2016
1. [](#improved)
* Take URI parameters into account when switching languages
* Add `external` class to avoid problems on modular pages when `jquery.singlePageNav` is loaded
# v1.1.0
## 10/15/2015
1. [](#improved)
* Added active class to language links
# v1.0.2
## 07/13/2015
1. [](#improved)
* Improved homepage routing
# v1.0.1
## 07/08/2015
1. [](#improved)
* Updated blueprints with some typo fixes
# v1.0.0
## 07/08/2015
1. [](#new)
* ChangeLog started...

View File

@ -1,6 +1,6 @@
MIT License
The MIT License (MIT)
Copyright (c) 2017
Copyright (c) 2017 Clemdesign (http://www.clemdesign.fr)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

85
README.md Normal file
View File

@ -0,0 +1,85 @@
# Grav Language Selector Plugin
![Language Selector](assets/readme_1.jpg)
`Language Selector` is a [Grav](http://github.com/getgrav/grav) plugin that provides native language selector with flags to switch between [Multiple Languages](http://learn.getgrav.org/content/multi-language).
# Installation
Installing the Language Selector plugin can be done only manually for this moment. GPM installation is not yet available
## Manual Installation
To install this plugin, just download the zip version of this repository and unzip it under `user/plugins`. Then, rename the folder to `language-selector`. You can find these files either on [GitHub](https://github.com/clemdesign/grav-plugin-language-selector).
You should now have all the plugin files under
/yoursite/user/plugins/language-selector
Other way is to use `GIT`. In `user/plugins` folder, apply the following command:
```
git clone https://github.com/clemdesign/grav-plugin-language-selector language-selector
```
This will clone this repository into the _language-selector_ folder.
# Usage
The `Language Selector` plugin doesn't require any configuration. You do however need to add the included Twig partials template into your own theme somewhere you want the available languages to be displayed.
```
{% include 'partials/language-selector.html.twig' %}
```
Something you might want to do is to override the look and feel of the langswitcher, and with Grav it is super easy.
Copy the template file [language-selector.html.twig](templates/partials/language-selector.html.twig) into the `templates` folder of your custom theme:
```
/yoursite/user/themes/custom-theme/templates/partials/language-selector.html.twig
```
You can now edit the override and tweak it however you prefer.
## Usage of the `hreflang` partial
A second template is available for `hreflang` annotations in the header of the page. In order to emit language annotations for the available languages of a page you need to add the corrsponding Twig partial template into the `<head>` section of your page, which can typically be found in `base.html.twig`:
```
{% include 'partials/language-selector.hreflang.html.twig' %}
```
This will generate something like:
```
<link rel="alternate" href="http://example.com/en" hreflang="en" />
<link rel="alternate" href="http://example.com/fr" hreflang="fr" />
<link rel="alternate" href="http://example.com/zh-cn" hreflang="zh-cn" />
```
# Configuration
## Plugin
Simply copy the `user/plugins/language-selector/language-selector.yaml` into `user/config/plugins/language-selector.yaml` and make your modifications.
```
enabled: true
built_in_css: true
button_display: default
select_display: default
```
Options are pretty self explanatory.
## Redirecting after switching language
To have Grav redirect to the default page route after switching language, you must add the following configuration to `user/config/system.yaml`
```
pages:
redirect_default_route: true
```
# Credits
[Language Selector](https://github.com/clemdesign/grav-plugin-language-selector) is based on [Lang Switcher](https://github.com/getgrav/grav-plugin-langswitcher) plugin.

BIN
assets/readme_1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

68
blueprints.yaml Normal file
View File

@ -0,0 +1,68 @@
name: Language Selector
version: 1.0.0
description: Language Selector is a [Grav](http://github.com/getgrav/grav) plugin that provides native language selector with flags to switch between [multiple languages](http://learn.getgrav.org/content/multi-language).
icon: globe
author:
name: Clément G.
email: contact@clemdesign.fr
url: http://www.clemdesign.fr
homepage: https://github.com/clemdesign/grav-plugin-language-selector
keywords: mulitlang, multilanguage, translation, switcher, selector, flag
bugs: https://github.com/clemdesign/grav-plugin-language-selector/issues
docs: https://github.com/clemdesign/grav-plugin-language-selector/blob/master/README.md
license: MIT
form:
validation: strict
fields:
enabled:
type: toggle
label: PLUGINS.LANGUAGE_SELECTOR.PLUGIN_STATUS
highlight: 1
default: 1
options:
1: PLUGIN_ADMIN.ENABLED
0: PLUGIN_ADMIN.DISABLED
validate:
type: bool
built_in_css:
type: toggle
label: PLUGINS.LANGUAGE_SELECTOR.BUILT_IN_CSS
highlight: 1
default: 1
options:
1: PLUGIN_ADMIN.ENABLED
0: PLUGIN_ADMIN.DISABLED
validate:
type: bool
untranslated_pages_behavior:
type: select
label: PLUGINS.LANGUAGE_SELECTOR.UNTRANSLATED_PAGES.LABEL
help: PLUGINS.LANGUAGE_SELECTOR.UNTRANSLATED_PAGES.HELP
default: none
options:
none: PLUGINS.LANGUAGE_SELECTOR.UNTRANSLATED_PAGES.OPT_NONE
redirect: PLUGINS.LANGUAGE_SELECTOR.UNTRANSLATED_PAGES.OPT_REDIR
hide: PLUGINS.LANGUAGE_SELECTOR.UNTRANSLATED_PAGES.OPT_HIDE
button_display:
type: select
label: PLUGINS.LANGUAGE_SELECTOR.BUTTON_DISPLAY.LABEL
help: PLUGINS.LANGUAGE_SELECTOR.BUTTON_DISPLAY.HELP
default: default
options:
default: PLUGINS.LANGUAGE_SELECTOR.SELECT_DISPLAY.OPT_DEFAULT
flag: PLUGINS.LANGUAGE_SELECTOR.SELECT_DISPLAY.OPT_FLAG
name: PLUGINS.LANGUAGE_SELECTOR.SELECT_DISPLAY.OPT_NAME
select_display:
type: select
label: PLUGINS.LANGUAGE_SELECTOR.SELECT_DISPLAY.LABEL
help: PLUGINS.LANGUAGE_SELECTOR.SELECT_DISPLAY.HELP
default: default
options:
default: PLUGINS.LANGUAGE_SELECTOR.SELECT_DISPLAY.OPT_DEFAULT
flag: PLUGINS.LANGUAGE_SELECTOR.SELECT_DISPLAY.OPT_FLAG
name: PLUGINS.LANGUAGE_SELECTOR.SELECT_DISPLAY.OPT_NAME

87
css/language-selector.css Normal file
View File

@ -0,0 +1,87 @@
.language-selector {
float: right;
position: relative;
top: 50%;
vertical-align: middle;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-o-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
margin: 0 1rem !important;
display: inline-block;
}
.language-selector>.btn:first-child {
margin-left: 0;
}
.language-selector .btn {
float: left;
position: relative;
display: inline-block;
margin-bottom: 0;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
touch-action: manipulation;
cursor: pointer;
user-select: none;
background-image: none;
border: 1px solid transparent;
/* size */
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
/* Aspect */
color: #333;
background-color: #fff;
border-color: #ccc;
}
.language-selector .dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
list-style: none;
background-color: #fff;
background-clip: padding-box;
border-radius: 4px;
box-shadow: 0 6px 12px rgba(0,0,0,.175);
}
.language-selector .dropdown-menu img {
width: 24px;
height: 12px;
max-width: inherit;
}
.language-selector .dropdown-menu li {
line-height: 1rem;
font-color: #c0c0c0;
display: list-item;
text-align: -webkit-match-parent;
}
.language-selector .dropdown-menu li:hover {
background-color: #eee;
}
.language-selector .dropdown-menu>li>a {
display: block;
padding: 3px 15px;
clear: both;
font-weight: 400;
line-height: 1.42857143;
color: #333;
white-space: nowrap;
}

BIN
flags/af.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

BIN
flags/ar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

BIN
flags/be.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

BIN
flags/bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

BIN
flags/bo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

BIN
flags/ca.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

BIN
flags/cs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

BIN
flags/da.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

BIN
flags/de.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

BIN
flags/el.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 B

BIN
flags/en.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

BIN
flags/eo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

BIN
flags/es.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

BIN
flags/et.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

BIN
flags/eu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

BIN
flags/fa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

BIN
flags/fi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

BIN
flags/fil.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

BIN
flags/fo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

BIN
flags/fr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

BIN
flags/ga.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

BIN
flags/gl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

BIN
flags/he.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

BIN
flags/hi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

BIN
flags/hr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

BIN
flags/hu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

BIN
flags/id.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

BIN
flags/is.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

BIN
flags/it.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

BIN
flags/ja.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

BIN
flags/km.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

BIN
flags/ko.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

BIN
flags/lb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

BIN
flags/lt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

BIN
flags/lv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

BIN
flags/mn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

BIN
flags/ms.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

BIN
flags/nb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

BIN
flags/nl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

BIN
flags/nn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 B

BIN
flags/pl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 B

BIN
flags/pt-br.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

BIN
flags/pt-pt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

BIN
flags/ro.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 B

BIN
flags/ru.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 B

BIN
flags/sco.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

BIN
flags/se.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

BIN
flags/sk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

BIN
flags/sl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

BIN
flags/so.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

BIN
flags/sq.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

BIN
flags/sr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

BIN
flags/sv.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

BIN
flags/tg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

BIN
flags/th.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

BIN
flags/tl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

BIN
flags/tr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

BIN
flags/uk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

BIN
flags/vi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

BIN
flags/zh-hans.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

BIN
flags/zh-hant.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

76
js/language-selector.js Normal file
View File

@ -0,0 +1,76 @@
/*!
* Language Selector JS plugin
* Copyright 2017 Clement G., Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
var dropdownmenu={
animspeed: 200, //reveal animation speed (in milliseconds)
showhidedelay: [150, 150], //delay before menu appears and disappears when mouse rolls over it, in milliseconds
//***** NO NEED TO EDIT BEYOND HERE
builtdropdownids: [], //ids of dropdown already built (to prevent repeated building of same dropdown)
showbox:function($, $dropdown, e){
clearTimeout($dropdown.data('timers').hidetimer)
$dropdown.data('timers').showtimer=setTimeout(function(){$dropdown.show(dropdownmenu.animspeed)}, this.showhidedelay[0])
},
hidebox:function($, $dropdown){
clearTimeout($dropdown.data('timers').showtimer)
$dropdown.data('timers').hidetimer=setTimeout(function(){$dropdown.hide(100)}, this.showhidedelay[1]) //hide dropdown plus all of its sub ULs
},
builddropdown:function($, $menu, $target){
$menu.css({display:'none'}).addClass('jqdropdown')
$menu.bind('mouseenter', function(){
clearTimeout($menu.data('timers').hidetimer)
})
$menu.bind('mouseleave', function(){ //hide menu when mouse moves out of it
dropdownmenu.hidebox($, $menu)
})
$menu.data('dimensions', {w:$menu.outerWidth(), h:$menu.outerHeight()}) //remember main menu's dimensions
$menu.data('timers', {})
this.builtdropdownids.push($menu.get(0).id) //remember id of dropdown that was just built
},
init:function($, $target, $dropdown){
if (this.builtdropdownids.length==0){ //only bind click event to document once
$(document).bind("click", function(e){
if (e.button==0){ //hide all dropdown (and their sub ULs) when left mouse button is clicked
$('.jqdropdown').find('ul').andSelf().hide()
}
})
}
if (jQuery.inArray($dropdown.get(0).id, this.builtdropdownids)==-1) //if this dropdown hasn't been built yet
this.builddropdown($, $dropdown, $target)
if ($target.parents().filter('ul.jqdropdown').length>0) //if $target matches an element within the dropdown markup, don't bind ondropdown to that element
return
$target.bind("mouseenter", function(e){
dropdownmenu.showbox($, $dropdown, e)
})
$target.bind("mouseleave", function(e){
dropdownmenu.hidebox($, $dropdown)
})
}
};
jQuery.fn.adddropdown=function(dropdownid){
var $=jQuery
return this.each(function(){ //return jQuery obj
var $target=$(this)
if ($('#'+dropdownid).length==1) //check dropdown is defined
dropdownmenu.init($, $target, $('#'+dropdownid))
})
};
//By default, add dropdown to anchor links with attribute "data-dropdown"
jQuery(document).ready(function($){
var $anchors=$('*[data-dropdown]')
$anchors.each(function(){
$(this).adddropdown(this.getAttribute('data-dropdown'))
})
});

109
language-selector.php Normal file
View File

@ -0,0 +1,109 @@
<?php
namespace Grav\Plugin;
use Grav\Common\Language\LanguageCodes;
use Grav\Common\Page\Page;
use \Grav\Common\Plugin;
class LanguageSelectorPlugin extends Plugin
{
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
'onPluginsInitialized' => ['onPluginsInitialized', 0]
];
}
/**
* Initialize configuration
*/
public function onPluginsInitialized()
{
if ($this->isAdmin()) {
$this->active = false;
return;
}
$this->enable([
'onTwigInitialized' => ['onTwigInitialized', 0],
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
]);
}
/** Add the native_name function */
public function onTwigInitialized()
{
$this->grav['twig']->twig()->addFunction(
new \Twig_SimpleFunction('native_name', function($key) {
return LanguageCodes::getNativeName($key);
})
);
}
/**
* Add current directory to twig lookup paths.
*/
public function onTwigTemplatePaths()
{
$this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
}
/**
* Set needed variables to display Language-Selector.
*/
public function onTwigSiteVariables()
{
$data = new \stdClass;
// Manage Data content
$page = $this->grav['page'];
$data->page_route = $page->rawRoute();
if ($page->home()) {
$data->page_route = '/';
}
$languages = $this->grav['language']->getLanguages();
$data->languages = $languages;
if ($this->config->get('plugins.language-selector.untranslated_pages_behavior') !== 'none') {
$translated_pages = [];
foreach ($languages as $language) {
$translated_pages[$language] = null;
$page_name_without_ext = substr($page->name(), 0, -(strlen($page->extension())));
$translated_page_path = $page->path() . DS . $page_name_without_ext . '.' . $language . '.md';
if (file_exists($translated_page_path)) {
$translated_page = new Page();
$translated_page->init(new \SplFileInfo($translated_page_path), $language . '.md');
$translated_pages[$language] = $translated_page;
}
}
$data->translated_pages = $translated_pages;
}
$data->current = $this->grav['language']->getLanguage();
// Manage Twig Variables
$path_flags = $this->grav['locator']->findResource('plugin://language-selector/flags/', false) . "/";
$path_flags = $this->grav['base_url'] ."/". ltrim($path_flags, '/');
$this->grav['twig']->twig_vars['language_selector'] = $data;
$this->grav['twig']->twig_vars['language_display'] = array(
"select" => $this->config->get('plugins.language-selector.select_display'),
"button" => $this->config->get('plugins.language-selector.button_display'),
);
$this->grav['twig']->twig_vars['path_flags'] = $path_flags;
// Manage Assets
if ($this->config->get('plugins.language-selector.built_in_css')) {
$this->grav['assets']->add('plugin://language-selector/css/language-selector.css');
}
$this->grav['assets']->add('plugin://language-selector/js/language-selector.js');
}
public function getNativeName($code) {
}
}

5
language-selector.yaml Normal file
View File

@ -0,0 +1,5 @@
enabled: true
built_in_css: true
untranslated_pages_behavior: none
button_display: default
select_display: default

43
languages.yaml Normal file
View File

@ -0,0 +1,43 @@
# English
en:
PLUGINS:
LANGUAGE_SELECTOR:
PLUGIN_STATUS: 'Plugin status'
BUILT_IN_CSS: 'Use built in CSS'
UNTRANSLATED_PAGES:
LABEL: 'Untranslated pages behavior'
HELP: 'Determine what to do with a language link when the current page doesn''t exist in that language or it exists but it''s not published.'
OPT_NONE: 'Show language (default)'
OPT_REDIR: 'Show language, link to home route'
OPT_HIDE: 'Hide language'
BUTTON_DISPLAY:
LABEL: 'Button Display'
HELP: 'Define how button of selected language will be displayed'
SELECT_DISPLAY:
LABEL: 'Selector Display'
HELP: 'Define how language selector will be displayed'
OPT_DEFAULT: 'Flag + Language name'
OPT_FLAG: 'Only the flag'
OPT_NAME: 'Only the language name'
# French
fr:
PLUGINS:
LANGUAGE_SELECTOR:
PLUGIN_STATUS: 'Statut du plugin'
BUILT_IN_CSS: 'Utiliser CSS du plugin'
UNTRANSLATED_PAGES:
LABEL: 'Comportement des pages non-traduites'
HELP: 'Définit le comportement des liens lorsque la page n''existe pas dans la langue courante, ou bien existe mais non publié'
OPT_NONE: 'Affiche le langage (par défaut)'
OPT_REDIR: 'Affiche le langage, lié à l''URL de base'
OPT_HIDE: 'Cache le langage'
BUTTON_DISPLAY:
LABEL: 'Affichage du boutton'
HELP: 'Définit l''affichage du bouton de language sélectioné'
SELECT_DISPLAY:
LABEL: 'Affichage du sélecteur'
HELP: 'Définit l''affichage du sélecteur de language'
OPT_DEFAULT: 'Drapeau + Nom de la langue'
OPT_FLAG: 'Seulement le drapeau'
OPT_NAME: 'Seulement le nom de la langue'

View File

@ -0,0 +1,9 @@
{% set langobj = grav['language'] %}
{% for key in language_selector.languages %}
{% if key == language_selector.current %}
{% set lang_url = page.url %}
{% else %}
{% set lang_url = base_url_simple ~ langobj.getLanguageURLPrefix(key) ~ language_selector.page_route ~ page.urlExtension ?: '/' %}
{% endif %}
<link rel="alternate" hreflang="{{ key }}" href="{{ lang_url ~ uri.params }}" />
{% endfor %}

View File

@ -0,0 +1,49 @@
<div class="language-selector">
<button class="btn" type="button" data-dropdown="langSelectorList">
{% if language_display.button == 'default' or language_display.button == 'flag' %}
<img alt="{{ native_name(language_selector.current)|capitalize }}" src="{{ path_flags ~ language_selector.current }}.png" />
{% endif %}
{% if language_display.button == 'default' or language_display.button == 'name' %}
{{ native_name(language_selector.current)|capitalize }}
{% endif %}
<i class="fa fa-caret-down"></i>
</button>
<ul class="dropdown-menu" id="langSelectorList">
{% for language in language_selector.languages %}
{% set show_language = true %}
{% if language == language_selector.current %}
{% set lang_url = page.url %}
{% else %}
{% set base_lang_url = base_url_simple ~ grav.language.getLanguageURLPrefix(language) %}
{% set lang_url = base_lang_url ~ language_selector.page_route ~ page.urlExtension %}
{% set untranslated_pages_behavior = grav.config.plugins.language_selector.untranslated_pages_behavior %}
{% if untranslated_pages_behavior != 'none' %}
{% set translated_page = language_selector.translated_pages[language] %}
{% if (not translated_page) or (not translated_page.published) %}
{% if untranslated_pages_behavior == 'redirect' %}
{% set lang_url = base_lang_url ~ '/' %}
{% elseif untranslated_pages_behavior == 'hide' %}
{% set show_language = false %}
{% endif %}
{% endif %}
{% endif %}
{% endif %}
{% if show_language %}
<li>
<a href="{{ lang_url ~ uri.params }}">
{% if language_display.select == 'default' or language_display.select == 'flag' %}
<img alt="{{ native_name(language)|capitalize }}" src="{{ path_flags ~ language }}.png" />
{% endif %}
{% if language_display.select == 'default' or language_display.select == 'name' %}
{{ native_name(language)|capitalize }}
{% endif %}
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>