-
Notifications
You must be signed in to change notification settings - Fork 43
[WIP] removal of duplicate about attribute in collections rendering #46
Changes from 5 commits
73049ee
5dc9560
e3f032f
280c10e
8d549c6
d146e4d
e3ea138
caa8488
a885ae8
3395fd6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,17 +29,22 @@ class CreatephpNode extends Twig_Node | |
* @param Twig_NodeInterface $body The body node | ||
* @param string $modelname The name of the model class to make an rdfa entity | ||
* @param string $varname The name for the rdfa entity to expose | ||
* @param boolean $autotag Automatically render start and end part of the node? | ||
* @param integer $lineno The line number | ||
* @param string $tag The tag name | ||
*/ | ||
public function __construct(Twig_NodeInterface $body, $modelname, $varname, $lineno = 0, $tag = null) | ||
public function __construct(Twig_NodeInterface $body, $modelname, $varname, $autotag, $lineno = 0, $tag = null) | ||
{ | ||
$nodes = array('body' => $body); | ||
if (empty($varname)) { | ||
$varname = $modelname . '_rdf'; | ||
} | ||
|
||
$attributes = array('varname' => $varname, 'modelname' => $modelname); | ||
$attributes = array( | ||
'varname' => $varname, | ||
'modelname' => $modelname, | ||
'autotag' => $autotag | ||
); | ||
|
||
parent::__construct($nodes, $attributes, $lineno, $tag); | ||
} | ||
|
@@ -59,9 +64,32 @@ public function compile(Twig_Compiler $compiler) | |
|
||
$compiler | ||
->raw(";\n") | ||
; | ||
|
||
$autotag = $this->getAttribute('autotag'); | ||
if ($autotag) { | ||
$compiler->write('echo '); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we start rendering even when we do not want to output, to set the node into the correct mode. it is up to the user to be intelligent enough to understand what he has to do if he is using noautotag. |
||
} | ||
|
||
$compiler | ||
->write('$context[') | ||
->repr($this->getAttribute('varname')) | ||
->write(']->renderStart()') | ||
->raw(";\n"); | ||
|
||
$compiler | ||
->subcompile($this->getNode('body')) | ||
; | ||
|
||
if ($autotag) { | ||
$compiler->write('echo '); | ||
} | ||
$compiler | ||
->write('$context[') | ||
->repr($this->getAttribute('varname')) | ||
->write(']->renderEnd()') | ||
->raw(";\n"); | ||
|
||
$compiler | ||
->write('unset($context[') | ||
->repr($this->getAttribute('varname')) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ | |
* attributes, parent/children relations and rendering. The latter is split into three | ||
* different functions for maximum flexibility. So you can call render() to output the | ||
* complete node HTML, or you can call render_start() for the opening tag, render_content() | ||
* for the node's content (or children) and render_end() for the colsing tag. | ||
* for the node's content (or children) and render_end() for the closing tag. | ||
* | ||
* @package Midgard.CreatePHP | ||
*/ | ||
|
@@ -245,12 +245,13 @@ public function renderStart($tag_name = false) | |
$this->_tag_name = $tag_name; | ||
} | ||
|
||
$attributesToSkip = array(); | ||
|
||
if ( $this->_parent | ||
&& $this->_parent->isRendering()) | ||
{ | ||
//remove about to work around a VIE bug with nested identical about attributes | ||
$about_backup = $this->getAttribute('about'); | ||
$this->unsetAttribute('about'); | ||
$attributesToSkip[] = 'about'; | ||
} | ||
|
||
$template = explode('__CONTENT__', $this->_template); | ||
|
@@ -259,14 +260,9 @@ public function renderStart($tag_name = false) | |
$replace = array | ||
( | ||
"__TAG_NAME__" => $this->_tag_name, | ||
" __ATTRIBUTES__" => $this->renderAttributes(), | ||
" __ATTRIBUTES__" => $this->renderAttributes($attributesToSkip), | ||
); | ||
|
||
if (!empty($about_backup)) | ||
{ | ||
$this->setAttribute('about', $about_backup); | ||
} | ||
|
||
$this->_is_rendering = true; | ||
return strtr($template, $replace); | ||
} | ||
|
@@ -291,11 +287,15 @@ public function render($tag_name = false) | |
* | ||
* @api | ||
*/ | ||
public function renderAttributes() | ||
public function renderAttributes($attributesToSkip = array()) | ||
{ | ||
// add additional attributes | ||
$attributes = ''; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think you should array_swap and then check with isset instead of in_array. in_array needs to loop through the whole array for each lookup - once swapped the values are the keys and isset is a fast hash lookup. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In $attributesToRemove, we have only the name of the attributes to skip. So in this case, the array is either empty or having one single element: 'about'. So $attributesToRemove is not an associative array. The key and values here are for $this->_attributes. So I guess it doesn't make senses to change it the way you propose? Or did I miss something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well as its an array other uses could skip many attributes. if you swap this array you will have array('about' => 0) which makes the lookup the same speed regardless of the array length. though swapping the array also costs something. maybe we could say the array must already be passed with the keys saying what to skip. it does not make more effort in calling and would definitely be faster in all cases than in_array. |
||
$swappedAttributes = array_flip($attributesToSkip); | ||
foreach ($this->_attributes as $key => $value) { | ||
if (isset($swappedAttributes[$key])) { | ||
continue; | ||
} | ||
$attributes .= ' ' . $key . '="' . $value . '"'; | ||
} | ||
if ($attributes === ' ') { | ||
|
@@ -329,6 +329,9 @@ public function renderEnd() | |
*/ | ||
public function __toString() | ||
{ | ||
if ($this->isRendering()) { | ||
return $this->renderContent(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do not render start and end again if we are already rendering. this is helpful in twig to say
|
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it wouldn't be better to move this logic to the render() method, because right now the last two lines would produce different outputs: echo $entity->renderStart();
echo $entity; //only renders content
echo $entity->render(); //renders enclosing tags as well. You could of course say that render() is the "I know what I'm doing" option, but then this should be clearly stated in the phpdoc. But intuitively, I would say that the __toString method should be only an alias to render() so that they always behave in the same way. Of course, I might still be convinced otherwise :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think you are right. and i see no good usecase where i would want to renderStart and before renderEnd call render and get the enclosing tag again. |
||
return $this->render(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,9 +142,11 @@ public function renderEnd(); | |
* Render just the attributes. This is not needed if you use | ||
* renderStart() | ||
* | ||
* @param array $attributesToSkip attributes names that will not be printed | ||
* | ||
* @return string the rendered attributes | ||
*/ | ||
public function renderAttributes(); | ||
public function renderAttributes($attributesToSkip = array()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How would you feel about using a typehint here? i.e. public function renderAttributes(array $attributesToSkip = array()); just to make it a bit more robust There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. willdo |
||
|
||
/** | ||
* Has to return the same as self::render() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
namespace Test\Midgard\CreatePHP; | ||
|
||
class Collection | ||
{ | ||
public function getTitle() | ||
{ | ||
return 'the collection title'; | ||
} | ||
|
||
public function getSubject() | ||
{ | ||
return '/the/subject/collection'; | ||
} | ||
|
||
public function getChildren() | ||
{ | ||
return array( | ||
new Model('title 1', 'content 1', '/the/subject/model/1'), | ||
new Model('title 2', 'content 2', '/the/subject/model/2') | ||
); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think the first example should be using the autotag feature, and then we add a section how to have more control over the html from the template where we explain the noautotag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually if you look at https://github.com/symfony-cmf/createphp/blob/d146e4d71dd0797ffc0c4ccc859c4cf9a8e2ab1a/README.md#twig-extension, the first example is using the autotag:
{% createphp mymodel %}{{ mymodel_rdf|raw }}{% endcreatephp %}
Is it ok like this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah sorry, just saw that this replaced something existing and thought there is no more example without noautotag. all fine then.