1
0
Fork 0
mirror of https://github.com/sbrl/Pepperminty-Wiki.git synced 2024-11-25 17:23:00 +00:00

Add title to internal links, and refactor page cache id generation

This commit is contained in:
Starbeamrainbowlabs 2019-02-10 23:01:01 +00:00
parent 1938bfd5b9
commit a5563bb458
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
6 changed files with 166 additions and 46 deletions

View file

@ -19,6 +19,7 @@ This file holds the changelog for Pepperminty Wiki. This is the master list of t
- Useful for longer pages - Useful for longer pages
- `parser_cache_min_size` may need tuning for your specific installation (lower it if you regularly use features that are slow to parse; raise if it's the opposite) - `parser_cache_min_size` may need tuning for your specific installation (lower it if you regularly use features that are slow to parse; raise if it's the opposite)
- You may need to turn this off if it interferes with complex dynamic includes - You may need to turn this off if it interferes with complex dynamic includes
- Internal links now show the page name on hover (inter-wiki links are also supported here)
### Changed ### Changed
- Completely reworked the README to refactor out the documentation to its [own static site](https://starbeamrainbowlabs.com/labs/peppermint/_docpress/) - Completely reworked the README to refactor out the documentation to its [own static site](https://starbeamrainbowlabs.com/labs/peppermint/_docpress/)

View file

@ -413,7 +413,7 @@ if($settings->sessionprefix == "auto")
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/** The version of Pepperminty Wiki currently running. */ /** The version of Pepperminty Wiki currently running. */
$version = "v0.18-dev"; $version = "v0.18-dev";
$commit = "d51c3f163fbaeed63e8b0109e684a810d2a4604a"; $commit = "1938bfd5b985a4a21872010d963553d10cab25e1";
/// Environment /// /// Environment ///
/** Holds information about the current request environment. */ /** Holds information about the current request environment. */
$env = new stdClass(); $env = new stdClass();
@ -2123,9 +2123,14 @@ function has_action($action_name)
} }
$parsers = [ $parsers = [
"none" => function() { "none" => [
"parser" => function() {
throw new Exception("No parser registered!");
},
"hash_generator" => function() {
throw new Exception("No parser registered!"); throw new Exception("No parser registered!");
} }
]
]; ];
/** /**
* Registers a new parser. * Registers a new parser.
@ -2133,13 +2138,16 @@ $parsers = [
* @param string $name The name of the new parser to register. * @param string $name The name of the new parser to register.
* @param function $parser_code The function to register as a new parser. * @param function $parser_code The function to register as a new parser.
*/ */
function add_parser($name, $parser_code) function add_parser($name, $parser_code, $hash_generator)
{ {
global $parsers; global $parsers;
if(isset($parsers[$name])) if(isset($parsers[$name]))
throw new Exception("Can't register parser with name '$name' because a parser with that name already exists."); throw new Exception("Can't register parser with name '$name' because a parser with that name already exists.");
$parsers[$name] = $parser_code; $parsers[$name] = [
"parser" => $parser_code,
"hash_generator" => $hash_generator
];
} }
/** /**
* Parses the specified page source using the parser specified in the settings * Parses the specified page source using the parser specified in the settings
@ -2164,7 +2172,7 @@ function parse_page_source($source, $use_cache = true) {
$source = htmlentities($source, ENT_QUOTES | ENT_HTML5); $source = htmlentities($source, ENT_QUOTES | ENT_HTML5);
*/ */
$cache_id = str_replace(["+","/"], ["-","_"], base64_encode(hash("sha256", "$version|$settings->parser|$source", true))); $cache_id = $parsers[$settings->parser]["hash_generator"]($source);
$cache_file = "{$paths->cache_directory}/{$cache_id}.html"; $cache_file = "{$paths->cache_directory}/{$cache_id}.html";
$result = null; $result = null;
@ -2173,7 +2181,7 @@ function parse_page_source($source, $use_cache = true) {
$result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n"; $result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
} }
if($result == null) { if($result == null) {
$result = $parsers[$settings->parser]($source); $result = $parsers[$settings->parser]["parser"]($source);
// If we should use the cache and we failed to write to it, warn the admin. // If we should use the cache and we failed to write to it, warn the admin.
// It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern. // It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern.
if($use_cache && !file_put_contents($cache_file, $result)) if($use_cache && !file_put_contents($cache_file, $result))
@ -3723,7 +3731,7 @@ function is_interwiki_link($pagename) {
register_module([ register_module([
"name" => "Recent Changes", "name" => "Recent Changes",
"version" => "0.3.5", "version" => "0.4",
"author" => "Starbeamrainbowlabs", "author" => "Starbeamrainbowlabs",
"description" => "Adds recent changes. Access through the 'recent-changes' action.", "description" => "Adds recent changes. Access through the 'recent-changes' action.",
"id" => "feature-recent-changes", "id" => "feature-recent-changes",
@ -4173,7 +4181,7 @@ function render_recent_change_atom($recent_changes) {
$xml->startElement("author"); $xml->startElement("author");
$xml->writeElement("name", $recent_change->user); $xml->writeElement("name", $recent_change->user);
$xml->writeElement("uri", "$full_url_stem?page=".rawurlencode("$settings->user_page_prefix/$recent_change->page")); $xml->writeElement("uri", "$full_url_stem?page=".rawurlencode("$settings->user_page_prefix/$recent_change->user"));
$xml->endElement(); $xml->endElement();
$xml->endElement(); $xml->endElement();
@ -9022,7 +9030,7 @@ register_module([
register_module([ register_module([
"name" => "Parsedown", "name" => "Parsedown",
"version" => "0.9.12", "version" => "0.9.13",
"author" => "Emanuil Rusev & Starbeamrainbowlabs", "author" => "Emanuil Rusev & Starbeamrainbowlabs",
"description" => "An upgraded (now default!) parser based on Emanuil Rusev's Parsedown Extra PHP library (https://github.com/erusev/parsedown-extra), which is licensed MIT. Please be careful, as this module adds some weight to your installation, and also *requires* write access to the disk on first load.", "description" => "An upgraded (now default!) parser based on Emanuil Rusev's Parsedown Extra PHP library (https://github.com/erusev/parsedown-extra), which is licensed MIT. Please be careful, as this module adds some weight to your installation, and also *requires* write access to the disk on first load.",
"id" => "parser-parsedown", "id" => "parser-parsedown",
@ -9037,6 +9045,28 @@ register_module([
$result = $parser->text($source); $result = $parser->text($source);
return $result; return $result;
}, function($source) {
global $version, $settings, $pageindex;
$id_text = "$version|$settings->parser|$source";
// Find template includes
preg_match_all(
'/\{\{\s*([^|]+)\s*(?:\|[^}]*)?\}\}/',
$source, $includes
);
foreach($includes[1] as $include_pagename) {
if(empty($pageindex->$include_pagename))
$id_text .= "|$include_pagename:" . parsedown_pagename_resolve(
$pageindex->$include_pagename->lastmodified
);
}
return str_replace(["+","/"], ["-","_"], base64_encode(hash(
"sha256",
$id_text,
true
)));
}); });
/* /*
@ -9224,6 +9254,28 @@ if(!file_exists("./ParsedownExtra.php") || filesize("./ParsedownExtra.php") ===
require_once("./Parsedown.php"); require_once("./Parsedown.php");
require_once("./ParsedownExtra.php"); require_once("./ParsedownExtra.php");
/**
* Attempts to 'auto-correct' a page name by trying different capitalisation
* combinations.
* @param string $pagename The page name to auto-correct.
* @return string The auto-corrected page name.
*/
function parsedown_pagename_resolve($pagename) {
global $pageindex;
// If the page doesn't exist, check varying different
// capitalisations to see if it exists under some variant.
if(!empty($pageindex->$pagename))
return $pagename;
$pagename = ucfirst($pagename);
if(!empty($pageindex->$pagename))
return $pagename;
$pagename = ucwords($pagename);
return $pagename;
}
/* /*
* ██████ █████ ██████ ███████ ███████ ██████ ██████ ██ ██ ███ ██ * ██████ █████ ██████ ███████ ███████ ██████ ██████ ██ ██ ███ ██
* ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
@ -9501,14 +9553,10 @@ class PeppermintParsedown extends ParsedownExtra
// 3: Page name auto-correction // 3: Page name auto-correction
// ------------------------------- // -------------------------------
$is_interwiki_link = module_exists("feature-interwiki-links") && is_interwiki_link($link_page); $is_interwiki_link = module_exists("feature-interwiki-links") && is_interwiki_link($link_page);
if(!$is_interwiki_link && empty($pageindex->$link_page)) { // Try different variants on the pagename to try and get it to
// If the page doesn't exist, check varying different // match something automagically
// capitalisations to see if it exists under some variant. if(!$is_interwiki_link && empty($pageindex->$link_page))
if(!empty($pageindex->{ucfirst($link_page)})) $link_page = parsedown_pagename_resolve($link_page);
$link_page = ucfirst($link_page);
else if(!empty($pageindex->{ucwords($link_page)}))
$link_page = ucwords($link_page);
}
// 4: Construct the full url // 4: Construct the full url
@ -9529,6 +9577,12 @@ class PeppermintParsedown extends ParsedownExtra
$is_interwiki_link = false; $is_interwiki_link = false;
} }
// 5: Construct the title
// -------------------------------
$title = $link_page;
if($is_interwiki_link)
$title = interwiki_pagename_resolve($link_page)->name . ": " . interwiki_pagename_parse($link_page)[1] . " (Interwiki)";
if(strlen($hash_code) > 0) if(strlen($hash_code) > 0)
$link_url .= "#$hash_code"; $link_url .= "#$hash_code";
@ -9540,8 +9594,10 @@ class PeppermintParsedown extends ParsedownExtra
"element" => [ "element" => [
"name" => "a", "name" => "a",
"text" => $display, "text" => $display,
"attributes" => [ "attributes" => [
"href" => $link_url "href" => $link_url,
"title" => $title
] ]
] ]
]; ];

View file

@ -1720,9 +1720,14 @@ function has_action($action_name)
} }
$parsers = [ $parsers = [
"none" => function() { "none" => [
"parser" => function() {
throw new Exception("No parser registered!");
},
"hash_generator" => function() {
throw new Exception("No parser registered!"); throw new Exception("No parser registered!");
} }
]
]; ];
/** /**
* Registers a new parser. * Registers a new parser.
@ -1730,13 +1735,16 @@ $parsers = [
* @param string $name The name of the new parser to register. * @param string $name The name of the new parser to register.
* @param function $parser_code The function to register as a new parser. * @param function $parser_code The function to register as a new parser.
*/ */
function add_parser($name, $parser_code) function add_parser($name, $parser_code, $hash_generator)
{ {
global $parsers; global $parsers;
if(isset($parsers[$name])) if(isset($parsers[$name]))
throw new Exception("Can't register parser with name '$name' because a parser with that name already exists."); throw new Exception("Can't register parser with name '$name' because a parser with that name already exists.");
$parsers[$name] = $parser_code; $parsers[$name] = [
"parser" => $parser_code,
"hash_generator" => $hash_generator
];
} }
/** /**
* Parses the specified page source using the parser specified in the settings * Parses the specified page source using the parser specified in the settings
@ -1761,7 +1769,7 @@ function parse_page_source($source, $use_cache = true) {
$source = htmlentities($source, ENT_QUOTES | ENT_HTML5); $source = htmlentities($source, ENT_QUOTES | ENT_HTML5);
*/ */
$cache_id = str_replace(["+","/"], ["-","_"], base64_encode(hash("sha256", "$version|$settings->parser|$source", true))); $cache_id = $parsers[$settings->parser]["hash_generator"]($source);
$cache_file = "{$paths->cache_directory}/{$cache_id}.html"; $cache_file = "{$paths->cache_directory}/{$cache_id}.html";
$result = null; $result = null;
@ -1770,7 +1778,7 @@ function parse_page_source($source, $use_cache = true) {
$result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n"; $result .= "\n<!-- cache: hit, id: $cache_id, took: " . round((microtime(true) - $start_time)*1000, 5) . "ms -->\n";
} }
if($result == null) { if($result == null) {
$result = $parsers[$settings->parser]($source); $result = $parsers[$settings->parser]["parser"]($source);
// If we should use the cache and we failed to write to it, warn the admin. // If we should use the cache and we failed to write to it, warn the admin.
// It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern. // It's not terribible if we can't write to the cache directory (so we shouldn't stop dead & refuse service), but it's still of concern.
if($use_cache && !file_put_contents($cache_file, $result)) if($use_cache && !file_put_contents($cache_file, $result))

View file

@ -91,11 +91,11 @@
}, },
{ {
"name": "Recent Changes", "name": "Recent Changes",
"version": "0.3.5", "version": "0.4",
"author": "Starbeamrainbowlabs", "author": "Starbeamrainbowlabs",
"description": "Adds recent changes. Access through the 'recent-changes' action.", "description": "Adds recent changes. Access through the 'recent-changes' action.",
"id": "feature-recent-changes", "id": "feature-recent-changes",
"lastupdate": 1548630687, "lastupdate": 1549211706,
"optional": false "optional": false
}, },
{ {
@ -271,20 +271,20 @@
}, },
{ {
"name": "Old Default Parser", "name": "Old Default Parser",
"version": "0.10", "version": "0.10.1",
"author": "Johnny Broadway & Starbeamrainbowlabs", "author": "Johnny Broadway & Starbeamrainbowlabs",
"description": "The *old* default parser for Pepperminty Wiki. Based on Johnny Broadway's Slimdown (with more than a few modifications). This parser's features are documented in the help page. Superceded by a customised extension of parsedown extra.", "description": "The *old* default parser for Pepperminty Wiki. Based on Johnny Broadway's Slimdown (with more than a few modifications). This parser's features are documented in the help page. Superceded by a customised extension of parsedown extra.",
"id": "parser-default-old", "id": "parser-default-old",
"lastupdate": 1458824880, "lastupdate": 1549839049,
"optional": true "optional": true
}, },
{ {
"name": "Parsedown", "name": "Parsedown",
"version": "0.9.12", "version": "0.9.13",
"author": "Emanuil Rusev & Starbeamrainbowlabs", "author": "Emanuil Rusev & Starbeamrainbowlabs",
"description": "An upgraded (now default!) parser based on Emanuil Rusev's Parsedown Extra PHP library (https:\/\/github.com\/erusev\/parsedown-extra), which is licensed MIT. Please be careful, as this module adds some weight to your installation, and also *requires* write access to the disk on first load.", "description": "An upgraded (now default!) parser based on Emanuil Rusev's Parsedown Extra PHP library (https:\/\/github.com\/erusev\/parsedown-extra), which is licensed MIT. Please be careful, as this module adds some weight to your installation, and also *requires* write access to the disk on first load.",
"id": "parser-parsedown", "id": "parser-parsedown",
"lastupdate": 1546724653, "lastupdate": 1549839523,
"optional": false "optional": false
} }
] ]

View file

@ -1,7 +1,7 @@
<?php <?php
register_module([ register_module([
"name" => "Old Default Parser", "name" => "Old Default Parser",
"version" => "0.10", "version" => "0.10.1",
"author" => "Johnny Broadway & Starbeamrainbowlabs", "author" => "Johnny Broadway & Starbeamrainbowlabs",
"description" => "The *old* default parser for Pepperminty Wiki. Based on Johnny Broadway's Slimdown (with more than a few modifications). This parser's features are documented in the help page. Superceded by a customised extension of parsedown extra.", "description" => "The *old* default parser for Pepperminty Wiki. Based on Johnny Broadway's Slimdown (with more than a few modifications). This parser's features are documented in the help page. Superceded by a customised extension of parsedown extra.",
"id" => "parser-default-old", "id" => "parser-default-old",
@ -11,6 +11,13 @@ register_module([
add_parser("default", function($markdown) { add_parser("default", function($markdown) {
return Slimdown::render($markdown); return Slimdown::render($markdown);
}, function($source) {
global $version, $settings;
return str_replace(["+","/"], ["-","_"], base64_encode(hash(
"sha256",
"$version|$settings->parser|$source",
true
)));
}); });
// Register the help section // Register the help section
@ -159,7 +166,7 @@ class Slimdown {
return trim ($text); return trim ($text);
} }
} }
//////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
?> ?>

View file

@ -1,7 +1,7 @@
<?php <?php
register_module([ register_module([
"name" => "Parsedown", "name" => "Parsedown",
"version" => "0.9.12", "version" => "0.10",
"author" => "Emanuil Rusev & Starbeamrainbowlabs", "author" => "Emanuil Rusev & Starbeamrainbowlabs",
"description" => "An upgraded (now default!) parser based on Emanuil Rusev's Parsedown Extra PHP library (https://github.com/erusev/parsedown-extra), which is licensed MIT. Please be careful, as this module adds some weight to your installation, and also *requires* write access to the disk on first load.", "description" => "An upgraded (now default!) parser based on Emanuil Rusev's Parsedown Extra PHP library (https://github.com/erusev/parsedown-extra), which is licensed MIT. Please be careful, as this module adds some weight to your installation, and also *requires* write access to the disk on first load.",
"id" => "parser-parsedown", "id" => "parser-parsedown",
@ -16,6 +16,28 @@ register_module([
$result = $parser->text($source); $result = $parser->text($source);
return $result; return $result;
}, function($source) {
global $version, $settings, $pageindex;
$id_text = "$version|$settings->parser|$source";
// Find template includes
preg_match_all(
'/\{\{\s*([^|]+)\s*(?:\|[^}]*)?\}\}/',
$source, $includes
);
foreach($includes[1] as $include_pagename) {
if(empty($pageindex->$include_pagename))
$id_text .= "|$include_pagename:" . parsedown_pagename_resolve(
$pageindex->$include_pagename->lastmodified
);
}
return str_replace(["+","/"], ["-","_"], base64_encode(hash(
"sha256",
$id_text,
true
)));
}); });
/* /*
@ -203,6 +225,28 @@ if(!file_exists("./ParsedownExtra.php") || filesize("./ParsedownExtra.php") ===
require_once("./Parsedown.php"); require_once("./Parsedown.php");
require_once("./ParsedownExtra.php"); require_once("./ParsedownExtra.php");
/**
* Attempts to 'auto-correct' a page name by trying different capitalisation
* combinations.
* @param string $pagename The page name to auto-correct.
* @return string The auto-corrected page name.
*/
function parsedown_pagename_resolve($pagename) {
global $pageindex;
// If the page doesn't exist, check varying different
// capitalisations to see if it exists under some variant.
if(!empty($pageindex->$pagename))
return $pagename;
$pagename = ucfirst($pagename);
if(!empty($pageindex->$pagename))
return $pagename;
$pagename = ucwords($pagename);
return $pagename;
}
/* /*
* ██████ █████ ██████ ███████ ███████ ██████ ██████ ██ ██ ███ ██ * ██████ █████ ██████ ███████ ███████ ██████ ██████ ██ ██ ███ ██
* ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██ * ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ████ ██
@ -480,14 +524,10 @@ class PeppermintParsedown extends ParsedownExtra
// 3: Page name auto-correction // 3: Page name auto-correction
// ------------------------------- // -------------------------------
$is_interwiki_link = module_exists("feature-interwiki-links") && is_interwiki_link($link_page); $is_interwiki_link = module_exists("feature-interwiki-links") && is_interwiki_link($link_page);
if(!$is_interwiki_link && empty($pageindex->$link_page)) { // Try different variants on the pagename to try and get it to
// If the page doesn't exist, check varying different // match something automagically
// capitalisations to see if it exists under some variant. if(!$is_interwiki_link && empty($pageindex->$link_page))
if(!empty($pageindex->{ucfirst($link_page)})) $link_page = parsedown_pagename_resolve($link_page);
$link_page = ucfirst($link_page);
else if(!empty($pageindex->{ucwords($link_page)}))
$link_page = ucwords($link_page);
}
// 4: Construct the full url // 4: Construct the full url
@ -508,6 +548,12 @@ class PeppermintParsedown extends ParsedownExtra
$is_interwiki_link = false; $is_interwiki_link = false;
} }
// 5: Construct the title
// -------------------------------
$title = $link_page;
if($is_interwiki_link)
$title = interwiki_pagename_resolve($link_page)->name . ": " . interwiki_pagename_parse($link_page)[1] . " (Interwiki)";
if(strlen($hash_code) > 0) if(strlen($hash_code) > 0)
$link_url .= "#$hash_code"; $link_url .= "#$hash_code";
@ -519,8 +565,10 @@ class PeppermintParsedown extends ParsedownExtra
"element" => [ "element" => [
"name" => "a", "name" => "a",
"text" => $display, "text" => $display,
"attributes" => [ "attributes" => [
"href" => $link_url "href" => $link_url,
"title" => $title
] ]
] ]
]; ];