Hi,
There should be more information about reusable code, I guess.
In hopes this topic expands daily usable skills towards more comfortable re-use of shared code.
Functions are good, because we can send different data there and receive results without rewriting / adapting code each time. Variable names and content, in practice, are different but operations are the same.
UPDATE: See KK's release of functions to CouchCMS and new tutorial
UPDATE 2: Repository CmsFu » functions is now the place to download funcs.
UPDATE 3: Addon Tweakus Dilectus » "Func-on-demand" has been published intended to autoload funcs placed in snippets.
UPDATE 4: A proper dedicated documentation page at Midware Concepts » Reusable Functions has been published.
Complete snippet-as-a-function code in attachment:
A great deal of calling functions is abstraction of its variables - somefunction('1','2') will perform the same as some_function( my_var1, some_other_var55 ) - no matter how the variables are named, it doesn't make any difference.
Sample for today is very simple, with didactic purpose: sum of numbers (1) and averaging a set of people's ages (2). Both operations share the same "cms:add" tag.
Let's take a regular code that sums values. It already has CouchCMS's tags (functions) that take data arguments and return values (cms:each, cms:add, cms:show). The problem: to apply the same logic to anything else besides summing numbers - as we need to average ages - we would have to copy-paste this code or write it again and change variables. It is not comfortable if code is more than 5 lines.
Let's build our own function , based only on the tags CouchCMS provides with the help of snippets.
Snippets are great reusable pieces of code, but today I am going to show again how make them truly independent, very much like functions.
(1)
Create a snippet 'add-many.html'. I will put it to some sub-folder that I prefer to call 'functions', so the call would look like:
Snippet's initial content consists of the core of the operation - summing. Our future function will accept any string of comma-separated numbers and return result.
(2)
Let's see our real-world tasks, that we need to perform with
Incoming data has different names: numbersToSum, peopleAgeData, Outgoing: totalSum, sumOfAges, peopleCount.
(3)
With everything prepared, we must make sure our function accepts various names as incoming data and returns variable that we expect. In other words, complete independence of this snippet-function is required. Following approach helps us:
So, let's rewrite front-end code with the help of arguments-variables set as incoming and outgoing data. We will have in this example 3 parameters that will be used by function: data, result, count (optional). Our snippet should read numbers from a variable which name is stored in parameter 'data', put results in a variable which name is stored in parameter 'result' and same with 'count'.
Final code on the front-end (aka function calls)
(4)
Let's instruct the code in the snippet to use passed arguments and operate upon them. (If you place cms:dump inside the snippet to debug, you will see how these arguments are present there). Final look of the snippet:
See, how easier it will be to maintain your code and reuse parts of it in truly awesome independent manner. Much less code required in templates to do stuff and snippet can be reused independently (yes, you can save the code for future and maybe even share your functions as well )
Hopefully, this brilliant explanation positively influences your day-to-day coding.
Regards
Anton
There should be more information about reusable code, I guess.
In hopes this topic expands daily usable skills towards more comfortable re-use of shared code.
Functions are good, because we can send different data there and receive results without rewriting / adapting code each time. Variable names and content, in practice, are different but operations are the same.
UPDATE: See KK's release of functions to CouchCMS and new tutorial
UPDATE 2: Repository CmsFu » functions is now the place to download funcs.
UPDATE 3: Addon Tweakus Dilectus » "Func-on-demand" has been published intended to autoload funcs placed in snippets.
UPDATE 4: A proper dedicated documentation page at Midware Concepts » Reusable Functions has been published.
Complete snippet-as-a-function code in attachment:
- Code: Select all
// General and important concept of function is
some_function( ->incoming data1, ->incoming data2, ... etc){
... operation over incoming datas
outgoing result->
}
A great deal of calling functions is abstraction of its variables - somefunction('1','2') will perform the same as some_function( my_var1, some_other_var55 ) - no matter how the variables are named, it doesn't make any difference.
Sample for today is very simple, with didactic purpose: sum of numbers (1) and averaging a set of people's ages (2). Both operations share the same "cms:add" tag.
Let's take a regular code that sums values. It already has CouchCMS's tags (functions) that take data arguments and return values (cms:each, cms:add, cms:show). The problem: to apply the same logic to anything else besides summing numbers - as we need to average ages - we would have to copy-paste this code or write it again and change variables. It is not comfortable if code is more than 5 lines.
- Code: Select all
<cms:set numbersToSum='10,20,30,40' />
<cms:set result = '0' scope='global'/>
<cms:each numbersToSum sep=',' >
<cms:set result = "<cms:add result item />" scope='global'/>
</cms:each>
<cms:show result />
Let's build our own function , based only on the tags CouchCMS provides with the help of snippets.
Snippets are great reusable pieces of code, but today I am going to show again how make them truly independent, very much like functions.
(1)
Create a snippet 'add-many.html'. I will put it to some sub-folder that I prefer to call 'functions', so the call would look like:
- Code: Select all
<cms:embed 'functions/add-many.html' />
Snippet's initial content consists of the core of the operation - summing. Our future function will accept any string of comma-separated numbers and return result.
- Code: Select all
<cms:each numbersToSum sep=',' >
<cms:set result = "<cms:add result item />" />
</cms:each>
(2)
Let's see our real-world tasks, that we need to perform with
- Code: Select all
<h3>Sum a set of numbers</h3>
<cms:set numbersToSum='10,20,30,40' />
<cms:set totalSum = '0' scope='global'/>
<cms:embed 'functions/add-many.html' />
<cms:show totalSum />
<!-- // ----------------------------------------------- -->
<h3>Average age of humans</h3>
<cms:set peopleAgeData='16,23,55,82,30' />
<cms:set averageAge = '0' scope='global'/>
<cms:embed 'functions/add-many.html' />
<cms:set averageAge = "<cms:div sumOfAges peopleCount />" />
<cms:show averageAge />
Incoming data has different names: numbersToSum, peopleAgeData, Outgoing: totalSum, sumOfAges, peopleCount.
(3)
With everything prepared, we must make sure our function accepts various names as incoming data and returns variable that we expect. In other words, complete independence of this snippet-function is required. Following approach helps us:
- Code: Select all
<!-- "cms:embed" tag supports its own scope of variables, if written as a tag-pair: -->
<cms:embed 'functions/add-many.html' ></cms:embed>
// -------------- IMPORTANT FEATURES ----------
<!-- "cms:embed" tag also supports passing variables in its own scope towards the content of the snippet -->
<cms:embed 'functions/add-many.html' var=my_var var2='55' ></cms:embed>
So, let's rewrite front-end code with the help of arguments-variables set as incoming and outgoing data. We will have in this example 3 parameters that will be used by function: data, result, count (optional). Our snippet should read numbers from a variable which name is stored in parameter 'data', put results in a variable which name is stored in parameter 'result' and same with 'count'.
Final code on the front-end (aka function calls)
- Code: Select all
<cms:set numbersToSum='10,20,30,40' />
<cms:embed 'functions/add-many.html' data='numbersToSum' result='totalSum' ></cms:embed>
<cms:show totalSum />
<!-- // ---------------------------------------- -->
<cms:set peopleAgeData='16,23,55,82,30' />
<cms:embed 'functions/add-many.html' data='peopleAgeData' result='sumOfAges' count='peopleCount'></cms:embed>
<cms:set averageAge = "<cms:div sumOfAges peopleCount />" />
<cms:show averageAge />
(4)
Let's instruct the code in the snippet to use passed arguments and operate upon them. (If you place cms:dump inside the snippet to debug, you will see how these arguments are present there). Final look of the snippet:
- Code: Select all
<cms:hide>
// Receive passed values:
</cms:hide>
<cms:set fdata = "<cms:get data />" scope='local' /><cms:ignore>// 'fdata' will have content of variable whose name is stored in argument 'data'. </cms:ignore>
<cms:set fresult = '0' scope='local' />
<cms:hide>
// Perform calculations:
</cms:hide>
<cms:each fdata sep=',' >
<cms:set fresult = "<cms:add fresult item />" scope='local' />
<cms:if k_last_item ><cms:put var=result value=fresult scope='global' /><cms:ignore>// function doesn't know where to put results, but target variable's name is stored in 'result'</cms:ignore>
<cms:if count ><cms:put var=count value=k_total_items scope='global' /></cms:if>
</cms:if>
</cms:each>
See, how easier it will be to maintain your code and reuse parts of it in truly awesome independent manner. Much less code required in templates to do stuff and snippet can be reused independently (yes, you can save the code for future and maybe even share your functions as well )
Hopefully, this brilliant explanation positively influences your day-to-day coding.
Regards
Anton