diff --git a/src/PageLinkTrait.php b/src/PageLinkTrait.php
new file mode 100644
index 0000000..c2d2a62
--- /dev/null
+++ b/src/PageLinkTrait.php
@@ -0,0 +1,162 @@
+getPageUuidSafe();
+ $text = (string)$this->getLang('pagelink_unlinked');
+
+ if ($renderer instanceof \Doku_Renderer_xhtml) {
+ $renderer->doc .= '' . hsc($text) . '';
+ return;
+ }
+
+ $renderer->cdata('[n/a: ' . $text . ']');
+ }
+
+ /**
+ * Read the current page UUID (if any).
+ *
+ * @return string The UUID or empty string
+ */
+ protected function getPageUuidSafe(): string
+ {
+ global $ID;
+ $pageId = is_string($ID) ? $ID : '';
+ if ($pageId === '') return '';
+
+ if (function_exists('cleanID')) {
+ $pageId = (string)cleanID($pageId);
+ }
+ if ($pageId === '') return '';
+
+ $depth = (int)$this->getConf('pagelink_search_depth');
+ if ($depth < 0) $depth = 0;
+
+ $pageLink = new PageLink((string)$this->getConf('paths'), $depth);
+ $uuid = $pageLink->getPageUuid($pageId);
+ return $uuid ?? '';
+ }
+
+ /**
+ * Resolve the current page's pagelink folder for the blobs alias.
+ *
+ * Results are cached per page ID within a single request.
+ *
+ * @return string The linked folder path or empty string if not linked
+ */
+ protected function resolveBlobsRoot(): string
+ {
+ static $cached = [];
+
+ global $ID;
+ $pageId = is_string($ID) ? $ID : '';
+ if ($pageId === '') return '';
+
+ if (function_exists('cleanID')) {
+ $pageId = (string)cleanID($pageId);
+ }
+ if ($pageId === '') return '';
+
+ if (isset($cached[$pageId])) {
+ return (string)$cached[$pageId];
+ }
+
+ $depth = (int)$this->getConf('pagelink_search_depth');
+ if ($depth < 0) $depth = 0;
+
+ $pageLink = new PageLink((string)$this->getConf('paths'), $depth);
+ $uuid = $pageLink->getPageUuid($pageId);
+ if ($uuid === null) {
+ $cached[$pageId] = '';
+ return '';
+ }
+
+ $linkInfo = $pageLink->resolveUuid($uuid);
+ $folder = $linkInfo['folder'] ?? '';
+ if (!is_string($folder) || $folder === '') {
+ $cached[$pageId] = '';
+ return '';
+ }
+
+ $cached[$pageId] = $folder;
+ return $folder;
+ }
+
+ /**
+ * Build a path config string with the blobs alias appended (if available).
+ *
+ * @param string|null $blobsRoot The blobs root folder (or null to auto-resolve)
+ * @return string The path config string
+ */
+ protected function buildPathConfigWithBlobs(?string $blobsRoot = null): string
+ {
+ $pathConfig = (string)$this->getConf('paths');
+
+ if ($blobsRoot === null) {
+ $blobsRoot = $this->resolveBlobsRoot();
+ }
+
+ if ($blobsRoot !== '') {
+ $pathConfig = rtrim($pathConfig) . "\n" . $blobsRoot . "\nA> blobs";
+ }
+
+ return $pathConfig;
+ }
+
+ /**
+ * Create a Path helper with blobs alias support.
+ *
+ * @param string|null $blobsRoot The blobs root folder (or null to auto-resolve)
+ * @return Path
+ */
+ protected function createPathHelperWithBlobs(?string $blobsRoot = null): Path
+ {
+ return new Path($this->buildPathConfigWithBlobs($blobsRoot));
+ }
+
+ /**
+ * Create a Path helper using only the base paths config (no blobs alias).
+ *
+ * @return Path
+ */
+ protected function createPathHelper(): Path
+ {
+ return new Path((string)$this->getConf('paths'));
+ }
+}
diff --git a/syntax/AbstractSyntax.php b/syntax/AbstractSyntax.php
index 0c9e901..8be0d21 100644
--- a/syntax/AbstractSyntax.php
+++ b/syntax/AbstractSyntax.php
@@ -4,7 +4,7 @@ use dokuwiki\Extension\SyntaxPlugin;
use dokuwiki\plugin\luxtools\Crawler;
use dokuwiki\plugin\luxtools\Output;
use dokuwiki\plugin\luxtools\Path;
-use dokuwiki\plugin\luxtools\PageLink;
+use dokuwiki\plugin\luxtools\PageLinkTrait;
require_once(__DIR__ . '/../autoload.php');
@@ -16,6 +16,7 @@ require_once(__DIR__ . '/../autoload.php');
if (!class_exists('syntax_plugin_luxtools_abstract', false)) {
abstract class syntax_plugin_luxtools_abstract extends SyntaxPlugin
{
+ use PageLinkTrait;
/**
* Returns the syntax keyword (e.g., 'files', 'directory', 'images').
* Used for pattern matching and plugin registration.
@@ -209,16 +210,12 @@ abstract class syntax_plugin_luxtools_abstract extends SyntaxPlugin
protected function getPathInfoSafe(string $basePath, \Doku_Renderer $renderer)
{
try {
- $pathConfig = (string)$this->getConf('paths');
$blobsRoot = $this->resolveBlobsRoot();
if ($blobsRoot === '' && $this->isBlobsPath($basePath)) {
$this->renderPageNotLinked($renderer);
return false;
}
- if ($blobsRoot !== '') {
- $pathConfig = rtrim($pathConfig) . "\n" . $blobsRoot . "\nA> blobs";
- }
- $pathHelper = new Path($pathConfig);
+ $pathHelper = $this->createPathHelperWithBlobs($blobsRoot);
return $pathHelper->getPathInfo($basePath);
} catch (\Exception $e) {
$this->renderError($renderer, 'error_outsidejail');
@@ -226,99 +223,6 @@ abstract class syntax_plugin_luxtools_abstract extends SyntaxPlugin
}
}
- /**
- * Check if the given path uses the blobs alias.
- */
- protected function isBlobsPath(string $path): bool
- {
- $trimmed = ltrim($path, '/');
- return preg_match('/^blobs(\/|$)/', $trimmed) === 1;
- }
-
- /**
- * Render the "Page not linked" message with copy ID affordance.
- */
- protected function renderPageNotLinked(\Doku_Renderer $renderer): void
- {
- $uuid = $this->getPageUuidSafe();
- $text = (string)$this->getLang('pagelink_unlinked');
-
- if ($renderer instanceof \Doku_Renderer_xhtml) {
- $renderer->doc .= '' . hsc($text) . '';
- return;
- }
-
- $renderer->cdata('[n/a: ' . $text . ']');
- }
-
- /**
- * Read the current page UUID (if any).
- */
- protected function getPageUuidSafe(): string
- {
- global $ID;
- $pageId = is_string($ID) ? $ID : '';
- if ($pageId === '') return '';
-
- if (function_exists('cleanID')) {
- $pageId = (string)cleanID($pageId);
- }
- if ($pageId === '') return '';
-
- $depth = (int)$this->getConf('pagelink_search_depth');
- if ($depth < 0) $depth = 0;
-
- $pageLink = new PageLink((string)$this->getConf('paths'), $depth);
- $uuid = $pageLink->getPageUuid($pageId);
- return $uuid ?? '';
- }
-
- /**
- * Resolve the current page's pagelink folder for the blobs alias.
- *
- * @return string
- */
- protected function resolveBlobsRoot(): string
- {
- static $cached = [];
-
- global $ID;
- $pageId = is_string($ID) ? $ID : '';
- if ($pageId === '') return '';
-
- if (function_exists('cleanID')) {
- $pageId = (string)cleanID($pageId);
- }
- if ($pageId === '') return '';
-
- if (isset($cached[$pageId])) {
- return (string)$cached[$pageId];
- }
-
- $pathConfig = (string)$this->getConf('paths');
- $depth = (int)$this->getConf('pagelink_search_depth');
- if ($depth < 0) $depth = 0;
-
- $pageLink = new PageLink($pathConfig, $depth);
- $uuid = $pageLink->getPageUuid($pageId);
- if ($uuid === null) {
- $cached[$pageId] = '';
- return '';
- }
-
- $linkInfo = $pageLink->resolveUuid($uuid);
- $folder = $linkInfo['folder'] ?? '';
- if (!is_string($folder) || $folder === '') {
- $cached[$pageId] = '';
- return '';
- }
-
- $cached[$pageId] = $folder;
- return $folder;
- }
-
/**
* Create and configure a Crawler instance.
*
diff --git a/syntax/image.php b/syntax/image.php
index 2a960ef..d0180cf 100644
--- a/syntax/image.php
+++ b/syntax/image.php
@@ -2,7 +2,7 @@
use dokuwiki\Extension\SyntaxPlugin;
use dokuwiki\plugin\luxtools\Path;
-use dokuwiki\plugin\luxtools\PageLink;
+use dokuwiki\plugin\luxtools\PageLinkTrait;
use dokuwiki\plugin\luxtools\ThumbnailHelper;
require_once(__DIR__ . '/../autoload.php');
@@ -16,6 +16,7 @@ require_once(__DIR__ . '/../autoload.php');
*/
class syntax_plugin_luxtools_image extends SyntaxPlugin
{
+ use PageLinkTrait;
/** @inheritdoc */
public function getType()
{
@@ -139,12 +140,7 @@ class syntax_plugin_luxtools_image extends SyntaxPlugin
return true;
}
- $pathConfig = (string)$this->getConf('paths');
- if ($blobsRoot !== '') {
- $pathConfig = rtrim($pathConfig) . "\n" . $blobsRoot . "\nA> blobs";
- }
-
- $pathHelper = new Path($pathConfig);
+ $pathHelper = $this->createPathHelperWithBlobs($blobsRoot);
// Use addTrailingSlash=false since this is a file path, not a directory
$pathInfo = $pathHelper->getPathInfo($data['path'], false);
} catch (\Exception $e) {
@@ -226,96 +222,6 @@ class syntax_plugin_luxtools_image extends SyntaxPlugin
return DOKU_BASE . 'lib/plugins/luxtools/file.php?' . http_build_query($params, '', '&');
}
- /**
- * Check if the given path uses the blobs alias.
- */
- protected function isBlobsPath(string $path): bool
- {
- $trimmed = ltrim($path, '/');
- return preg_match('/^blobs(\/|$)/', $trimmed) === 1;
- }
-
- /**
- * Render the "Page not linked" message with copy ID affordance.
- */
- protected function renderPageNotLinked(\Doku_Renderer $renderer): void
- {
- $uuid = $this->getPageUuidSafe();
- $text = (string)$this->getLang('pagelink_unlinked');
-
- if ($renderer instanceof \Doku_Renderer_xhtml) {
- $renderer->doc .= '' . hsc($text) . '';
- return;
- }
-
- $renderer->cdata('[n/a: ' . $text . ']');
- }
-
- /**
- * Read the current page UUID (if any).
- */
- protected function getPageUuidSafe(): string
- {
- global $ID;
- $pageId = is_string($ID) ? $ID : '';
- if ($pageId === '') return '';
-
- if (function_exists('cleanID')) {
- $pageId = (string)cleanID($pageId);
- }
- if ($pageId === '') return '';
-
- $depth = (int)$this->getConf('pagelink_search_depth');
- if ($depth < 0) $depth = 0;
-
- $pageLink = new PageLink((string)$this->getConf('paths'), $depth);
- $uuid = $pageLink->getPageUuid($pageId);
- return $uuid ?? '';
- }
-
- /**
- * Resolve the current page's pagelink folder for the blobs alias.
- */
- protected function resolveBlobsRoot(): string
- {
- static $cached = [];
-
- global $ID;
- $pageId = is_string($ID) ? $ID : '';
- if ($pageId === '') return '';
-
- if (function_exists('cleanID')) {
- $pageId = (string)cleanID($pageId);
- }
- if ($pageId === '') return '';
-
- if (isset($cached[$pageId])) {
- return (string)$cached[$pageId];
- }
-
- $depth = (int)$this->getConf('pagelink_search_depth');
- if ($depth < 0) $depth = 0;
-
- $pageLink = new PageLink((string)$this->getConf('paths'), $depth);
- $uuid = $pageLink->getPageUuid($pageId);
- if ($uuid === null) {
- $cached[$pageId] = '';
- return '';
- }
-
- $linkInfo = $pageLink->resolveUuid($uuid);
- $folder = $linkInfo['folder'] ?? '';
- if (!is_string($folder) || $folder === '') {
- $cached[$pageId] = '';
- return '';
- }
-
- $cached[$pageId] = $folder;
- return $folder;
- }
-
/**
* Render the imagebox HTML.
*
diff --git a/syntax/open.php b/syntax/open.php
index 9212c87..900f885 100644
--- a/syntax/open.php
+++ b/syntax/open.php
@@ -1,7 +1,7 @@
getConf('paths');
- $pathConfig = rtrim($pathConfig) . "\n" . $blobsRoot . "\nA> blobs";
- $pathHelper = new Path($pathConfig);
+ $pathHelper = $this->createPathHelperWithBlobs($blobsRoot);
$resolvedPath = $path;
$isBlobsRoot = (rtrim($resolvedPath, '/') === 'blobs');
if ($isBlobsRoot) {
@@ -105,7 +104,7 @@ class syntax_plugin_luxtools_open extends SyntaxPlugin
// Map local paths back to their configured aliases before opening.
if (!preg_match('/^[a-zA-Z][a-zA-Z0-9+.-]*:/', $path)) {
try {
- $pathHelper = new Path((string)$this->getConf('paths'));
+ $pathHelper = $this->createPathHelper();
$path = $pathHelper->mapToAliasPath($path);
} catch (\Exception $e) {
// ignore mapping failures
@@ -145,81 +144,4 @@ class syntax_plugin_luxtools_open extends SyntaxPlugin
$renderer->doc .= $renderer->_formatLink($link);
return true;
}
-
- /**
- * Check if the given path uses the blobs alias.
- */
- protected function isBlobsPath(string $path): bool
- {
- $trimmed = ltrim($path, '/');
- return preg_match('/^blobs(\/|$)/', $trimmed) === 1;
- }
-
- /**
- * Resolve the current page's pagelink folder for the blobs alias.
- */
- protected function resolveBlobsRoot(): string
- {
- global $ID;
- $pageId = is_string($ID) ? $ID : '';
- if ($pageId === '') return '';
-
- if (function_exists('cleanID')) {
- $pageId = (string)cleanID($pageId);
- }
- if ($pageId === '') return '';
-
- $depth = (int)$this->getConf('pagelink_search_depth');
- if ($depth < 0) $depth = 0;
-
- $pageLink = new PageLink((string)$this->getConf('paths'), $depth);
- $uuid = $pageLink->getPageUuid($pageId);
- if ($uuid === null) return '';
-
- $linkInfo = $pageLink->resolveUuid($uuid);
- $folder = $linkInfo['folder'] ?? '';
- if (!is_string($folder) || $folder === '') return '';
-
- return $folder;
- }
-
- /**
- * Render the "Page not linked" message with copy ID affordance.
- */
- protected function renderPageNotLinked(\Doku_Renderer $renderer): void
- {
- $uuid = $this->getPageUuidSafe();
- $text = (string)$this->getLang('pagelink_unlinked');
-
- if ($renderer instanceof \Doku_Renderer_xhtml) {
- $renderer->doc .= '' . hsc($text) . '';
- return;
- }
-
- $renderer->cdata('[n/a: ' . $text . ']');
- }
-
- /**
- * Read the current page UUID (if any).
- */
- protected function getPageUuidSafe(): string
- {
- global $ID;
- $pageId = is_string($ID) ? $ID : '';
- if ($pageId === '') return '';
-
- if (function_exists('cleanID')) {
- $pageId = (string)cleanID($pageId);
- }
- if ($pageId === '') return '';
-
- $depth = (int)$this->getConf('pagelink_search_depth');
- if ($depth < 0) $depth = 0;
-
- $pageLink = new PageLink((string)$this->getConf('paths'), $depth);
- $uuid = $pageLink->getPageUuid($pageId);
- return $uuid ?? '';
- }
}