summaryrefslogtreecommitdiff
path: root/src/lib/lang.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/lang.php')
-rw-r--r--src/lib/lang.php186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/lib/lang.php b/src/lib/lang.php
new file mode 100644
index 0000000..84a4215
--- /dev/null
+++ b/src/lib/lang.php
@@ -0,0 +1,186 @@
+<?php
+/// CRIMSON --- A simple PHP framework.
+/// Copyright © 2024 Freya Murphy <contact@freyacat.org>
+///
+/// This file is part of CRIMSON.
+///
+/// CRIMSON 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.
+///
+/// CRIMSON 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 CRIMSON. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Returns the lang string for the provided $key
+ *
+ * $key - The key of the lang string
+ * $default - The string to use if lang string $key is undefined
+ * $sub - List of values to substitute using php's sprinf
+ */
+function lang(
+ string $key,
+ ?string $default = NULL,
+ ?array $sub = NULL
+): string {
+ $lang = ROUTER->get_lang();
+ $result = NULL;
+
+ // lookup lang key
+ if (isset($lang[$key]))
+ $result = $lang[$key];
+
+ // replace with $default if undefined
+ if ($result === NULL && $default !== NULL)
+ $result = $default;
+
+ // error if undefined
+ if ($result === NULL) {
+ CRIMSON_WARNING('Undefined lang string: ' . $key);
+ return $key;
+ }
+
+ // make substitutions
+ if ($sub) {
+ if (!is_array($sub))
+ $sub = [$sub];
+ $result = sprintf($result, ...$sub);
+ }
+
+ return $result;
+}
+
+/**
+ * Returns a html element (button, a, div, ...) containing content from
+ * the lang string, icon, aria tags, and/or tooltips. Text content and icon
+ * are contained in a seconed inner html element (span, h1, ...).
+ *
+ * ilang has up to four parts: text, tooltip, icon class, and icon content.
+ * Each part is loaded from a different lang string using $key as the prefix.
+ *
+ * == LANG_KEYS ==
+ *
+ * NAME | LANG KEY | REQUIRED | DESCRIPTION
+ * --------------------------------------------------------------------------
+ * text | $key_text | yes | The text content of the element. Text
+ * | | | content will always uppercase the first
+ * | | | letter.
+ * tip | $key_tip | no | The tool tip of the element.
+ * icon | $key_icon | no | Adds a <i> element with the class
+ * | | | <lang string>.
+ * content | $key_content | no | If icon, adds <lang string> as the
+ * | | | inner html of the icon.
+ *
+ * == ARGUMENTS ==
+ *
+ * NAME | REQUIRED | DEFAULT | DESCRIPTION
+ * ---------------------------------------------------------------------------
+ * $key | yes | | The key of the interface lang string.
+ * $class | no | | The class of the html element.
+ * $id | no | | The id of the html element.
+ * $sub | no | [] | Substitution arguments passed into lang()
+ * | | | in both $key_text and $key_tip.
+ * $type | no | 'a' | Sets the type of the html element.
+ * $subtype | no | 'span' | Sets the type of the inner html element.
+ * $attrs | no | array() | Sets html attributes using the key/value
+ * | | | pairs from $attrs. $class, $id, $href, and
+ * | | | and $onclick are all short hand for
+ * | | | $attrs['<name>']; Named attr arguments take
+ * | | | priority over any defined in $attrs.
+ * $style | no | | $attrs['style'] = $style.
+ * $href | no | | $attrs['href'] = $href. $type = 'a';
+ * $onclick | no | | $attrs['onclick'] = $onclick. $type = 'button'.
+ *
+ * NOTE: For any non required argument that is falsy, it is converted back to
+ * its default value.
+ *
+ * NOTE: For any non required argument that does not have a default value
+ * listed, falsy values turn off that attribute or functionality.
+ *
+ * WARNING: $href and $onclick also modify the default $type. If $type is
+ * passed to ilang, that type will be used instead.
+ *
+ * WARNING: Lang strings WILL be html escaped along with each atribute value.
+ * Everything else will not be sanitized by this function.
+ */
+function ilang(
+ string $key,
+ ?string $class = NULL,
+ ?string $id = NULL,
+ array $sub = [],
+ ?string $type = NULL,
+ string $subtype = 'span',
+ array $attrs = array(),
+ ?string $style = NULL,
+ ?string $href = NULL,
+ ?string $onclick = NULL,
+): string {
+ // read lang keys
+ $text = lang("{$key}_text", sub: $sub);
+ $tip = lang("{$key}_tip", '', sub: $sub);
+ $icon = lang("{$key}_icon", '');
+ $content = lang("{$key}_content", '');
+
+ // uppercase
+ $text = ucfirst($text);
+
+ // set $type if falsy
+ if (!$type) {
+ if ($href)
+ $type = 'a';
+ else if ($onclick)
+ $type = 'button';
+ else
+ $type = 'a';
+ }
+
+ // populate $attrs with named arguments
+ if ($tip) {
+ $attrs['title'] = $tip;
+ $attrs['aria-label'] = $tip;
+ }
+ if ($class)
+ $attrs['class'] = "{$class} ilang";
+ else
+ $attrs['class'] = "ilang";
+ if ($id)
+ $attrs['id'] = $id;
+ if ($style)
+ $attrs['style'] = $style;
+ if ($href)
+ $attrs['href'] = $href;
+ if ($onclick)
+ $attrs['onclick'] = $onclick;
+
+ $html = "";
+ // open tag
+ $html .= "<{$type}";
+ foreach ($attrs as $key => $value) {
+ $value = esc($value, TRUE); // html tag & string escape
+ $html .= " {$key}=\"{$value}\"";
+ }
+ $html .= ">";
+ // icon
+ if ($icon) {
+ $icon = esc($icon, TRUE); // html tag & string escape
+ $html .= "<i class=\"{$icon}\">";
+ if ($content) {
+ $content = esc($content); // html tag escape
+ $html .= "{$content}";
+ }
+ $html .= "</i>";
+ }
+ // content
+ $text = esc($text); // html tag escape
+ $html .= "<{$subtype}>{$text}</{$subtype}>";
+ // close tag
+ $html .= "</{$type}>";
+
+ return $html;
+}