Render open-location syntax as link
Some checks failed
DokuWiki Default Tasks / all (push) Has been cancelled
Some checks failed
DokuWiki Default Tasks / all (push) Has been cancelled
This commit is contained in:
@@ -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}}');
|
$instructions = p_get_instructions('{{open>/tmp/somewhere|Open here}}');
|
||||||
$xhtml = p_render('xhtml', $instructions, $info);
|
$xhtml = p_render('xhtml', $instructions, $info);
|
||||||
@@ -256,7 +256,7 @@ class plugin_luxtools_test extends DokuWikiTest
|
|||||||
$doc->html($xhtml);
|
$doc->html($xhtml);
|
||||||
|
|
||||||
$structure = [
|
$structure = [
|
||||||
'button.luxtools-open' => 1,
|
'a.luxtools-open' => 1,
|
||||||
];
|
];
|
||||||
$this->structureCheck($doc, $structure);
|
$this->structureCheck($doc, $structure);
|
||||||
|
|
||||||
|
|||||||
49
images/folder.svg
Normal file
49
images/folder.svg
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
version="1.1"
|
||||||
|
id="svg3"
|
||||||
|
sodipodi:docname="folder.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs3" /><sodipodi:namedview
|
||||||
|
id="namedview3"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="5.7134228"
|
||||||
|
inkscape:cx="66.860097"
|
||||||
|
inkscape:cy="56.008458"
|
||||||
|
inkscape:window-width="1633"
|
||||||
|
inkscape:window-height="1059"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg3" /><style
|
||||||
|
id="style1">.st1{fill:#a87d45}</style><path
|
||||||
|
fill="#fff"
|
||||||
|
d="M0 0h100v100H0z"
|
||||||
|
id="path1" /><path
|
||||||
|
class="st1"
|
||||||
|
d="M100 100H0V0h100v100zM9.7 90h80.7V10H9.7"
|
||||||
|
id="path2" /><path
|
||||||
|
d="m 75.489689,40.94749 v -5.60846 c 0,-1.548724 -1.255453,-2.804239 -2.80423,-2.804239 H 44.643148 L 41.838918,26.92633 H 27.817766 l -2.212116,4.424267 c -0.389393,0.77876 -0.592114,1.637504 -0.592114,2.508186 v 7.088707"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
id="path1-3"
|
||||||
|
style="fill:#a87d45;stroke-width:2.80423;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /><path
|
||||||
|
d="m 27.574388,71.794032 h 45.354476 c 1.450348,0 2.661499,-1.105996 2.792732,-2.550454 L 78.016021,44.005505 C 78.165205,42.363397 76.872176,40.94749 75.223289,40.94749 H 25.280016 c -1.648967,0 -2.941996,1.415907 -2.792706,3.058015 l 2.294372,25.238073 c 0.131321,1.444458 1.342358,2.550454 2.792706,2.550454 z"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
id="path2-6"
|
||||||
|
style="fill:#a87d45;stroke-width:2.804;fill-opacity:1;stroke-dasharray:none;stroke:#ffffff;stroke-opacity:1" /></svg>
|
||||||
|
After Width: | Height: | Size: 2.1 KiB |
43
images/open-folder.svg
Normal file
43
images/open-folder.svg
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
version="1.1"
|
||||||
|
id="svg3"
|
||||||
|
sodipodi:docname="open-folder.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||||
|
id="defs3" /><sodipodi:namedview
|
||||||
|
id="namedview3"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:zoom="5.7134228"
|
||||||
|
inkscape:cx="67.210149"
|
||||||
|
inkscape:cy="56.183484"
|
||||||
|
inkscape:window-width="1633"
|
||||||
|
inkscape:window-height="1059"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg3" /><style
|
||||||
|
id="style1">.st1{fill:#a87d45}</style><path
|
||||||
|
d="m 85.019893,39.020089 v -7.70915 c 0,-2.12881 -1.725693,-3.854588 -3.854577,-3.854588 H 42.619548 l -3.854576,-7.70915 H 19.492093 l -3.04068,6.081408 c -0.535243,1.07045 -0.813896,2.250843 -0.813896,3.447646 v 9.743834"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
id="path1-3"
|
||||||
|
style="fill:#ebc8ab;fill-opacity:0;stroke:#888888;stroke-width:8;stroke-opacity:1;stroke-dasharray:none" /><path
|
||||||
|
d="m 19.157556,81.420435 h 62.342335 c 1.993587,0 3.658383,-1.520255 3.838771,-3.505746 L 88.492481,43.223508 C 88.697542,40.966336 86.9202,39.020089 84.65371,39.020089 h -68.6499 c -2.266601,0 -4.043943,1.946247 -3.838736,4.203419 l 3.153747,34.691181 c 0.180508,1.985491 1.845149,3.505746 3.838735,3.505746 z"
|
||||||
|
stroke="#000000"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
id="path2-6"
|
||||||
|
style="fill:#ebc8ab;fill-opacity:0;stroke:#888888;stroke-width:8;stroke-dasharray:none;stroke-opacity:1" /></svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -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['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).';
|
||||||
|
|||||||
18
script.js
18
script.js
@@ -119,9 +119,23 @@
|
|||||||
return path;
|
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) {
|
function onClick(event) {
|
||||||
var el = event.target;
|
var el = findOpenElement(event.target);
|
||||||
if (!el || !el.classList || !el.classList.contains('luxtools-open')) return;
|
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') || '';
|
var raw = el.getAttribute('data-path') || '';
|
||||||
if (!raw) return;
|
if (!raw) return;
|
||||||
|
|||||||
20
style.css
20
style.css
@@ -21,13 +21,25 @@ div.luxtools-plugin table thead tr.luxtools-openlocation-row:hover td {
|
|||||||
/* Ensure directories use a dedicated folder icon.
|
/* Ensure directories use a dedicated folder icon.
|
||||||
* DokuWiki's icon CSS is generated primarily for file extensions; a custom
|
* DokuWiki's icon CSS is generated primarily for file extensions; a custom
|
||||||
* mf_folder class may otherwise fall back to the generic file icon.
|
* 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.media.mediafile.mf_folder,
|
||||||
div.luxtools-plugin a.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. */
|
/* Muted empty-state message when a listing has no results. */
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use dokuwiki\Extension\SyntaxPlugin;
|
|||||||
/**
|
/**
|
||||||
* luxtools Plugin: Open local path syntax.
|
* 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).
|
* to open the configured path in the default file manager (best-effort).
|
||||||
*/
|
*/
|
||||||
class syntax_plugin_luxtools_open extends SyntaxPlugin
|
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'));
|
$serviceUrl = trim((string)$this->getConf('open_service_url'));
|
||||||
|
$serviceToken = trim((string)$this->getConf('open_service_token'));
|
||||||
|
|
||||||
$attrs = ' type="button" class="luxtools-open"'
|
if (!($renderer instanceof \Doku_Renderer_xhtml)) {
|
||||||
. ' data-path="' . hsc($path) . '"';
|
$renderer->cdata($caption);
|
||||||
if ($serviceUrl !== '') {
|
return true;
|
||||||
$attrs .= ' data-service-url="' . hsc($serviceUrl) . '"';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$renderer->doc .= '<button' . $attrs . '>' . hsc($caption) . '</button>';
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user