[TikiWiki-commits] [Git][tikiwiki/tiki][tiki-fix-tracker-url-wikisyntax] [ENH] trackerFieldUrl: implement wiki syntax validation and feedback in URL input
"Sammy Ndabo \(@ndabosam084\) via TikiWiki-cvs" <[email protected]>
| Newsgroups | gmane.comp.cms.tiki.cvs |
|---|---|
| Message-ID | <698d923fefa20_3b1852e07989@gitlab-sidekiq-low-urgency-cpu-bound-v2-7b7ccc47b4-nv22h.mail> |
Sammy Ndabo pushed to branch tiki-fix-tracker-url-wikisyntax at Tiki Wiki CMS Groupware / Tiki
Commits:
45a32150 by Sammy Ndabo at 2026-02-12T10:41:20+02:00
[ENH] trackerFieldUrl: implement wiki syntax validation and feedback in URL input
- - - - -
4 changed files:
- lib/core/Tracker/Field/Url.php
- lib/jquery_tiki/tiki-trackers.js
- lib/test/Core/Tracker/Field/UrlTest.php
- templates/trackerinput/url.tpl
Changes:
=====================================
lib/core/Tracker/Field/Url.php
=====================================
@@ -182,7 +182,7 @@ class Tracker_Field_Url extends \Tracker\Field\AbstractItemField implements \Tra
{
$value = trim((string) $this->getConfiguration('value'));
$templateData = [
- 'wikiSyntaxInfo' => tr('You can also use complete wiki-link syntax: ((PageName)) or [url|label].'),
+ 'wikiSyntaxInfo' => tr('You can also use complete wiki-link syntax: ((PageName)) or [url|text].'),
'wikiSyntaxWarning' => '',
];
=====================================
lib/jquery_tiki/tiki-trackers.js
=====================================
@@ -670,6 +670,106 @@
});
// Global tracker field functions
+ function updateTrackerFormSubmitState($input) {
+ const $form = $input.closest('form');
+ if (! $form.length) {
+ return;
+ }
+
+ const hasInvalidUrlSyntax = $form.find('input[data-url-wiki-syntax="1"]').filter(function () {
+ return !! $(this).data('urlWikiSyntaxInvalid');
+ }).length > 0;
+
+ $form.find('input[type="submit"], button[type="submit"], .item-submit-btn').prop('disabled', hasInvalidUrlSyntax);
+ $form.closest('.modal').find('.modal-footer .auto-btn').prop('disabled', hasInvalidUrlSyntax);
+ }
+
+ function validateUrlWikiSyntax($input) {
+ const rawValue = ($input.val() || '');
+ const value = rawValue.trim();
+
+ const feedbackId = $input.data('url-wiki-syntax-feedback-id');
+ const $feedback = feedbackId ? $('#' + feedbackId) : $();
+
+ if (! $feedback.length) {
+ return;
+ }
+
+ const defaultInfo = $feedback.data('default-info') || '';
+
+ if (value === '') {
+ $feedback
+ .removeClass('text-warning')
+ .addClass('text-muted')
+ .text(defaultInfo);
+ $input.data('urlWikiSyntaxInvalid', false);
+ updateTrackerFormSubmitState($input);
+ return;
+ }
+
+ const startsDouble = value.startsWith('((');
+ const endsDouble = value.endsWith('))');
+ const startsBracket = value.startsWith('[');
+ const endsBracket = value.endsWith(']');
+ const startsSingleParenOnly = value.startsWith('(') && ! startsDouble;
+ const endsSingleParenOnly = value.endsWith(')') && ! endsDouble;
+
+ let message = '';
+
+ if (startsSingleParenOnly || endsSingleParenOnly) {
+ message = tr('Invalid wiki link syntax. Use ((PageName)) for wiki pages.');
+ } else if ((startsDouble && ! endsDouble) || (! startsDouble && endsDouble) || (startsBracket && ! endsBracket) || (! startsBracket && endsBracket)) {
+ message = tr('Invalid wiki link syntax. Use complete wrappers like ((PageName)) or [url|text].');
+ } else if (startsBracket && endsBracket) {
+ const inside = value.slice(1, -1).trim();
+ if (! inside) {
+ message = tr('Invalid wiki link syntax. [url|text] cannot be empty.');
+ } else {
+ const target = inside.split('|', 1)[0].trim();
+ if (! target) {
+ message = tr('Invalid wiki link syntax. Missing link target before "|".');
+ }
+ }
+ } else if (startsDouble && endsDouble) {
+ const inside = value.slice(2, -2).trim();
+ if (! inside) {
+ message = tr('Invalid wiki link syntax. ((PageName)) cannot be empty.');
+ }
+ }
+
+ if (message) {
+ $feedback
+ .removeClass('text-muted')
+ .addClass('text-warning')
+ .text(message);
+ $input.data('urlWikiSyntaxInvalid', true);
+ } else {
+ $feedback
+ .removeClass('text-warning')
+ .addClass('text-muted')
+ .text(defaultInfo);
+ $input.data('urlWikiSyntaxInvalid', false);
+ }
+
+ updateTrackerFormSubmitState($input);
+ }
+
+ $(document).on('input blur', 'input[data-url-wiki-syntax="1"]', function () {
+ validateUrlWikiSyntax($(this));
+ });
+
+ $(document).on('tiki.modal.redraw', '.modal.fade', function () {
+ $(this).find('input[data-url-wiki-syntax="1"]').each(function () {
+ validateUrlWikiSyntax($(this));
+ });
+ });
+
+ $(function () {
+ $('input[data-url-wiki-syntax="1"]').each(function () {
+ validateUrlWikiSyntax($(this));
+ });
+ });
+
$(document).on('mouseenter', '.currency_output', function(){
$('.'+$(this).attr('id')).removeClass('d-none');
});
=====================================
lib/test/Core/Tracker/Field/UrlTest.php
=====================================
@@ -39,6 +39,7 @@ class TrackerFieldUrlTest extends \PHPUnit\Framework\TestCase
{
return [
'plain url' => ['https://example.org'],
+ 'single parenthesis syntax is unsupported' => ['(PageName)'],
'broken wikilink prefix only' => ['((PageName'],
'broken bracket syntax suffix only' => ['https://example.org|Example]'],
'escaped bracket syntax is out of scope' => ['\[https://example.org|Example]'],
@@ -53,4 +54,5 @@ class TrackerFieldUrlTest extends \PHPUnit\Framework\TestCase
return (bool) $method->invoke(null, $value);
}
+
}
=====================================
templates/trackerinput/url.tpl
=====================================
@@ -1,6 +1,8 @@
<div{if !empty($field.options_map.labelasplaceholder)} class="input-group"{/if}>
<input type="text" class="form-control{if !empty($field.options_map.labelasplaceholder)} labelasplaceholder{/if}"
name="{$field.ins_id}" id="{$field.ins_id}" value="{$field.value|escape}" size="60"
+ data-url-wiki-syntax="1"
+ data-url-wiki-syntax-feedback-id="{$field.ins_id}_wikiSyntaxLive"
{if !empty($field.options_map.labelasplaceholder)}placeholder="{$field.name}"{/if}
>
{if $field.options_map.labelasplaceholder and $field.isMandatory eq 'y'}
@@ -9,9 +11,7 @@
</span>
{/if}
</div>
-{if !empty($wikiSyntaxInfo)}
- <div class="form-text text-muted">{$wikiSyntaxInfo|escape}</div>
-{/if}
-{if !empty($wikiSyntaxWarning)}
- <div class="form-text text-warning">{$wikiSyntaxWarning|escape}</div>
-{/if}
+<div id="{$field.ins_id}_wikiSyntaxLive"
+ class="form-text text-muted js-url-wiki-syntax-feedback"
+ data-default-info="{$data.wikiSyntaxInfo|escape:'htmlattr'}"
+>{if !empty($data.wikiSyntaxWarning)}{$data.wikiSyntaxWarning|escape}{else}{$data.wikiSyntaxInfo|escape}{/if}</div>
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/45a321507f4ceab7a432435f67cfbc123f23a821
--
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/45a321507f4ceab7a432435f67cfbc123f23a821
You're receiving this email because of your account on gitlab.com.
_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs