diff --git a/src/_h5ai/backend/php/class-bootstrap.php b/src/_h5ai/backend/php/class-bootstrap.php
index 2bb458be..d47a8275 100644
--- a/src/_h5ai/backend/php/class-bootstrap.php
+++ b/src/_h5ai/backend/php/class-bootstrap.php
@@ -21,9 +21,11 @@ class Bootstrap {
(new Api($context))->apply();
} else if ($context->is_info_request()) {
$public_href = $setup->get('PUBLIC_HREF');
+ $x_head_tags = $context->get_x_head_html();
require __DIR__ . '/pages/info.php';
} else {
$public_href = $setup->get('PUBLIC_HREF');
+ $x_head_tags = $context->get_x_head_html();
$fallback_html = (new Fallback($context))->get_html();
require __DIR__ . '/pages/index.php';
}
diff --git a/src/_h5ai/backend/php/core/class-context.php b/src/_h5ai/backend/php/core/class-context.php
index 242975b2..2383a605 100644
--- a/src/_h5ai/backend/php/core/class-context.php
+++ b/src/_h5ai/backend/php/core/class-context.php
@@ -17,7 +17,7 @@ class Context {
$this->request = $request;
$this->setup = $setup;
- $this->options = Util::load_commented_json($this->setup->get('APP_PATH') . '/conf/options.json');
+ $this->options = Json::load($this->setup->get('APP_PATH') . '/conf/options.json');
$this->passhash = $this->query_option('passhash', '');
$this->options['hasCustomPasshash'] = strcasecmp($this->passhash, Context::$DEFAULT_PASSHASH) !== 0;
@@ -51,7 +51,7 @@ class Context {
public function get_types() {
- return Util::load_commented_json($this->setup->get('APP_PATH') . '/conf/types.json');
+ return Json::load($this->setup->get('APP_PATH') . '/conf/types.json');
}
public function login_admin($pass) {
@@ -222,7 +222,7 @@ class Context {
if ($dir = opendir($l10n_path)) {
while (($file = readdir($dir)) !== false) {
if (Util::ends_with($file, '.json')) {
- $translations = Util::load_commented_json($l10n_path . '/' . $file);
+ $translations = Json::load($l10n_path . '/' . $file);
$langs[basename($file, '.json')] = $translations['lang'];
}
}
@@ -239,7 +239,7 @@ class Context {
foreach ($iso_codes as $iso_code) {
$file = $this->setup->get('APP_PATH') . '/conf/l10n/' . $iso_code . '.json';
- $results[$iso_code] = Util::load_commented_json($file);
+ $results[$iso_code] = Json::load($file);
$results[$iso_code]['isoCode'] = $iso_code;
}
@@ -257,4 +257,31 @@ class Context {
return $hrefs;
}
+
+ private function prefix_x_head_href($href) {
+
+ if (preg_match('@^(https?://|/)@i', $href)) {
+ return $href;
+ }
+
+ return $this->setup->get('PUBLIC_HREF') . 'ext/' . $href;
+ }
+
+ public function get_x_head_html() {
+
+ $scripts = $this->query_option('resources.scripts', []);
+ $styles = $this->query_option('resources.styles', []);
+
+ $tags = '';
+
+ foreach ($styles as $href) {
+ $tags .= '';
+ }
+
+ foreach ($scripts as $href) {
+ $tags .= '';
+ }
+
+ return $tags;
+ }
}
diff --git a/src/_h5ai/backend/php/core/class-json.php b/src/_h5ai/backend/php/core/class-json.php
new file mode 100644
index 00000000..06626f57
--- /dev/null
+++ b/src/_h5ai/backend/php/core/class-json.php
@@ -0,0 +1,71 @@
+get('CACHE_PRV_PATH') . '/cmds.json', false);
- $cmds = Util::load_commented_json($cmds_cache_path);
+ $cmds = Json::load($cmds_cache_path);
if (sizeof($cmds) === 0 || $this->refresh) {
$cmds['command'] = Util::exec_0('command -v command');
$cmds['which'] = Util::exec_0('which which');
@@ -141,7 +141,7 @@ class Setup {
$cmds[$c] = ($cmd !== false) && Util::exec_0($cmd . ' ' . $c);
}
- Util::save_json($cmds_cache_path, $cmds);
+ Json::save($cmds_cache_path, $cmds);
}
foreach ($cmds as $c => $has) {
$this->set('HAS_CMD_' . strtoupper($c), $has);
diff --git a/src/_h5ai/backend/php/core/class-util.php b/src/_h5ai/backend/php/core/class-util.php
index c75c497e..35c0940c 100644
--- a/src/_h5ai/backend/php/core/class-util.php
+++ b/src/_h5ai/backend/php/core/class-util.php
@@ -61,26 +61,6 @@ class Util {
return Util::RE_DELIMITER . str_replace(Util::RE_DELIMITER, '\\' . Util::RE_DELIMITER, $pattern) . Util::RE_DELIMITER;
}
- public static function load_commented_json($path) {
-
- if (!file_exists($path)) {
- return [];
- }
-
- $content = file_get_contents($path);
-
- // remove comments to get pure json
- $content = preg_replace("/\/\*.*?\*\/|\/\/.*?(\n|$)/s", '', $content);
-
- return json_decode($content, true);
- }
-
- public static function save_json($path, $obj) {
-
- $json = json_encode($obj);
- return file_put_contents($path, $json) !== false;
- }
-
public static function passthru_cmd($cmd) {
$rc = null;
diff --git a/src/_h5ai/backend/php/pages/page.tpl.jade b/src/_h5ai/backend/php/pages/page.tpl.jade
index f0745448..3f37e5aa 100644
--- a/src/_h5ai/backend/php/pages/page.tpl.jade
+++ b/src/_h5ai/backend/php/pages/page.tpl.jade
@@ -1,5 +1,3 @@
-- var public_href = '= $public_href; ?>'
-
block init
@@ -13,11 +11,11 @@ head
title #{title}
meta(name='description', content='#{title}')
meta(name='viewport', content='width=device-width, initial-scale=1')
- link(rel='shortcut icon', href!='#{public_href}images/favicon/favicon-16-32.ico')
- link(rel='apple-touch-icon-precomposed', type='image/png', href!='#{public_href}images/favicon/favicon-152.png')
- link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Roboto:300,400,700')
- link(rel='stylesheet', href!='#{public_href}css/styles.css')
- script(src!='#{public_href}js/scripts.js', data-module='#{module}')
+ link(rel='shortcut icon', href!='= $public_href; ?>images/favicon/favicon-16-32.ico')
+ link(rel='apple-touch-icon-precomposed', type='image/png', href!='= $public_href; ?>images/favicon/favicon-152.png')
+ link(rel='stylesheet', href!='= $public_href; ?>css/styles.css')
+ script(src!='= $public_href; ?>js/scripts.js', data-module='#{module}')
+ = $x_head_tags; ?>
body#root(class='#{module}')
diff --git a/src/_h5ai/conf/options.json b/src/_h5ai/conf/options.json
index e8f7d74d..61202b72 100644
--- a/src/_h5ai/conf/options.json
+++ b/src/_h5ai/conf/options.json
@@ -16,6 +16,25 @@ Options
+ /*
+ Resources.
+
+ Additional script and style tags added to all pages. Paths not beginning
+ with "http://", "https://" or "/" will be looked up relative to
+ "_h5ai/public/ext/" (no check for existence).
+
+ - scripts: array of strings
+ - styles: array of strings
+ */
+ "resources": {
+ "scripts": [],
+ "styles": [
+ "//fonts.googleapis.com/css?family=Roboto:300,400,700"
+ ]
+ },
+
+
+
/*
General view options.