├── .editorconfig
├── .gitignore
├── .prettierrc
├── LICENSE.md
├── README.md
├── composer.json
├── config
├── buttons.php
├── dialogs.php
└── translations.php
├── index.css
├── index.js
├── index.php
├── src
└── LanguageSelector.php
└── translations
├── de.yml
├── en.yml
├── fr.yml
├── is.yml
└── pt_PT.yml
/.editorconfig:
--------------------------------------------------------------------------------
1 | # This file is for unifying the coding style for different editors and IDEs
2 | # editorconfig.org
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | end_of_line = lf
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.md,*.txt]
13 | trim_trailing_whitespace = false
14 | insert_final_newline = false
15 |
16 | [*.php]
17 | indent_size = 2
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS files
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "singleQuote": true,
6 | "trailingComma": "none",
7 | "bracketSpacing": true,
8 | "semi": true,
9 | "proseWrap": "preserve",
10 | "arrowParens": "avoid",
11 | "htmlWhitespaceSensitivity": "css"
12 | }
13 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 JUNO
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Kirby Language Selector
2 |
3 | This plugin for **Kirby 5** replaces the default language dropdown with a customized version. It displays the translation state of each language and adds a dropdown for deleting translations.
4 |
5 | 
6 |
7 | Please note: If you are using **Kirby 4**, please install [v1.1.9](https://github.com/junohamburg/kirby-language-selector/releases/tag/1.1.9).
8 |
9 | ### UI states
10 |
11 | 
12 | Left to right: No translations, some translations, dropdown.
13 |
14 | ## Installation
15 |
16 | ### Download
17 |
18 | Download and copy this repository to `/site/plugins/kirby-language-selector`.
19 |
20 | ### Composer
21 |
22 | ```
23 | composer require junohamburg/kirby-language-selector
24 | ```
25 |
26 | ### Git submodule
27 |
28 | ```
29 | git submodule add https://github.com/junohamburg/kirby-language-selector.git site/plugins/kirby-language-selector
30 | ```
31 |
32 | ## Setup
33 |
34 | Install the plugin in a multi-language Kirby site.
35 |
36 | Please note: On small viewports, the default language dropdown is displayed.
37 |
38 | ## Available options
39 |
40 | **site/config/config.php**
41 |
42 | ```php
43 | [
47 | 'allowDelete' => false, // Hide dropdown for deleting translations, default: true
48 | ]
49 | ];
50 | ```
51 |
52 | ## Contributions
53 | ### Plugin Translations
54 |
55 | The dialog text and tooltips are not translated into every language that the Kirby panel supports. For missing languages, feel free to add a pull request with a new `yml` translation file in [this folder](https://github.com/junohamburg/kirby-language-selector/tree/main/translations).
56 |
57 | ## Disclaimer
58 |
59 | This plugin is provided "as is" with no guarantee. Use it at your own risk and always test it yourself before using it in a production environment. If you find any issues, please [create a new issue](https://github.com/junohamburg/kirby-language-selector/issues/new).
60 |
61 | ## Similar plugins
62 |
63 | [https://github.com/Daandelange/k3-translations](https://github.com/Daandelange/k3-translations)
64 | [https://github.com/doldenroller/k3-translation-status](https://github.com/doldenroller/k3-translation-status)
65 | [https://github.com/sietseveenman/kirby3-language-sync](https://github.com/sietseveenman/kirby3-language-sync)
66 |
67 | ## License
68 |
69 | MIT
70 |
71 | ## Credits
72 |
73 | - [JUNO](https://juno-hamburg.com)
74 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "junohamburg/kirby-language-selector",
3 | "description": "Kirby Language Selector",
4 | "license": "MIT",
5 | "type": "kirby-plugin",
6 | "version": "2.0.2",
7 | "authors": [
8 | {
9 | "name": "JUNO",
10 | "email": "github@juno-hamburg.com"
11 | }
12 | ],
13 | "require": {
14 | "getkirby/composer-installer": "^1.2"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/config/buttons.php:
--------------------------------------------------------------------------------
1 | fn (ModelWithContent $model) => new LanguageSelector($model),
7 | ];
--------------------------------------------------------------------------------
/config/dialogs.php:
--------------------------------------------------------------------------------
1 | language($language);
17 |
18 | return [
19 | 'component' => 'k-remove-dialog',
20 | 'props' => [
21 | 'text' => I18n::template(
22 | 'junohamburg.language-selector.' . $model::CLASS_ALIAS . '.delete.confirm',
23 | [
24 | 'language' => Escape::html($language->name()),
25 | 'title' => match (true) {
26 | $model instanceof Site => $model->title(),
27 | $model instanceof Page => $model->title(),
28 | $model instanceof File => $model->filename(),
29 | $model instanceof User => $model->name() ?? $model->email(),
30 | default => throw new Exception('Invalid model type'),
31 | },
32 | ]
33 | )
34 | ]
35 | ];
36 | };
37 |
38 | $submit = function (ModelWithContent $model, string $language) {
39 | $model->version('latest')->delete($language);
40 |
41 | return [
42 | 'redirect' => $model->panel()->url(true)
43 | ];
44 | };
45 |
46 | // Dialog routes
47 | return [
48 | 'page.translation.delete' => $forModel = [
49 | 'pattern' => '(pages/.*?)/translation/(:any)',
50 | 'load' => fn (string $model, string $language) =>
51 | $load(model: Find::parent($model), language: $language),
52 | 'submit' => fn (string $model, string $language) =>
53 | $submit(model: Find::parent($model), language: $language)
54 | ],
55 | 'page.file.translation.delete' => $forFile = [
56 | 'pattern' => '(pages/.*?)/files/(:any)/translation/(:any)',
57 | 'load' => fn (string $model, string $filename, string $language) =>
58 | $load(model: Find::file($model, $filename), language: $language),
59 | 'submit' => fn (string $model, string $filename, string $language) =>
60 | $submit(model: Find::file($model, $filename), language: $language)
61 | ],
62 | 'site.translation.delete' => [
63 | ...$forModel,
64 | 'pattern' => '(site)/translation/(:any)'
65 | ],
66 | 'site.file.translation.delete' => [
67 | ...$forFile,
68 | 'pattern' => '(site)/files/(:any)/translation/(:any)'
69 | ],
70 | 'user.translation.delete' => [
71 | ...$forModel,
72 | 'pattern' => '(users/.*?)/translation/(:any)'
73 | ],
74 | 'user.file.translation.delete' => [
75 | ...$forFile,
76 | 'pattern' => '(users/.*?)/files/(:any)/translation/(:any)'
77 | ],
78 | 'account.translation.delete' => [
79 | ...$forModel,
80 | 'pattern' => '(account)/translation/(:any)'
81 | ],
82 | 'account.file.translation.delete' => [
83 | ...$forFile,
84 | 'pattern' => '(account)/files/(:any)/translation/(:any)'
85 | ]
86 | ];
--------------------------------------------------------------------------------
/config/translations.php:
--------------------------------------------------------------------------------
1 | 'junohamburg.language-selector.' . $key
21 | ),
22 | $translation
23 | );
24 | }
25 |
26 | return $translations;
--------------------------------------------------------------------------------
/index.css:
--------------------------------------------------------------------------------
1 | @container (max-width: 30rem) {
2 | .k-button-group.k-language-selector {
3 | display: none;
4 | }
5 | }
6 |
7 | @container (min-width: 30rem) {
8 | .k-language-selector + .k-languages-dropdown {
9 | display: none;
10 | }
11 | }
12 |
13 | /* Language Selector style */
14 | .k-language-selector > .k-button,
15 | .k-language-selector + .k-languages-dropdown > .k-button {
16 | text-transform: uppercase;
17 | }
18 |
19 | /* Same width buttons */
20 | .k-language-selector > .k-button:not([data-dropdown='true']) {
21 | --button-padding: 0;
22 | min-width: 2rem;
23 | }
24 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | panel.plugin('junohamburg/language-selector', {
2 | components: {
3 | 'k-language-selector': {
4 | inheritAttrs: false,
5 | props: {
6 | dropdown: String,
7 | language: Object,
8 | languages: {
9 | type: Array,
10 | default: () => []
11 | },
12 | options: {
13 | type: Array,
14 | default: () => []
15 | }
16 | },
17 | methods: {
18 | change(language) {
19 | this.$reload({
20 | query: {
21 | language: language.code
22 | }
23 | });
24 | },
25 | remove(code) {
26 | this.$panel.dialog.open(
27 | this.$panel.view.path + '/translation/' + code
28 | );
29 | }
30 | },
31 | template: `
32 |