Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
23 posts Page 2 of 3
Tomarnst wrote: mmm.... that should not be the case also those hidden ones should be clear for someone who doesn't read the source files.

I must correct myself then. In reality, CouchCMS doesn't have anything hidden - only undocumented :)
Snippets, on the contrary, have samples of usage, detailed explanation and a list of all parameters used in code. In fact, anyone can read couch code and see what is going on there without any php involved.

My Documentation, Addons, Functions.
Join COUCH:TALK telegram channel
Seeing @trendoman's interest in using embeds behave as functions, I have created something that might make things a tad easier.

The current version of Couch from GitHub (https://github.com/CouchCMS/CouchCMS) now offers two new tags - <cms:func /> and <cms:call />.

Anyone willing to try out how the tags work, assuming you have the current GitHub version installed, try placing the following in any of your test template -

1.
Code: Select all
    <cms:func 'makecoffee' type='cappuccino' >
        Making a cup of <cms:show type />.<br />
    </cms:func>

    <cms:call 'makecoffee' />
    <cms:call 'makecoffee' '' />
    <cms:call 'makecoffee' 'espresso' />

Output:
Making a cup of cappuccino.
Making a cup of .
Making a cup of espresso.

As you can see, the <cms:func> defines a function named 'makecoffee' which accepts an optional single parameter named 'type'.
The <cms:call /> statements that follow show how the function can be invoked. Please note how the default value of 'type' is used when the function is called without any parameter.

2.
Code: Select all
    <cms:func 'makecoffee2' type='cappuccino' size='medium'>
        Making a <cms:show size /> cup of <cms:show type />.<br />
    </cms:func>

    <cms:call 'makecoffee2' />
    <cms:call 'makecoffee2' 'espresso' 'large' />
    <cms:call 'makecoffee2' size='small' type='espresso' />

Output:
Making a medium cup of cappuccino.
Making a large cup of espresso.
Making a small cup of espresso.

The next example above defines another function (named 'makecoffee2') that takes two parameters - 'type' and 'size'.
Please note the third <cms:call> statement above - it shows how we can pass parameters to the function in any order by explicitly using their names. If names are not used with the parameters then they have to be passed in strictly the same order as that defined by the function being called, as shown by the second <cms:call /> (i.e. first 'type' and then 'size').

3.
Code: Select all
    <cms:func 'recursion' count='0'>
        <cms:if count lt '20'>
            count: <cms:show count /><br>
            <cms:call 'recursion' "<cms:add count '1' />" />
        </cms:if>
    </cms:func>

    <cms:call 'recursion' />

Output:
count: 0
count: 1
count: 2
count: 3
count: 4
count: 5
..
..


Hopefully the simple examples above should be sufficient to illustrate how we can use <cms:func /> for creating resusable chunks of code.

I'd like to stress one point about <cms:func /> here - every parameter we define for it needs to have a default value (it may be blank but it has to be present) e.g. the following is incorrect
Code: Select all
    <cms:func 'makecoffee' type >

Following is the right syntax if the parameter has no visible default value -

Code: Select all
    <cms:func 'makecoffee' type='' >

Finally, you might find it more manageable to put all functions (or groups of related functions) as snippets e.g. I could create a snippet named 'funcs.html' as follows (the cms:hide allows me to freely use text as comments) -

Code: Select all
    <cms:hide>
        <!-- makes coffee (what else did you expect?) -->
        <cms:func 'makecoffee' type='cappuccino' >
            Making a cup of <cms:show type />.<br />
        </cms:func>

        <!-- make coffee version 2 -->
        <cms:func 'makecoffee2' type='cappuccino' size='medium'>
            Making a <cms:show size /> cup of <cms:show type />.<br />
        </cms:func>

        <!-- look Ma! I can recurse! -->
        <cms:func 'recursion' count='0'>
            <cms:if count lt '20'>
                count: <cms:show count /><br>
                <cms:call 'recursion' "<cms:add count '1' />" />
            </cms:if>
        </cms:func>
    </cms:hide>

And now my test template could embed the snippet somewhere at its beginning -

Code: Select all
    <cms:embed 'funcs.html' />

and then call the functions as usual -

Code: Select all
    <cms:call 'makecoffee' />
    <cms:call 'makecoffee' '' />
    <cms:call 'makecoffee' 'espresso' />

    <cms:call 'makecoffee2' />
    <cms:call 'makecoffee2' 'espresso' 'large' />
    <cms:call 'makecoffee2' size='small' type='espresso' />

    <cms:call 'recursion' />

Hope this helps.
Thanks, @KK.

Update: Addon Tweakus Dilectus » "Func-on-demand" has been published intended to autoload funcs placed in snippets.

8. A function that returns a remote page via server's cURL extension:

Update: Relocated the func to repository Cms-Fu » fetch-url

Code: Select all
<cms:call 'remote_url' url="https://www.couchcms.com/" />


Example 1. Output some remote url's content:
Code: Select all
<cms:abort>
    <cms:call 'remote_url' url="https://www.couchcms.com/" />
</cms:abort>


Example 2. Show latest 5 commits for CouchCMS repo on GitHub:
Code: Select all
<cms:capture into='commits' is_json='1' >
    <cms:call 'remote_url' url='https://api.github.com/repos/CouchCMS/CouchCMS/commits?per_page=5' />
</cms:capture>

<cms:each commits as='entry' startcount='1'>
    <cms:html_encode>
        <cms:date date=entry.commit.committer.date format='j M' />: <cms:show entry.commit.message />
    </cms:html_encode>
    <br/>
</cms:each>


Output as of today:
20 Mar: Fix json in advanced relations
20 Mar: Add 'adjust' param to cms:pages (for non-uniform pagination needs)
19 Mar: Add tag <cms:func_exists>
17 Mar: Add setting repeatable-regions using JSON in DataBound Forms
16 Mar: Add tags <cms:func> and <cms:call>

My Documentation, Addons, Functions.
Join COUCH:TALK telegram channel
Nice :)
9. A function for search by page titles with support of patterns and wildcards.
Even 1-symbol is enough :)

Code: Select all
// 1. Builds an sql query to search for pages by title.
// 2. Returns either query results or query itself (return_sql = '1')       
//
// Samples:
//
//
// b (exactly). Such cases should be handled by parameter strictly='1' instead!
// <cms:call 'search_by_title' masterpage='data.php, index.php' key='b' />
//
// b* (starts with 'b')
// <cms:call 'search_by_title' masterpage='data.php, index.php' key='b*' />
//
// *b (ends with 'b')
// <cms:call 'search_by_title' masterpage='data.php, index.php' key='*b' />
//
// *b* (has 'b' somewhere)
// <cms:call 'search_by_title' masterpage='data.php, index.php' key='*b*' />
//
// b**** (5-letter word, starting with 'b')
// <cms:call 'search_by_title' masterpage='data.php, index.php' key='b****' />   
//
// ***b (4-letter word ending with 'b')
// <cms:call 'search_by_title' masterpage='data.php, index.php' key='***b' />   


Sample use:
Code: Select all
<h1>TESTS:</h1>
<p>Try on template(s) with a lot of pages.</p>       
       
<cms:nl2br>
       
            // b* (starts with 'b')
   
</cms:nl2br>
<cms:call 'search_by_title' key='b*' /><hr/>

<cms:nl2br>
       
            // *b (ends with 'b')
   
</cms:nl2br>
<cms:call 'search_by_title' key='*b' /><hr/>

<cms:nl2br>
       
            // *b* (has 'b' anywhere)
   
</cms:nl2br>
<cms:call 'search_by_title' key='*b*' /><hr/>

<cms:nl2br>
       
            // b**** (5-letter word, starting with 'b')
   
</cms:nl2br>
<cms:call 'search_by_title' key='b****' /><hr/>

<cms:nl2br>
       
            // ***b (4-letter word ending with 'b')
   
</cms:nl2br>
<cms:call 'search_by_title' key='***b' /><hr/>

<cms:nl2br>
       
            // b (exactly). Such cases are better (faster) handled by adding parameter: strictly='1'
   
</cms:nl2br>
<cms:call 'search_by_title' key='b' /><hr/>


Regards

My Documentation, Addons, Functions.
Join COUCH:TALK telegram channel
11. A function encodeURIComponent that should work as in Javascript

Code: Select all
<cms:func 'encodeURIComponent' str=''><cms:ignore>
   
        // A bit of JS in PHP
        // Sample: <cms:call 'encodeURIComponent' str=nonce />

    </cms:ignore>
    <cms:php>
        global $CTX;
        $revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')');
        echo strtr(rawurlencode( $CTX->get('str') ), $revert);
    </cms:php>
</cms:func>

My Documentation, Addons, Functions.
Join COUCH:TALK telegram channel
12. A function to convert bytes to human-readable units

Code: Select all
<cms:func 'bytes2human' size=''><cms:ignore>
    /**
    *   Converts '1024' to '1 kb'.
    *   Converts '12345678' to '11.77 mb'.
    *   Converts bytes to human-readable units (kb, mb etc..)
    *
    *   @example <cms:call 'bytes2human' size=size />
    *   @example <cms:call 'bytes2human' size='12345678' />
    *   @author Anton aka Trendoman &lt;tony.smirnov@gmail.com&gt;
    *   @date   01.05.2018
    *   @last   24.02.2020
    */
    </cms:ignore>
    <cms:php>
        global $CTX;
        $size = trim($CTX->get('size'));
        $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
        if( $size == 0 ) return '0 b';
        if( $size != '' ) return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
    </cms:php>
</cms:func>

My Documentation, Addons, Functions.
Join COUCH:TALK telegram channel
Extra tip: Remove any possible spaces (trim) around the output of cms:call automatically (code added to kfunctions.php)

Code: Select all
// Trim spaces in udf calls
$FUNCS->add_event_listener( 'alter_tag_call_execute', 'trim_spaces_call');
function trim_spaces_call( $tag_name, $params, $node, &$html ){
    global $TAGS;
    $html = trim($TAGS->call( $params, $node ));
    return 1;
}

My Documentation, Addons, Functions.
Join COUCH:TALK telegram channel
13. A function to delete a single cached file on demand.

Possible use-case: a cron-job calls this function to delete cache of some page on website. Useful for blogs with new content's publish_date set in future. Once that future date becomes present, blog posts should become available for visitors. Regenerating cache of list-view via regular cron job is a way to go.

Code: Select all
// This function expects K_USE_CACHE set to 1 in config.php and an optional parameter 'link'.
// Then it proceeds to search-delete that cached file from /couch/cache
//
// Sample:
// <cms:call 'delete_existing_cached_file' />

My Documentation, Addons, Functions.
Join COUCH:TALK telegram channel
Getting some random chars:

Code: Select all
// Returns random char from regular non-UTF8 latin set
<cms:call 'random_char'  />

// Returns '+' or '-'
<cms:call 'random_sign' />

// Returns a single digit from '0' to '9'
<cms:call 'random_digit' />

My Documentation, Addons, Functions.
Join COUCH:TALK telegram channel
23 posts Page 2 of 3