KK wrote: Of course, with a little more effort you can have an array of questions (can even use repeatable regions or cloned pages for storing the questions) and then display them randomly.
I made a copy-paste code for this. Only used a
<cms:each /> mod to count total number of questions in list and have
startcount parameter. Used that total number to select one randomly. Comments /** can be removed. A small php function also doesn't stink.
- Code: Select all
/** List of potential questions and answers
<cms:capture into='questions'>
What color is the sky? | blue ;
What is 1+1? | 2 ;
What is the color of grass? | green ;
Are you a robot? | no ;
Are you human? | yes
</cms:capture>
/** Take a random question from list
<cms:each questions sep=';' as='question' startcount='1'>
<cms:if k_count='1' >
<cms:set random_number = "<cms:php>echo (rand(1,<cms:show k_total_count />));</cms:php>"/>
</cms:if>
<cms:if k_count=random_number>
<cms:set antispam_question = question scope='global'/>
</cms:if>
</cms:each>
/** Save question and answer separately
<cms:if "<cms:not antispam_question />" >
/** if list is gone.. breathe and set defaults
<cms:set antispam_question = 'What color is the sky?' scope='global'/>
<cms:set antispam_answer = 'blue' scope='global'/>
<cms:else />
<cms:each antispam_question as='piece'>
<cms:if k_count='0'>
<cms:set antispam_question = piece scope='global'/>
<cms:else_if k_count='1'/>
<cms:set antispam_answer = piece scope='global'/>
</cms:if>
</cms:each>
</cms:if>
/** Prepare a hint for a human
<cms:set count = "<cms:php>echo strlen('<cms:show antispam_answer />');</cms:php>" /> /** use mb_strlen if non-latin characters
<cms:if count eq '1' >
<cms:set answer_hint = '1 character' scope='global' />
<cms:else_if count gt '1' />
<cms:set answer_hint = "<cms:concat count ' characters' />" scope='global' />
<cms:else />
<cms:set answer_hint = 'Unknown error' scope='global' />
</cms:if>
/** Remember the correct answer
<cms:set_flash name='antispam_answer' value=antispam_answer />
Code sets 3 variables:
antispam_question,
answer_hint,
antispam_answer.
And validator pattern will match the correct answer after the form submits and page reloads.
- Code: Select all
<label class="required" for="human">
<cms:show antispam_question /> (<cms:show answer_hint />)
<em>* <cms:if k_error_human>Please answer the question</cms:if></em>
</label>
<cms:input type="text" required='1' validator="regex=/^<cms:get_flash 'antispam_answer' />$/i" class="input-text required-entry" id="human" name="human"/>
If the list, established in code above, must be edited in backend, here is a definition of repeatable region:
- Code: Select all
<cms:repeatable name='security_questions' order='20' label='List of security questions for antispam'>
<cms:editable type='text' col_width='300' label='Question' name='security_question' />
<cms:editable type='text' col_width='100' label='Answer' name='security_answer' />
</cms:repeatable>
Screenshot:

- ScreenCut-01-14---22-20-46-.png (20.15 KiB) Viewed 1357 times
And code can be changed as follows:
- Code: Select all
/** List of potential questions and answers
<cms:capture into='questions'>
<cms:show_repeatable 'security_questions' >
<cms:show security_question /> | <cms:show security_answer /> ;
</cms:show_repeatable>
</cms:capture>