From: Banana Date: Sat, 6 Apr 2024 09:32:09 +0000 (+0200) Subject: compact theme and init of i18n X-Git-Tag: 1.7~37 X-Git-Url: http://91.132.146.200/gitweb/?a=commitdiff_plain;h=d7c57dd9211fbc9727cd411dfbede07773871909;p=bibliotheca-php.git compact theme and init of i18n --- diff --git a/CHANGELOG b/CHANGELOG index cacba5f..710f80b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,10 +1,12 @@ 1.x - The Ceremonial Chambers + * Added i18n. Please read the upgrade file for more information. English and german are available * Added group infos to profile view. + * Added compact theme. Based on default, but with less space. * User- and groupmanagement: Check if in use before deletion. * Removed legacy ifset method and replace with ?? * Removed legacy ifsetvalue method. * Made documentation files markdown. - + * Updated to uikit-3.19.2 1.6 - Chizra 2024-02-03 * Config change. Added new entries. See upgrade/from-version-1.5.txt. It won't work if it is missing. diff --git a/TODO b/TODO index 105b6cf..d2af478 100644 --- a/TODO +++ b/TODO @@ -1,14 +1,8 @@ * Better error handling and display while adding / update and delete ** Maybe some message "store" * change multiple-attachment to a field which tells it is used for a image gallery -* i18n support * Export of an entry, collection or everything. Stored on disk. * Import of the export -* New Design? * update JS and remove deprecations -* minimal theme -** https://watercss.kognise.dev/ -* create a real fallback theme, which does not depend on any styling/css -** change the css and js lookup too in main file * Definition of fields in "card view" diff --git a/USES b/USES index 08368be..768aca2 100644 --- a/USES +++ b/USES @@ -2,3 +2,4 @@ https://github.com/FabianBeiner/PHP-IMDB-Grabber with some modifications https://getuikit.com/ https://jdan.github.io/98.css/ https://sortablejs.github.io/Sortable/ +https://getbootstrap.com/ diff --git a/documentation/i18n.md b/documentation/i18n.md new file mode 100644 index 0000000..6f8ba37 --- /dev/null +++ b/documentation/i18n.md @@ -0,0 +1,29 @@ +# Internationalization + +The internationalization is based on files (`i18n/...ini`) which store a key - value set. +The key is used in the code and returns the value. + +The used language is set in `config.php`. The config and the names of each internationalization file is based +on [ISO 639-3](https://iso639-3.sil.org/code_tables/639/data). + +Since sometimes the two char variant is used and it is not always just the first two ones from the ISO 639-3 variant, +the format of the constant in the `config.php` is an array. `iso3 => value, iso2 => value` + +Additional to the usual ini format, there is the possibility to use an existing key as a value. + +## How to create a new language file + +Lookup the correct [ISO 639-3](https://iso639-3.sil.org/code_tables/639/data) code and create a file with this code +and the extenions `.ini`. Save it in the `i18n/` folder. As a base for the key - value sets, use the `eng.ini` file. +Add the licencse header and add yourself and the contributors as the creator. +Create a PR at [Github](https://github.com/bananas-repos/insipid/blob/master/CONTRIBUTING.md) and have it added to +the official package. + +# Fallback + +If the configured lang file is not found the `eng.ini` file will be used. Is the key not found in file, the +requested key will be returned. + +# Limitations + +Setup and some error messages will be in english. diff --git a/sources/uikit-3.19.2.zip b/sources/uikit-3.19.2.zip new file mode 100644 index 0000000..3a30540 Binary files /dev/null and b/sources/uikit-3.19.2.zip differ diff --git a/sources/uikit-3.5.3.zip b/sources/uikit-3.5.3.zip deleted file mode 100644 index 6858fd0..0000000 Binary files a/sources/uikit-3.5.3.zip and /dev/null differ diff --git a/upgrade/from-version-1.6.txt b/upgrade/from-version-1.6.txt index 4598242..e8a91e8 100644 --- a/upgrade/from-version-1.6.txt +++ b/upgrade/from-version-1.6.txt @@ -1,5 +1,16 @@ +# Config changes + +Add the following lines to your `config.php`. +``` +# language setting +# see i18n.md file for syntax +const FRONTEND_LANGUAGE = array('iso3' => 'eng', 'iso2' => 'en'); +``` + # DB changes. Run each line against your bibliotheca DB. + Replace #REPLACEME# with your table prefix. Default is bib ``` UPDATE `#REPLACEME#_sys_fields` SET `value` = 'DOS,Windows 1,Windows 2,Windows 3,Windows 95,Windows 98,Windows XP,Windows 2000,Windows ME,Windows Vista,Windows 7,Windows 8,Windows 10,Windows 11', `apiinfo` = 'One of DOS,Windows 1,Windows 2,Windows 3,Windows 95,Windows 98,Windows XP,Windows 2000,Windows ME,Windows Vista,Windows 7,Windows 8,Windows 10,Windows 11' WHERE `#REPLACEME#_sys_fields`.`id` = 17; -``` \ No newline at end of file +UPDATE `#REPLACEME#_menu` SET `action` = 'dashboard' WHERE `#REPLACEME#_menu`.`id` = 1; +``` diff --git a/webclient/config/config.php.default b/webclient/config/config.php.default index 54b285e..f039dfe 100644 --- a/webclient/config/config.php.default +++ b/webclient/config/config.php.default @@ -26,6 +26,10 @@ const QUERY_DEBUG = false; # timezone settings const TIMEZONE = '~timezone~'; +# language setting +# see i18n.md file for syntax +const FRONTEND_LANGUAGE = 'eng'; + # path settings const PATH_ABSOLUTE = '~pathabsolute~'; const PATH_SYSTEMOUT = PATH_ABSOLUTE.'/systemout'; @@ -41,7 +45,7 @@ const DB_NAME = '~dbname~'; const DB_PREFIX = '~dbprefix~'; # a _ is added automatically as separation ## theme support -# available values are: default, 98 +# available values are: default, 98, compact # fallback is default theme const UI_THEME = 'default'; # additional config for each theme with fallback diff --git a/webclient/i18n/deu.ini b/webclient/i18n/deu.ini new file mode 100644 index 0000000..8d63042 --- /dev/null +++ b/webclient/i18n/deu.ini @@ -0,0 +1,16 @@ +; Bibliotheca +; +; Copyright 2018-2024 Johannes Keßler +; +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see http://www.gnu.org/licenses/gpl-3.0. diff --git a/webclient/i18n/eng.ini b/webclient/i18n/eng.ini new file mode 100644 index 0000000..d46a3e4 --- /dev/null +++ b/webclient/i18n/eng.ini @@ -0,0 +1,108 @@ +; Bibliotheca +; +; Copyright 2018-2024 Johannes Keßler +; +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program. If not, see http://www.gnu.org/licenses/gpl-3.0. +; +; Format: key = "value", which is the default ini format +; Special logic is added to make key = key work. Use it to provide a uniqe key but with a already existing value. +; The value is the keyname without any quotes. +; Use this to create unique translations without changing the template + +auth.input.password = "Password" +auth.input.username = "Username" +auth.login = "Login" +auth.logout = "Logout" + +advsearch.explain.fields = "Available fields in %s are:" +advsearch.headline.syntax = "Syntax" +advsearch.help.1 = "To search within the collection default search field, like the ordinary search, just type the search term and go." +advsearch.help.2 = "To search within the possible fields of a collection type the field identifier followed by : and then a space. Not every search operator does make sense with tag search fields. If the search is within a field witch is not configured to be displayed in the table view, it will be added." +advsearch.input.description = "This uses the table view as default. Remember to select the fields to show in collection config." +advsearch.input.search.placeholder = "See search syntax for options" +advsearch.operators = "Possible search operators:" +advsearch.operators.asterisk = "The asterisk serves as the truncation (or wildcard) operator. Unlike the other operators, it is appended to the word to be affected. Words match if they begin with the word preceding the * operator." +advsearch.operators.greater = "A leading greater than sign indicates that rows greater than the number will be returned." +advsearch.operators.less = "A leading less than sign indicates that rows smaller than the number will be returned." +advsearch.operators.minus = "A leading minus sign indicates that this word must not be present in any of the rows that are returned." +advsearch.operators.plus = "A leading plus sign indicates that this word must be present in each row that is returned." +advsearch.operators.quote = 'A phrase that is enclosed within double quote (") characters matches only rows that contain the phrase literally, as it was typed.' +advsearch.result = "Display result for: %s
(Max. result of 60)" +advsearch.submit.bulkedit = "Bulkedit these results" + +bulkedit.headline.edit = "Bulkedit these entries in:" + +managecol.addmodify = "Add or modify a collection" +managecol.addremfield = "Add or remove a field" +managecol.availablefields = "Available fields" +managecol.availcol = "Available collections" +managecol.configuredfields = "Configured fields" +managecol.defaultfieldvaluenote = "Any default field or any option which needs a field, get its values after the fields are configured." +managecol.globalsearchhowto = "The field is used in the global search. Altering the default search field results in a DB reindex.
This could take some time, depending on the amount of data.
As of version 1.6, the field 'Combined Search' provides a much better default search base.
Select the field and save. Use the option below to created or update the search data for every entry in this collection." +managecol.howto = "Just use drag and drop below to add, remove or order your fields.
Removing a field will remove the stored data from the collection.
Make sure at least the title, cover image and description fields are available." +managecol.input.advancedtablesearchfields = "Advanced search table fields" +managecol.input.advancedtablesearchfields.howto = "Make sure that the default global search field is in this list. This does not limit the fields to search in." +managecol.input.combinedsearch = "Update Combined Search field data" +managecol.input.combinedsearch.howto = "This could take some time to complete, depending on the amount of data.
Plase do this after you remove fields(text) from your collection." +managecol.input.defaultsearchfield = "Default global search field" +managecol.input.defaultsort = "Default sort field" +managecol.input.defaultsortorder = "Default sort order" +managecol.input.delete = global.delete +managecol.input.delete.howto = "Warning: This will delete ALL the data in this collection!" +managecol.input.description = global.description +managecol.input.name = global.name +managecol.input.name.placeholder = "Unique name. No special chars." +managecol.input.overwriterights = "Overwrite existing rights" +managecol.input.overwriterights.howto = "Warning: This will overwrite existing entry rights (user, group, rights) with the ones from the collection!" +managecol.input.tools = "Tools" +managecol.managecol = "Manage your collections" +managecol.managefields = "Manage your fields for:" + +global.ascending = "Ascending" +global.collection = "Collection" +global.collection.select.notice = "Please select a collection first" +global.created = "Created" +global.default = "Default" +global.delete = "Delete" +global.descending = "Descending" +global.description = "Description" +global.displayresultfor = "Display result for: %s" +global.edit = "Edit" +global.fields = "Fields" +global.group = "Group" +global.image = "Image" +global.latest = "Latest" +global.name = "Name" +global.none = "None" +global.other = "Other" +global.owner = "Owner" +global.pleaseselect = "Please select" +global.rights = "Rights" +global.save = "Save" +global.search = "Search" +global.search.resultfor = "Display result for: %s" +global.sort = "Sort" +global.title = "Title" +global.user = "User" +global.view = "View" +global.clickremove = "Click to remove" +global.field.writeenter = "Write and press enter." +global.field.select.bulkoption = "Select bulk edit option" +global.add = "Add" +global.replace = "Replace" +global.clear = "Clear" + +pagination.previous = "previous" +pagination.gotopage = "Goto page" +pagionation.next = "next" diff --git a/webclient/index.php b/webclient/index.php index 227c8c4..a956461 100644 --- a/webclient/index.php +++ b/webclient/index.php @@ -46,13 +46,16 @@ else { # time settings date_default_timezone_set(TIMEZONE); +# i18n +require_once 'lib/i18n.class.php'; +$I18n = new I18n(); + # static helper class require_once 'lib/summoner.class.php'; # general includes require_once 'lib/doomguy.class.php'; require_once 'lib/gorenest.class.php'; - ## main vars # the template data as an array # and some defaults @@ -82,7 +85,7 @@ $Doomguy = new Doomguy($DB); # menu Object $Gorenest = new GoreNest($DB,$Doomguy); -$_requestMode = false; +$_requestMode = "dashboard"; if(isset($_GET['p']) && !empty($_GET['p'])) { $_requestMode = trim($_GET['p']); $_requestMode = Summoner::validate($_requestMode,'nospace') ? $_requestMode : "dashboard"; diff --git a/webclient/lib/i18n.class.php b/webclient/lib/i18n.class.php new file mode 100644 index 0000000..4dfeb56 --- /dev/null +++ b/webclient/lib/i18n.class.php @@ -0,0 +1,92 @@ +_iso3 = FRONTEND_LANGUAGE['iso3']; + $this->_iso2 = FRONTEND_LANGUAGE['iso2']; + $_langFile = PATH_ABSOLUTE.'/i18n/'.$this->_iso3.'.ini'; + if(file_exists($_langFile)) { + $_langData = parse_ini_file($_langFile); + if($_langData !== false) { + $this->_langData = $_langData; + } + } + } + else { + $_langFile = PATH_ABSOLUTE.'/i18n/'.$this->_iso3.'.ini'; + $_langData = parse_ini_file($_langFile); + if($_langData !== false) { + $this->_langData = $_langData; + } + } + } + + public function twoCharLang(): string { + return $this->_iso2; + } + + /** + * Return text for given key for currently loaded lang + * uses vsprintf or sprintf for placeholders in key + * + * @param string $key + * @param mixed $replace + * @return string + */ + public function t(string $key, mixed $replace=''): string { + $ret = $key; + if(isset($this->_langData[$key])) { + $ret = $this->_langData[$key]; + // the value is another key + if(!str_contains($ret, '"') && str_contains($ret, ".") && isset($this->_langData[$ret])) { + $ret = $this->_langData[$ret]; + } + + if(!empty($replace)) { + if(is_array($replace)) { + $ret = vsprintf($ret, $replace); + } else { + $ret = sprintf($ret, $replace); + } + } + } + return $ret; + } +} diff --git a/webclient/lib/manageentry.class.php b/webclient/lib/manageentry.class.php index 7ab6afa..0eafc00 100644 --- a/webclient/lib/manageentry.class.php +++ b/webclient/lib/manageentry.class.php @@ -144,7 +144,6 @@ class Manageentry { $ret['_canDelete'] = $this->_canDelete($entryId); $ret['_isOwner'] = $this->_isOwner($result); } - } } catch (Exception $e) { diff --git a/webclient/view/compact/advancedsearch/advancedsearch.html b/webclient/view/compact/advancedsearch/advancedsearch.html new file mode 100644 index 0000000..53eb09c --- /dev/null +++ b/webclient/view/compact/advancedsearch/advancedsearch.html @@ -0,0 +1,188 @@ + + + +
+ +

Display result for:
+ (Max. result of 60) +

+
+
+ + + isSignedIn() === true) { ?> +
+ + + + +
+ +
+ + + +
+
+
+
+ +
+ +
+
+
+
Table view
+
+ +
+
+ +
+ +
+
+
+
+

Syntax

+

To search within the collection default search field, like the ordinary search, just type the search term and go.

+

+ To search within the possible fields of a collection type the field identifier followed by : and then a space. Not every search operator does make sense with tag search fields. + If the search is within a field witch is not configured to be displayed in the table view, it will be added. +

+ eg.: title: bourne +

Available fields in are:

+
+		$v) {
+			echo $v['identifier']." ";
+		}
+		?>
+		
+

Possible search operators:

+

+ * = The asterisk serves as the truncation (or wildcard) operator. Unlike the other operators, + it is appended to the word to be affected. Words match if they begin with the word preceding the * operator. +

+

+ = A leading plus sign indicates that this word must be present in each row that is returned.

+

- = A leading minus sign indicates that this word must not be present in any of the rows that are returned.

+

" = A phrase that is enclosed within double quote (") characters matches only rows that contain the phrase literally, as it was typed.

+

> = A leading greater than sign indicates that rows greater than the number will be returned.

+

< = A leading less than sign indicates that rows smaller than the number will be returned.

+
+
+ + +
+ + + + + + + '.$f['displayname'].''; + } + } + ?> + + + + + $entry) { ?> + + + + + + + + + +
#
+ + + +
+
+ + + $entry) { ?> + +
+
+ + + <?php echo $entry['fields']['coverimage']['displayname']; ?> + + + +
+
+
+ +

+ + + +

+ +
+ +
+
+ + + + + + +
+
+

Please select a collection first

+
+ $v) { ?> +
+
+ +
+
+
+ diff --git a/webclient/view/compact/collections/collections.html b/webclient/view/compact/collections/collections.html new file mode 100644 index 0000000..343593a --- /dev/null +++ b/webclient/view/compact/collections/collections.html @@ -0,0 +1,108 @@ + 1) { ?> +
+
+
    + +
+
+
+ +
+ +
+ +
+
+ +
+
+ + + +
+ +

Display result for:

+
+ + + + +

+ +

+ +$entry) { ?> +
+
+ + + <?php echo $entry['fields']['coverimage']['displayname']; ?> + + + +
+
+
+ +

+ + + +

+ +
+ +
+
+ + + +
+
+

Please select a collection first

+
+ $v) { ?> +
+
+ +
+
+
+ + + 1) { ?> +
+
+
    + +
+
+
+ diff --git a/webclient/view/compact/collections/collections_pagination.html b/webclient/view/compact/collections/collections_pagination.html new file mode 100644 index 0000000..3ba8aba --- /dev/null +++ b/webclient/view/compact/collections/collections_pagination.html @@ -0,0 +1,36 @@ + 1) { + echo '
  • +
  • '; +} else { + echo '
  • '; +} +$ellipsisShown = 0; + +for($i=1;$i<=$TemplateData['pagination']['pages'];$i++) { + $active = ''; + if($i == $TemplateData['pagination']['curPage']) $active = 'uk-active'; + + if(in_array($i,$TemplateData['pagination']['visibleRange'])) { + echo '
  • '.$i.'
  • '; + } + else { + if($i < $TemplateData['pagination']['currentRangeStart'] && $ellipsisShown == 0) { + echo '
  • '; + $ellipsisShown = 1; + } + if($i > $TemplateData['pagination']['currentRangeEnd'] && ($ellipsisShown == 0 || $ellipsisShown == 1)) { + echo '
  • '; + $ellipsisShown = 2; + } + } +} + +if($TemplateData['pagination']['curPage'] < $TemplateData['pagination']['pages']) { + echo '
  • +
  • '; +} else { + echo '
  • '; +} +?> diff --git a/webclient/view/compact/dashboard/dashboard.html b/webclient/view/compact/dashboard/dashboard.html new file mode 100644 index 0000000..569f227 --- /dev/null +++ b/webclient/view/compact/dashboard/dashboard.html @@ -0,0 +1,54 @@ + +
    + +

    Display result for:

    +
    + + + +$v) { ?> + +

    + + +

    + + + $entry) { ?> + +
    +
    + + + <?php echo $entry['fields']['coverimage']['displayname']; ?> + + + +
    +
    +
    + +

    + + + +

    + +
    + +
    +
    + + diff --git a/webclient/view/compact/entry/entry.html b/webclient/view/compact/entry/entry.html new file mode 100644 index 0000000..3bc4b6f --- /dev/null +++ b/webclient/view/compact/entry/entry.html @@ -0,0 +1,57 @@ + +
    +
    + + + +
    +
    + +
    +
    diff --git a/webclient/view/compact/entry/field-text-title.html b/webclient/view/compact/entry/field-text-title.html new file mode 100644 index 0000000..78da0f8 --- /dev/null +++ b/webclient/view/compact/entry/field-text-title.html @@ -0,0 +1 @@ +

    diff --git a/webclient/view/compact/entry/field-text3-description.html b/webclient/view/compact/entry/field-text3-description.html new file mode 100644 index 0000000..472aceb --- /dev/null +++ b/webclient/view/compact/entry/field-text3-description.html @@ -0,0 +1 @@ + diff --git a/webclient/view/compact/main.php b/webclient/view/compact/main.php new file mode 100644 index 0000000..1ba55c5 --- /dev/null +++ b/webclient/view/compact/main.php @@ -0,0 +1,35 @@ + + + + + + + + + + + + + <?php echo $TemplateData['pageTitle']; ?> - Bibliotheca + + +
    + +
    + +
    +
    + + +
    +
    + + + + diff --git a/webclient/view/compact/manageentry/manageentry.html b/webclient/view/compact/manageentry/manageentry.html new file mode 100644 index 0000000..6dbca35 --- /dev/null +++ b/webclient/view/compact/manageentry/manageentry.html @@ -0,0 +1,132 @@ + +

    Update an entry in:

    +

    + + View entry +

    + +Possible duplicate + + + +

    Add an entry to:

    + +
    +
    +
    + + + +
    +
    +
    Rights
    +
    + + + + + + + + + + + +
    UserGroupOther
    + + + + + + + + + + + +
    +
    +
    + + + + + +
    +
    +
    Delete
    +
    + +
    +
    + + + +
    + +
    +
    +
    +
    + +

    Available tools

    + + +
    +
    + + +

    Add an entry to your collection

    +
    +
    +

    Please select a collection first:

    +
    + $v) { ?> +
    +
    + +
    +
    +
    + diff --git a/webclient/view/compact/managetags/managetags.html b/webclient/view/compact/managetags/managetags.html new file mode 100644 index 0000000..6d6c651 --- /dev/null +++ b/webclient/view/compact/managetags/managetags.html @@ -0,0 +1,88 @@ + +
    +
    +

    Manage Tags in:

    +

    + The actions are top down. If you choose to move and rename, only move will be executed.
    + Deletion will remove without recover!
    + If you rename and input an existing one a move will be done instead.
    + Tag values are stored how they come and treated that way here (case sensitive). + In search they are case insensitive. +

    + + +
    + + $v) { ?> +

    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + + +
    +
    Delete
    +
    + +
    +
    + + + + +
    + +
    +
    + + +
    +
    + + +
    +
    +

    Please select a collection first

    +
    + $v) { ?> +
    +
    + +
    +
    +
    + diff --git a/webclient/view/compact/tags/tags.html b/webclient/view/compact/tags/tags.html new file mode 100644 index 0000000..a0da76e --- /dev/null +++ b/webclient/view/compact/tags/tags.html @@ -0,0 +1,37 @@ +
    +
    + +

    Tags for:

    + + +
    + +

    Display result for:

    +
    + + + + $v) { ?> +

    +
    + $ev) { ?> + , + +
    + + + +

    Please select a collection first

    +
    + $v) { ?> +
    +
    + +
    + +
    +
    diff --git a/webclient/view/default/advancedsearch/advancedsearch.html b/webclient/view/default/advancedsearch/advancedsearch.html index 5eb85b7..517a612 100644 --- a/webclient/view/default/advancedsearch/advancedsearch.html +++ b/webclient/view/default/advancedsearch/advancedsearch.html @@ -15,7 +15,7 @@ - + isSignedIn() === true) { ?>
    @@ -29,7 +29,7 @@
    -
    +
    @@ -55,7 +55,7 @@
    -
    +

    Syntax

    To search within the collection default search field, like the ordinary search, just type the search term and go.

    diff --git a/webclient/view/default/main.php b/webclient/view/default/main.php index 7ecfb9b..1ba55c5 100644 --- a/webclient/view/default/main.php +++ b/webclient/view/default/main.php @@ -1,5 +1,5 @@ - + diff --git a/webclient/view/default/system/menu.php b/webclient/view/default/system/menu.php index 5ce7195..7625f1a 100644 --- a/webclient/view/default/system/menu.php +++ b/webclient/view/default/system/menu.php @@ -29,7 +29,7 @@ if(!empty($_collection)) { $_menuShow = $Gorenest->get('show'); $_menuManage = $Gorenest->get('manage', false, $_contextActions); ?> -