[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 <698d948897773_3b2e3e1c45764a@gitlab-sidekiq-low-urgency-cpu-bound-v2-7b7ccc47b4-266xk.mail>

Sammy Ndabo pushed to branch tiki-fix-tracker-url-wikisyntax at Tiki Wiki CMS Groupware / Tiki


Commits:
f9388840 by Sammy Ndabo at 2026-02-12T10:51:03+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]'],


=====================================
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/f9388840bd13ff0c4725c69f8961f4f268af5f70

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/f9388840bd13ff0c4725c69f8961f4f268af5f70
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.