Skip to content

Commit 1abefa0

Browse files
committed
Wip change loop structure
1 parent ba655bc commit 1abefa0

17 files changed

+4552
-19999
lines changed

docs/Configuration/_category_.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"position": 2
3+
}
File renamed without changes.
File renamed without changes.
File renamed without changes.

docs/Configuration/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
sidebar_position: 1
3+
sidebar_label: Easy
4+
---
File renamed without changes.

docs/Loops/_category_.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"position": 3
3+
}

docs/loops/index.md renamed to docs/Loops/index.md

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
title: How it works
2+
title: Introduction to loops
33
---
44

55
Loops are the most convenient feature in Thelia for front developers. Already there in Thelia's first version, they deserved a makeover for Thelia v2.
@@ -211,3 +211,163 @@ List of output parameters :
211211
</ul>
212212
</div>
213213
```
214+
215+
216+
## Declare your loops
217+
218+
```xml
219+
<loops>
220+
<loop name="mymodule_product" class="MyModule\Loop\Product" />
221+
<loop name="mymodule_myloop" class="MyModule\Loop\MyLoop" />
222+
</loops>
223+
```
224+
225+
You have to create as many loop node as loop you have into the loops node. In this example there is 2 loops. Name and
226+
class properties are mandatory. The name is the loop name used into the template ( like in Thelia v1 : ```<THELIA_name
227+
type="MyModule_Product">...</THELIA_name>```), class property is the class executed by the template engine. This
228+
class must extends the Thelia\Core\Template\Element\BaseLoop abstract class, if not an exception is thrown.
229+
**If you name your loop like a default loop (eg : product), your loop will replace the default loop.**
230+
231+
## Implement your loops
232+
233+
Your loop can be anywhere (Thanks to namespace) in your module but it's better to create a Loop directory and put all your loops in this directory.
234+
235+
You have to extends the Thelia\Core\Template\Element\BaseLoop abstract class and implement either Thelia\Core\Template\Element\PropelSearchLoopInterface or Thelia\Core\Template\Element\ArraySearchLoopInterface. Therefore you will have to create *getArgDefinitions*, *parseResults* and either *buildModelCriteria* or *buildArray* methods.
236+
237+
NB : You can also extend BaseI18nLoop which itself extends BaseLoop. This will provide tools to manage i18n in your loop.
238+
239+
### What's the difference betwen *PropelSearchLoopInterface* and *ArraySearchLoopInterface*
240+
241+
It's a matter of data type. If the data your loop returns come from the database you must implement *PropelSearchLoopInterface* and create *buildModelCriteria* method which return a *Propel\Runtime\ActiveQuery\ModelCriteria*. Conversely if your loop displays data from an array you must implement *ArraySearchLoopInterface* and create *buildArray* method which return an array.
242+
243+
The *parseResults* method is used to render the template. It must return a Thelia\Core\Template\Element\LoopResult instance.
244+
245+
The getArgDefinitions method defines all args used in your loop. Args can be mandatory, optional, with default value, etc. This method must return an Thelia\Core\Template\Loop\Argument\ArgumentCollection. ArgumentCollection contains Thelia\Core\Template\Loop\Argument which contains a Thelia\Type\TypeCollection. Types in the collection must implement Thelia\Type\TypeInterface.
246+
247+
If you don't define your arguments here, you can't use them in your new loop. All arguments are accessible in the ```parseResults``` method.
248+
249+
Baseloop class declares 3 public properties you might overload in your new loop.
250+
251+
```php
252+
public $countable = true;
253+
public $timestampable = false;
254+
public $versionable = false;
255+
```
256+
257+
With these properties set to true, the loop will automatically render - or not - the following outputs :
258+
259+
```php
260+
if($countable === true)
261+
```
262+
263+
* LOOP_COUNT
264+
* LOOP_TOTAL
265+
266+
```php
267+
if($timestampable === true) //available if your table is timestampable
268+
```
269+
270+
* CREATE_DATE
271+
* CREATE_UPDATE
272+
273+
### Example 1
274+
275+
Here an example for my module "MyModule" and my loops in the loop directory. This is the architecture :
276+
277+
```
278+
\local
279+
\modules
280+
\MyModule
281+
...
282+
\Loop
283+
MyLoop.php
284+
```
285+
286+
MyLoop.php file :
287+
288+
```php
289+
namespace MyModule\Loop;
290+
291+
use Thelia\Core\Template\Element\BaseLoop;
292+
use Thelia\Core\Template\Element\LoopResult;
293+
use Thelia\Core\Template\Element\LoopResultRow;
294+
use Thelia\Core\Template\Element\ArraySearchLoopInterface;
295+
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
296+
use Thelia\Core\Template\Loop\Argument\Argument;
297+
298+
class MyLoop extends BaseLoop implements ArraySearchLoopInterface {
299+
300+
public $countable = true;
301+
public $timestampable = false;
302+
public $versionable = false;
303+
304+
public function getArgDefinitions()
305+
{
306+
return new ArgumentCollection(
307+
Argument::createIntListTypeArgument('start', 0),
308+
Argument::createIntListTypeArgument('stop', null, true)
309+
);
310+
}
311+
312+
public function buildArray()
313+
{
314+
$items = array();
315+
316+
$start = $this->getStart();
317+
$stop = $this->getStop();
318+
319+
for($i=$start; $i<=$stop; $i++ {
320+
$items[] = $i;
321+
}
322+
323+
return $items;
324+
325+
}
326+
327+
public function parseResults(LoopResult $loopResult)
328+
{
329+
foreach ($loopResult->getResultDataCollection() as $item) {
330+
331+
$loopResultRow = new LoopResultRow();
332+
333+
$loopResultRow->set("MY_OUTPUT", $item);
334+
335+
$loopResult->addRow($loopResultRow);
336+
}
337+
338+
return $loopResult;
339+
}
340+
}
341+
342+
```
343+
344+
Of course you can use all classes you want in your own loop class, like model class. All Thelia's model classes are in the
345+
namespace Thelia\Model
346+
347+
So if I want to add some search in my DB and return results from product table I can use something like this :
348+
349+
```php
350+
/**
351+
*
352+
* return Thelia\Core\Template\Element\LoopResult
353+
*/
354+
public function buildModelCriteria()
355+
{
356+
return ProductQuery::create();
357+
}
358+
359+
public function parseResults(LoopResult $loopResult)
360+
{
361+
foreach ($loopResult->getResultDataCollection() as $product) {
362+
363+
$loopResultRow = new LoopResultRow($product);
364+
365+
$loopResultRow->set("REF", $product->getRef());
366+
367+
$loopResult->addRow($loopResultRow);
368+
}
369+
370+
return $loopResult;
371+
}
372+
```
373+

docs/Loops/order.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
title: Order
3+
---

docs/Loops/product.mdx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: Product
3+
---
4+
5+
import Tabs from '@theme/Tabs';
6+
import TabItem from '@theme/TabItem';
7+
8+
## Arguments
9+
10+
### Specific Arguments
11+
| Argument | Description | Default | Example |
12+
| ------------- |-------------|-------------|-------------|
13+
| id | A single or a list of product ids. | | id="2" \| id="1,4,7" |
14+
| category | The maximum number of results to display. | | limit="10" |
15+
| category_default |The first product to display offset. Will not be used if `page` argument is set. | 0 | offset="10" |
16+
| brand | The page to display. | | page="2" |
17+
| new | Determine if loop is use in backend context. | false | backend_context="on" |
18+
| ref | force return result for i18n tables even if there is no record | false | force_return="on" |
19+
| order | force return result for i18n tables even if there is no record | false | force_return="on" |
20+
21+
### General Arguments
22+
| Argument | Description | Default | Example |
23+
| ------------- |:-------------:|-------------:|-------------:|
24+
| name * | The loop name. This name must be unique and is used to reference this loop. | | name="my_name_loop" |
25+
| limit | The maximum number of results to display. | | limit="10" |
26+
| offset |The first product to display offset. Will not be used if `page` argument is set. | 0 | offset="10" |
27+
| page | The page to display. | | page="2" |
28+
| backend_context | Determine if loop is use in backend context. | false | backend_context="on" |
29+
| force_return | force return result for i18n tables even if there is no record | false | force_return="on" |
30+
31+
### Search Arguments
32+
| Argument | Description | Default | Example |
33+
| ------------- |:-------------:|-------------:|-------------:|
34+
| search_in | A comma separeted list of field in which the search is performed. Possible values : ref, title, chapo, description, postscriptum. | | search_in="title" |
35+
| search_mode | The search mode : `any_word` (search any word separeted by a space), `sentence` (the sentence, anywhere in the field) or `strict_sentence` (the exact sentence). | strict_sentence | search_mode="strict_sentence" |
36+
| search_term | The term to search. | 0 | search_term="my product" |
37+
38+
## Outputs
39+
40+
### General output
41+
| Argument | Description | Default | Example |
42+
| ------------- |-------------|-------------|-------------|
43+
| id | A single or a list of product ids. | | id="2" \| id="1,4,7" |
44+
| category | The maximum number of results to display. | | limit="10" |
45+
| category_default |The first product to display offset. Will not be used if `page` argument is set. | 0 | offset="10" |
46+
| brand | The page to display. | | page="2" |
47+
| new | Determine if loop is use in backend context. | false | backend_context="on" |
48+
| ref | force return result for i18n tables even if there is no record | false | force_return="on" |
49+
| order | force return result for i18n tables even if there is no record | false | force_return="on" |
50+
51+
## Examples

0 commit comments

Comments
 (0)