Skip to content
This repository was archived by the owner on Jul 28, 2023. It is now read-only.
119 changes: 119 additions & 0 deletions phpunit/directives/attributes/wp-each.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php
/**
* data-wp-each attribute directive test.
*/

require_once __DIR__ . '/../../../src/directives/attributes/wp-each.php';

require_once __DIR__ . '/../../../src/directives/class-wp-directive-context.php';

require_once __DIR__ . '/../../../src/directives/class-wp-directive-processor.php';

/**
* Tests for the data-wp-each attribute directive.
*
* @group directives
* @covers process_wp_each
*/
class Tests_Directives_Attributes_WpEach extends WP_UnitTestCase {
public function test_directive_expands_correctly() {
$directives = array(
'data-wp-text' => function( $tags, $context ) {
if ( $tags->is_tag_closer() ) {
return;
}

$value = $tags->get_attribute( 'data-wp-text' );
if ( null === $value ) {
return;
}

$text = evaluate( $value, $context->get_context() );
$tags->set_inner_html( $text );
$tags->get_updated_html(); // FIXME: We shouldn't need to do this here.
},
);

$context = new WP_Directive_Context(
array(
'data' => array(
array(
'id' => 123,
'label' => 'foo',
),
array(
'id' => 456,
'label' => 'bar',
),
array(
'id' => 789,
'label' => 'foobar',
),
),
)
);

$markup = <<<EOF
<table class="table table-hover table-striped test-data">
<tbody data-wp-each:item="context.data" wp-key="id">
<tr class="" data-wp-class:danger="state.isSelected">
<td class="col-md-1" data-wp-text="context.item.id"></td>
<td class="col-md-4">
<a wp-on:click="actions.select" data-wp-text="context.item.label"></a>
</td>
<td class="col-md-1">
<a wp-on:click="actions.remove"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a>
</td>
<td class="col-md-6"></td>
</tr>
</tbody>
</table>
EOF;
$tags = new WP_Directive_Processor( $markup );
$tags->next_tag(); // table
$tags->next_tag(); // tbody

process_wp_each( $tags, $context, $directives );

$updated_markup = <<<EOF
<table class="table table-hover table-striped test-data">
<tbody data-wp-each:item="context.data" wp-key="id">
<tr class="" data-wp-class:danger="state.isSelected">
<td class="col-md-1" data-wp-text="context.item.id">123</td>
<td class="col-md-4">
<a wp-on:click="actions.select" data-wp-text="context.item.label">foo</a>
</td>
<td class="col-md-1">
<a wp-on:click="actions.remove"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a>
</td>
<td class="col-md-6"></td>
</tr>

<tr class="" data-wp-class:danger="state.isSelected">
<td class="col-md-1" data-wp-text="context.item.id">456</td>
<td class="col-md-4">
<a wp-on:click="actions.select" data-wp-text="context.item.label">bar</a>
</td>
<td class="col-md-1">
<a wp-on:click="actions.remove"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a>
</td>
<td class="col-md-6"></td>
</tr>

<tr class="" data-wp-class:danger="state.isSelected">
<td class="col-md-1" data-wp-text="context.item.id">789</td>
<td class="col-md-4">
<a wp-on:click="actions.select" data-wp-text="context.item.label">foobar</a>
</td>
<td class="col-md-1">
<a wp-on:click="actions.remove"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a>
</td>
<td class="col-md-6"></td>
</tr>
</tbody>
</table>
EOF;

$this->assertSame( $updated_markup, $tags->get_updated_html() );
}
}
39 changes: 39 additions & 0 deletions src/directives/attributes/wp-each.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

require_once __DIR__ . '/../class-wp-directive-processor.php';

function process_wp_each( $tags, $context, $directives ) {
if ( $tags->is_tag_closer() ) {
return;
}

$prefixed_attributes = $tags->get_attribute_names_with_prefix( 'data-wp-each:' );
if ( 0 === count( $prefixed_attributes ) ) {
return;
}
$attribute_name = $prefixed_attributes[0];

list( , $iterator_name ) = explode( ':', $attribute_name );

$value = $tags->get_attribute( $attribute_name );
if ( null === $value ) {
// No wp-each directive.
return;
}

$loop_array = evaluate( $value, $context->get_context() );
// TODO: Error handling.

$loop_inner_html = '';
foreach ( $loop_array as $iteration_item ) {
$context->set_context( array( 'item' => $iteration_item ) );

$inner_html = $tags->get_inner_html();
$inner_tags = new WP_Directive_Processor( $inner_html );
$inner_tags = wp_process_directives( $inner_tags, 'data-wp-', $directives, $context );
$loop_inner_html .= $inner_tags->get_updated_html();
$context->rewind_context();
}
$tags->set_inner_html( $loop_inner_html );
$tags->next_balanced_closer();
}
8 changes: 5 additions & 3 deletions src/directives/wp-process-directives.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
require_once __DIR__ . '/class-wp-directive-context.php';
require_once __DIR__ . '/class-wp-directive-processor.php';

function wp_process_directives( $tags, $prefix, $directives ) {
$context = new WP_Directive_Context;
function wp_process_directives( $tags, $prefix, $directives, $context = null ) {
if ( ! $context ) {
$context = new WP_Directive_Context;
}

$tag_stack = array();
while ( $tags->next_tag( array( 'tag_closers' => 'visit' ) ) ) {
Expand Down Expand Up @@ -50,7 +52,7 @@ function wp_process_directives( $tags, $prefix, $directives ) {
}

foreach ( $attributes as $attribute ) {
call_user_func( $directives[ $attribute ], $tags, $context );
call_user_func( $directives[ $attribute ], $tags, $context, $directives );
}
}

Expand Down
2 changes: 2 additions & 0 deletions wp-directives.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function () {
require_once __DIR__ . '/src/directives/attributes/wp-bind.php';
require_once __DIR__ . '/src/directives/attributes/wp-context.php';
require_once __DIR__ . '/src/directives/attributes/wp-class.php';
require_once __DIR__ . '/src/directives/attributes/wp-each.php';
require_once __DIR__ . '/src/directives/attributes/wp-html.php';
require_once __DIR__ . '/src/directives/attributes/wp-style.php';
require_once __DIR__ . '/src/directives/attributes/wp-text.php';
Expand Down Expand Up @@ -218,6 +219,7 @@ function process_directives_in_block( $block_content ) {
'data-wp-context' => 'process_wp_context',
'data-wp-bind' => 'process_wp_bind',
'data-wp-class' => 'process_wp_class',
'data-wp-each' => 'process_wp_each',
'data-wp-html' => 'process_wp_html',
'data-wp-style' => 'process_wp_style',
'data-wp-text' => 'process_wp_text',
Expand Down