[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
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.