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 {
|
public function getCode(): string {
|
||||||
$view = $this->getDocument()->getView() ?? "<Empty>";
|
$view = $this->getDocument()->getRequestedView() ?? "<Empty>";
|
||||||
return "<b>Requested View:</b> " . htmlspecialchars($view);
|
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.
|
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?
|
## Anything more?
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ export default function Sidebar(props) {
|
|||||||
let filePath = parent.filesPath;
|
let filePath = parent.filesPath;
|
||||||
if (filePath) {
|
if (filePath) {
|
||||||
li.push(<li className={"nav-item"} key={"files"}>
|
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"} />
|
<Icon icon={"folder"} className={"nav-icon"} />
|
||||||
<p>Files</p>
|
<p>Files</p>
|
||||||
</a>
|
</a>
|
||||||
|
@ -121,7 +121,13 @@ export default function HelpPage() {
|
|||||||
<b>Project Lead & Main Developer</b>
|
<b>Project Lead & Main Developer</b>
|
||||||
<ul className={"list-unstyled"}>
|
<ul className={"list-unstyled"}>
|
||||||
<li><small><Icon icon={"address-card"} className={"mr-1"}/>Roman Hergenreder</small></li>
|
<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>
|
<li><small><Icon icon={"envelope"} className={"mr-1"}/><a href={"mailto:webmaster@romanh.de"}>webmaster@romanh.de</a></small></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -422,7 +422,7 @@ export default class Settings extends React.Component {
|
|||||||
<label className={"form-check-label"} htmlFor={"recaptcha_enabled"}>
|
<label className={"form-check-label"} htmlFor={"recaptcha_enabled"}>
|
||||||
Enable Google's reCaptcha
|
Enable Google's reCaptcha
|
||||||
<span className={"ml-2"}>
|
<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
|
More Info
|
||||||
<sup><small><Icon icon={"external-link-alt"} className={"ml-1"}/></small></sup>
|
<sup><small><Icon icon={"external-link-alt"} className={"ml-1"}/></small></sup>
|
||||||
</a>)
|
</a>)
|
||||||
|
@ -27,12 +27,17 @@ abstract class Document {
|
|||||||
|
|
||||||
public function getView() : ?View {
|
public function getView() : ?View {
|
||||||
|
|
||||||
$file = getClassPath($this->activeView);
|
$view = parseClass($this->activeView);
|
||||||
if(!file_exists($file) || !is_subclass_of($this->activeView, View::class)) {
|
$file = getClassPath($view);
|
||||||
|
if(!file_exists($file) || !is_subclass_of($view, View::class)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new $this->activeView($this);
|
return new $view($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequestedView(): string {
|
||||||
|
return $this->activeView;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCode(): string {
|
function getCode(): string {
|
||||||
|
@ -89,7 +89,7 @@ abstract class View extends StaticView {
|
|||||||
|
|
||||||
protected function createExternalLink($link, $title=null): string {
|
protected function createExternalLink($link, $title=null): string {
|
||||||
if(is_null($title)) $title=$link;
|
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 {
|
protected function createIcon($icon, $type = "fas", $classes = ""): string {
|
||||||
|
@ -4,7 +4,7 @@ namespace Objects;
|
|||||||
|
|
||||||
abstract class ApiObject implements \JsonSerializable {
|
abstract class ApiObject implements \JsonSerializable {
|
||||||
|
|
||||||
public abstract function jsonSerialize();
|
public abstract function jsonSerialize(): array;
|
||||||
|
|
||||||
public function __toString() { return json_encode($this); }
|
public function __toString() { return json_encode($this); }
|
||||||
|
|
||||||
|
@ -31,7 +31,10 @@ namespace Objects {
|
|||||||
public function getEntries() { return $this->entries; }
|
public function getEntries() { return $this->entries; }
|
||||||
public function getModules() { return $this->modules; }
|
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))
|
if(!is_object($module))
|
||||||
$module = new $module;
|
$module = new $module;
|
||||||
|
|
||||||
@ -40,7 +43,7 @@ namespace Objects {
|
|||||||
$this->modules[] = $module;
|
$this->modules[] = $module;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function translate($key) {
|
public function translate(string $key): string {
|
||||||
if(isset($this->entries[$key]))
|
if(isset($this->entries[$key]))
|
||||||
return $this->entries[$key];
|
return $this->entries[$key];
|
||||||
|
|
||||||
@ -51,7 +54,7 @@ namespace Objects {
|
|||||||
setcookie('lang', $this->langCode, 0, "/", "");
|
setcookie('lang', $this->langCode, 0, "/", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize() {
|
public function jsonSerialize(): array {
|
||||||
return array(
|
return array(
|
||||||
'uid' => $this->languageId,
|
'uid' => $this->languageId,
|
||||||
'code' => $this->langCode,
|
'code' => $this->langCode,
|
||||||
|
@ -28,7 +28,7 @@ class Session extends ApiObject {
|
|||||||
$this->csrfToken = $csrfToken ?? generateRandomString(16);
|
$this->csrfToken = $csrfToken ?? generateRandomString(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function create($user, $stayLoggedIn) {
|
public static function create($user, $stayLoggedIn): ?Session {
|
||||||
$session = new Session($user, null, null);
|
$session = new Session($user, null, null);
|
||||||
if($session->insert($stayLoggedIn)) {
|
if($session->insert($stayLoggedIn)) {
|
||||||
return $session;
|
return $session;
|
||||||
@ -69,15 +69,15 @@ class Session extends ApiObject {
|
|||||||
setcookie('session', $sessionCookie, $this->getExpiresTime(), "/", "", $secure);
|
setcookie('session', $sessionCookie, $this->getExpiresTime(), "/", "", $secure);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExpiresTime() {
|
public function getExpiresTime(): int {
|
||||||
return ($this->stayLoggedIn == 0 ? 0 : $this->expires);
|
return ($this->stayLoggedIn == 0 ? 0 : $this->expires);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getExpiresSeconds() {
|
public function getExpiresSeconds(): int {
|
||||||
return ($this->stayLoggedIn == 0 ? -1 : $this->expires - time());
|
return ($this->stayLoggedIn == 0 ? -1 : $this->expires - time());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize() {
|
public function jsonSerialize(): array {
|
||||||
return array(
|
return array(
|
||||||
'uid' => $this->sessionId,
|
'uid' => $this->sessionId,
|
||||||
'user_id' => $this->user->getId(),
|
'user_id' => $this->user->getId(),
|
||||||
@ -89,7 +89,7 @@ class Session extends ApiObject {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function insert($stayLoggedIn) {
|
public function insert($stayLoggedIn): bool {
|
||||||
$this->updateMetaData();
|
$this->updateMetaData();
|
||||||
$sql = $this->user->getSQL();
|
$sql = $this->user->getSQL();
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?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";
|
return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https" : "http";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,12 +26,12 @@ function generateRandomString($length): string {
|
|||||||
return $randomString;
|
return $randomString;
|
||||||
}
|
}
|
||||||
|
|
||||||
function startsWith($haystack, $needle) {
|
function startsWith($haystack, $needle): bool {
|
||||||
$length = strlen($needle);
|
$length = strlen($needle);
|
||||||
return (substr($haystack, 0, $length) === $needle);
|
return (substr($haystack, 0, $length) === $needle);
|
||||||
}
|
}
|
||||||
|
|
||||||
function endsWith($haystack, $needle) {
|
function endsWith($haystack, $needle): bool {
|
||||||
$length = strlen($needle);
|
$length = strlen($needle);
|
||||||
if ($length == 0)
|
if ($length == 0)
|
||||||
return true;
|
return true;
|
||||||
@ -97,7 +97,7 @@ function createError($msg) {
|
|||||||
return json_encode(array("success" => false, "msg" => $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);
|
$path = realpath($webRoot . "/" . $file);
|
||||||
if (!startsWith($path, $webRoot . "/")) {
|
if (!startsWith($path, $webRoot . "/")) {
|
||||||
|
@ -141,12 +141,11 @@ if(isset($_GET["api"]) && is_string($_GET["api"])) {
|
|||||||
$response = serveStatic($currentDir, $target);
|
$response = serveStatic($currentDir, $target);
|
||||||
break;
|
break;
|
||||||
case "dynamic":
|
case "dynamic":
|
||||||
$view = parseClass($extra);
|
|
||||||
$file = getClassPath($target);
|
$file = getClassPath($target);
|
||||||
if(!file_exists($file) || !is_subclass_of($target, Document::class)) {
|
if (!file_exists($file) || !is_subclass_of($target, Document::class)) {
|
||||||
$document = new Document404($user, $view);
|
$document = new Document404($user, $extra);
|
||||||
} else {
|
} else {
|
||||||
$document = new $target($user, $view);
|
$document = new $target($user, $extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $document->getCode();
|
$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