Readme, some fixes, rel noopener for _blank links
This commit is contained in:
parent
2087e56626
commit
18e7955b12
44
README.md
44
README.md
@ -214,7 +214,7 @@ namespace Documents\Example {
|
||||
}
|
||||
|
||||
public function getCode(): string {
|
||||
$view = $this->getDocument()->getView() ?? "<Empty>";
|
||||
$view = $this->getDocument()->getRequestedView() ?? "<Empty>";
|
||||
return "<b>Requested View:</b> " . htmlspecialchars($view);
|
||||
}
|
||||
}
|
||||
@ -223,6 +223,48 @@ namespace Documents\Example {
|
||||
|
||||
Of course, the head and body classes can be placed in any file, as the code might get big and complex.
|
||||
|
||||
### Localization
|
||||
|
||||
Currently, there are two languages specified, which are stored in the database: `en_US` and `de_DE`.
|
||||
A language is dynamically loaded according to the sent `Accept-Language`-Header, but can also be set using the `lang` parameter
|
||||
or [/api/language/set](/core/Api/LanguageAPI.class.php) endpoint. Localization of strings can be achieved using the [LanguageModule](/core/Objects/lang/LanguageModule.php)-Class.
|
||||
Let's look at this example:
|
||||
|
||||
```php
|
||||
class ExampleLangModule extends \Objects\lang\LanguageModule {
|
||||
public function getEntries(string $langCode) {
|
||||
$entries = array();
|
||||
switch ($langCode) {
|
||||
case 'de_DE':
|
||||
$entries["EXAMPLE_KEY"] = "Das ist eine Beispielübersetzung";
|
||||
$entries["Welcome"] = "Willkommen";
|
||||
break;
|
||||
default:
|
||||
$entries["EXAMPLE_KEY"] = "This is an example translation";
|
||||
break;
|
||||
}
|
||||
return $entries;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If any translation key is not defined, the key is returned, which means, we don't need to specify the string `Welcome` again. To access the translations,
|
||||
we firstly have to load the module. This is done by adding the class, or the object inside the constructor.
|
||||
To translate the defined strings, we can use the global `L()` function. The following code snipped shows the use of
|
||||
our sample language module:
|
||||
|
||||
```php
|
||||
class SomeView extends \Elements\View {
|
||||
public function __construct(\Elements\Document $document) {
|
||||
parent::__construct($document);
|
||||
$this->langModules[] = ExampleModule::class;
|
||||
}
|
||||
|
||||
public function getCode() : string{
|
||||
return L("Welcome") . "! " . L("EXAMPLE_KEY");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Anything more?
|
||||
|
||||
|
@ -75,7 +75,7 @@ export default function Sidebar(props) {
|
||||
let filePath = parent.filesPath;
|
||||
if (filePath) {
|
||||
li.push(<li className={"nav-item"} key={"files"}>
|
||||
<a href={filePath} className={"nav-link"} target={"_blank"} rel={"noopener noreferrer"}>
|
||||
<a href={filePath} className={"nav-link"} target={"_blank"} rel={"noopener"}>
|
||||
<Icon icon={"folder"} className={"nav-icon"} />
|
||||
<p>Files</p>
|
||||
</a>
|
||||
|
@ -121,7 +121,13 @@ export default function HelpPage() {
|
||||
<b>Project Lead & Main Developer</b>
|
||||
<ul className={"list-unstyled"}>
|
||||
<li><small><Icon icon={"address-card"} className={"mr-1"}/>Roman Hergenreder</small></li>
|
||||
<li><small><Icon icon={"globe"} className={"mr-1"}/><a href={"https://romanh.de/"} target={"_blank"}>https://romanh.de/</a></small></li>
|
||||
<li>
|
||||
<small><Icon icon={"globe"} className={"mr-1"}/>
|
||||
<a href={"https://romanh.de/"} target={"_blank"} rel={"noopener"}>
|
||||
https://romanh.de/
|
||||
</a>
|
||||
</small>
|
||||
</li>
|
||||
<li><small><Icon icon={"envelope"} className={"mr-1"}/><a href={"mailto:webmaster@romanh.de"}>webmaster@romanh.de</a></small></li>
|
||||
</ul>
|
||||
|
||||
|
@ -422,7 +422,7 @@ export default class Settings extends React.Component {
|
||||
<label className={"form-check-label"} htmlFor={"recaptcha_enabled"}>
|
||||
Enable Google's reCaptcha
|
||||
<span className={"ml-2"}>
|
||||
(<a href={"https://www.google.com/recaptcha/intro/v3.html"} target={"_blank"}>
|
||||
(<a href={"https://www.google.com/recaptcha/intro/v3.html"} target={"_blank"} rel={"noopener noreferrer"}>
|
||||
More Info
|
||||
<sup><small><Icon icon={"external-link-alt"} className={"ml-1"}/></small></sup>
|
||||
</a>)
|
||||
|
@ -27,12 +27,17 @@ abstract class Document {
|
||||
|
||||
public function getView() : ?View {
|
||||
|
||||
$file = getClassPath($this->activeView);
|
||||
if(!file_exists($file) || !is_subclass_of($this->activeView, View::class)) {
|
||||
$view = parseClass($this->activeView);
|
||||
$file = getClassPath($view);
|
||||
if(!file_exists($file) || !is_subclass_of($view, View::class)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new $this->activeView($this);
|
||||
return new $view($this);
|
||||
}
|
||||
|
||||
public function getRequestedView(): string {
|
||||
return $this->activeView;
|
||||
}
|
||||
|
||||
function getCode(): string {
|
||||
|
@ -89,7 +89,7 @@ abstract class View extends StaticView {
|
||||
|
||||
protected function createExternalLink($link, $title=null): string {
|
||||
if(is_null($title)) $title=$link;
|
||||
return "<a href=\"$link\" target=\"_blank\" class=\"external\">$title</a>";
|
||||
return "<a href=\"$link\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"external\">$title</a>";
|
||||
}
|
||||
|
||||
protected function createIcon($icon, $type = "fas", $classes = ""): string {
|
||||
|
@ -4,7 +4,7 @@ namespace Objects;
|
||||
|
||||
abstract class ApiObject implements \JsonSerializable {
|
||||
|
||||
public abstract function jsonSerialize();
|
||||
public abstract function jsonSerialize(): array;
|
||||
|
||||
public function __toString() { return json_encode($this); }
|
||||
|
||||
|
@ -31,7 +31,10 @@ namespace Objects {
|
||||
public function getEntries() { return $this->entries; }
|
||||
public function getModules() { return $this->modules; }
|
||||
|
||||
public function loadModule(LanguageModule $module) {
|
||||
/**
|
||||
* @param $module LanguageModule class or object
|
||||
*/
|
||||
public function loadModule($module) {
|
||||
if(!is_object($module))
|
||||
$module = new $module;
|
||||
|
||||
@ -40,7 +43,7 @@ namespace Objects {
|
||||
$this->modules[] = $module;
|
||||
}
|
||||
|
||||
public function translate($key) {
|
||||
public function translate(string $key): string {
|
||||
if(isset($this->entries[$key]))
|
||||
return $this->entries[$key];
|
||||
|
||||
@ -51,7 +54,7 @@ namespace Objects {
|
||||
setcookie('lang', $this->langCode, 0, "/", "");
|
||||
}
|
||||
|
||||
public function jsonSerialize() {
|
||||
public function jsonSerialize(): array {
|
||||
return array(
|
||||
'uid' => $this->languageId,
|
||||
'code' => $this->langCode,
|
||||
|
@ -28,7 +28,7 @@ class Session extends ApiObject {
|
||||
$this->csrfToken = $csrfToken ?? generateRandomString(16);
|
||||
}
|
||||
|
||||
public static function create($user, $stayLoggedIn) {
|
||||
public static function create($user, $stayLoggedIn): ?Session {
|
||||
$session = new Session($user, null, null);
|
||||
if($session->insert($stayLoggedIn)) {
|
||||
return $session;
|
||||
@ -69,15 +69,15 @@ class Session extends ApiObject {
|
||||
setcookie('session', $sessionCookie, $this->getExpiresTime(), "/", "", $secure);
|
||||
}
|
||||
|
||||
public function getExpiresTime() {
|
||||
public function getExpiresTime(): int {
|
||||
return ($this->stayLoggedIn == 0 ? 0 : $this->expires);
|
||||
}
|
||||
|
||||
public function getExpiresSeconds() {
|
||||
public function getExpiresSeconds(): int {
|
||||
return ($this->stayLoggedIn == 0 ? -1 : $this->expires - time());
|
||||
}
|
||||
|
||||
public function jsonSerialize() {
|
||||
public function jsonSerialize(): array {
|
||||
return array(
|
||||
'uid' => $this->sessionId,
|
||||
'user_id' => $this->user->getId(),
|
||||
@ -89,7 +89,7 @@ class Session extends ApiObject {
|
||||
);
|
||||
}
|
||||
|
||||
public function insert($stayLoggedIn) {
|
||||
public function insert($stayLoggedIn): bool {
|
||||
$this->updateMetaData();
|
||||
$sql = $this->user->getSQL();
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?php
|
||||
|
||||
define("WEBBASE_VERSION", "1.2.2");
|
||||
define("WEBBASE_VERSION", "1.2.3");
|
||||
|
||||
function getProtocol() {
|
||||
function getProtocol(): string {
|
||||
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https" : "http";
|
||||
}
|
||||
|
||||
@ -26,12 +26,12 @@ function generateRandomString($length): string {
|
||||
return $randomString;
|
||||
}
|
||||
|
||||
function startsWith($haystack, $needle) {
|
||||
function startsWith($haystack, $needle): bool {
|
||||
$length = strlen($needle);
|
||||
return (substr($haystack, 0, $length) === $needle);
|
||||
}
|
||||
|
||||
function endsWith($haystack, $needle) {
|
||||
function endsWith($haystack, $needle): bool {
|
||||
$length = strlen($needle);
|
||||
if ($length == 0)
|
||||
return true;
|
||||
@ -97,7 +97,7 @@ function createError($msg) {
|
||||
return json_encode(array("success" => false, "msg" => $msg));
|
||||
}
|
||||
|
||||
function serveStatic(string $webRoot, string $file) {
|
||||
function serveStatic(string $webRoot, string $file): string {
|
||||
|
||||
$path = realpath($webRoot . "/" . $file);
|
||||
if (!startsWith($path, $webRoot . "/")) {
|
||||
|
@ -141,12 +141,11 @@ if(isset($_GET["api"]) && is_string($_GET["api"])) {
|
||||
$response = serveStatic($currentDir, $target);
|
||||
break;
|
||||
case "dynamic":
|
||||
$view = parseClass($extra);
|
||||
$file = getClassPath($target);
|
||||
if (!file_exists($file) || !is_subclass_of($target, Document::class)) {
|
||||
$document = new Document404($user, $view);
|
||||
$document = new Document404($user, $extra);
|
||||
} else {
|
||||
$document = new $target($user, $view);
|
||||
$document = new $target($user, $extra);
|
||||
}
|
||||
|
||||
$response = $document->getCode();
|
||||
|
2
js/admin.min.js
vendored
2
js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user