diff --git a/_test/SyntaxTest.php b/_test/SyntaxTest.php
index 20d757b..1da276c 100644
--- a/_test/SyntaxTest.php
+++ b/_test/SyntaxTest.php
@@ -245,9 +245,9 @@ class plugin_luxtools_test extends DokuWikiTest
}
/**
- * This function checks that the open syntax renders an inline button.
+ * This function checks that the open syntax renders an inline link.
*/
- public function test_open_button()
+ public function test_open_link()
{
$instructions = p_get_instructions('{{open>/tmp/somewhere|Open here}}');
$xhtml = p_render('xhtml', $instructions, $info);
@@ -256,7 +256,7 @@ class plugin_luxtools_test extends DokuWikiTest
$doc->html($xhtml);
$structure = [
- 'button.luxtools-open' => 1,
+ 'a.luxtools-open' => 1,
];
$this->structureCheck($doc, $structure);
diff --git a/images/folder.svg b/images/folder.svg
new file mode 100644
index 0000000..7e38c50
--- /dev/null
+++ b/images/folder.svg
@@ -0,0 +1,49 @@
+
+
diff --git a/images/open-folder.svg b/images/open-folder.svg
new file mode 100644
index 0000000..c867f84
--- /dev/null
+++ b/images/open-folder.svg
@@ -0,0 +1,43 @@
+
+
diff --git a/lang/en/settings.php b/lang/en/settings.php
index 35f8575..a2ddd79 100644
--- a/lang/en/settings.php
+++ b/lang/en/settings.php
@@ -9,4 +9,4 @@ $lang['thumb_placeholder'] = 'MediaManager ID for the gallery thumbnail placehol
$lang['gallery_thumb_scale'] = 'Gallery thumbnail scale factor. Use 2 for sharper thumbnails on HiDPI screens (still displayed as 150×150).';
-$lang['open_service_url'] = 'Local client service URL for the {{open>...}} button (e.g. http://127.0.0.1:8765).';
+$lang['open_service_url'] = 'Local client service URL for the {{open>...}} link (e.g. http://127.0.0.1:8765).';
diff --git a/script.js b/script.js
index 5ed346b..acc5e59 100644
--- a/script.js
+++ b/script.js
@@ -119,9 +119,23 @@
return path;
}
+ function findOpenElement(target) {
+ var el = target;
+ while (el && el !== document) {
+ if (el.classList && el.classList.contains('luxtools-open')) return el;
+ el = el.parentNode;
+ }
+ return null;
+ }
+
function onClick(event) {
- var el = event.target;
- if (!el || !el.classList || !el.classList.contains('luxtools-open')) return;
+ var el = findOpenElement(event.target);
+ if (!el) return;
+
+ // {{open>...}} renders as a link; avoid jumping to '#'.
+ if (el.tagName && el.tagName.toLowerCase() === 'a') {
+ event.preventDefault();
+ }
var raw = el.getAttribute('data-path') || '';
if (!raw) return;
diff --git a/style.css b/style.css
index 9f148d5..637bfd8 100644
--- a/style.css
+++ b/style.css
@@ -21,13 +21,25 @@ div.luxtools-plugin table thead tr.luxtools-openlocation-row:hover td {
/* Ensure directories use a dedicated folder icon.
* DokuWiki's icon CSS is generated primarily for file extensions; a custom
* mf_folder class may otherwise fall back to the generic file icon.
- *
- * The relative URL is resolved against the plugin directory by DokuWiki's CSS
- * aggregator, resulting in lib/images/fileicons/svg/folder.svg.
*/
div.luxtools-plugin a.media.mediafile.mf_folder,
div.luxtools-plugin a.mediafile.mf_folder {
- background-image: url(../../images/fileicons/svg/folder.svg) !important;
+ background-image: url(images/folder.svg) !important;
+}
+
+/* DokuWiki templates often style .media links with higher specificity.
+ * Ensure our custom color always wins.
+ */
+div.luxtools-plugin a.luxtools-open,
+div.luxtools-plugin a.luxtools-open:visited,
+a.luxtools-open,
+a.luxtools-open:visited {
+ color: #b57d35 !important;
+}
+
+/* Standalone {{open>...}} links are not wrapped in div.luxtools-plugin. */
+a.luxtools-open.media.mediafile.mf_folder {
+ background-image: url(images/open-folder.svg) !important;
}
/* Muted empty-state message when a listing has no results. */
diff --git a/syntax/open.php b/syntax/open.php
index 46b3555..5d82051 100644
--- a/syntax/open.php
+++ b/syntax/open.php
@@ -5,7 +5,7 @@ use dokuwiki\Extension\SyntaxPlugin;
/**
* luxtools Plugin: Open local path syntax.
*
- * Renders an inline button. Clicking it triggers client-side JS that attempts
+ * Renders an inline link. Clicking it triggers client-side JS that attempts
* to open the configured path in the default file manager (best-effort).
*/
class syntax_plugin_luxtools_open extends SyntaxPlugin
@@ -74,14 +74,36 @@ class syntax_plugin_luxtools_open extends SyntaxPlugin
}
$serviceUrl = trim((string)$this->getConf('open_service_url'));
+ $serviceToken = trim((string)$this->getConf('open_service_token'));
- $attrs = ' type="button" class="luxtools-open"'
- . ' data-path="' . hsc($path) . '"';
- if ($serviceUrl !== '') {
- $attrs .= ' data-service-url="' . hsc($serviceUrl) . '"';
+ if (!($renderer instanceof \Doku_Renderer_xhtml)) {
+ $renderer->cdata($caption);
+ return true;
}
- $renderer->doc .= '';
+ global $conf;
+ /** @var \Doku_Renderer_xhtml $renderer */
+
+ // Render like a normal DokuWiki link with an icon in front.
+ // Use the same folder icon class as directory listings.
+ $link = [
+ 'target' => $conf['target']['extern'],
+ 'style' => '',
+ 'pre' => '',
+ 'suf' => '',
+ 'name' => $caption,
+ 'url' => '#',
+ 'title' => $renderer->_xmlEntities($path),
+ 'more' => '',
+ 'class' => 'luxtools-open media mediafile mf_folder',
+ ];
+
+ $link['more'] .= ' data-path="' . hsc($path) . '"';
+ if (!empty($conf['relnofollow'])) $link['more'] .= ' rel="nofollow"';
+ if ($serviceUrl !== '') $link['more'] .= ' data-service-url="' . hsc($serviceUrl) . '"';
+ if ($serviceToken !== '') $link['more'] .= ' data-service-token="' . hsc($serviceToken) . '"';
+
+ $renderer->doc .= $renderer->_formatLink($link);
return true;
}
}