2
This file is part of the Grantlee template system.
4
Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Lesser General Public
8
License as published by the Free Software Foundation; either version
9
2 of the Licence, or (at your option) any later version.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Library General Public License for more details.
16
You should have received a copy of the GNU Lesser General Public
17
License along with this library. If not, see <http://www.gnu.org/licenses/>.
23
#include <QtCore/QStringList>
25
#include "exception.h"
29
static const char * _namedCycleNodes = "_namedCycleNodes";
31
CycleNodeFactory::CycleNodeFactory()
36
Node* CycleNodeFactory::getNode( const QString &tagContent, Parser *p ) const
38
QStringList expr = smartSplit( tagContent );
40
if ( expr.size() < 1 ) {
41
throw Grantlee::Exception( TagSyntaxError, QString( "%1 expects at least one argument" ).arg( expr.at( 0 ) ) );
44
if ( expr.at( 1 ).contains( ',' ) ) {
45
QStringList csvlist = expr.at( 1 ).split( ',' );
47
for ( int i = 0; i < csvlist.size() ; ++i ) {
48
expr.insert( i + 1, '"' + csvlist.at( i ) + '"' );
52
if ( expr.size() == 2 ) {
54
QString name = expr.at( 1 );
55
QVariant cycleNodes = p->property( _namedCycleNodes );
56
if ( !cycleNodes.isValid() || cycleNodes.type() != QVariant::Hash ) {
57
throw Grantlee::Exception( TagSyntaxError, QString( "No named cycles in template. '%1' is not defined" ).arg( name ) );
59
QVariantHash hash = cycleNodes.toHash();
60
if ( !hash.contains( name ) ) {
61
throw Grantlee::Exception( TagSyntaxError, QString( "Node not found: %1" ).arg( name ) );
63
QVariant nodeVariant = hash.value( name );
64
if ( nodeVariant.userType() != QMetaType::QObjectStar ) {
65
throw Grantlee::Exception( TagSyntaxError, "Invalid object in node cycle list" );
67
QObject *obj = nodeVariant.value<QObject*>();
68
Node *node = qobject_cast<Node*>( obj );
70
throw Grantlee::Exception( TagSyntaxError, "Invalid object in node cycle list" );
75
int exprSize = expr.size();
76
if ( exprSize > 4 && expr.at( exprSize - 2 ) == "as" ) {
77
// {% cycle "foo" "bar" "bat" as var %}
78
QString name = expr.at( exprSize - 1 );
79
QStringList list = expr.mid( 1, exprSize - 3 );
80
Node *node = new CycleNode( getFilterExpressionList( list, p ), name, p );
81
QVariant hashVariant = p->property( _namedCycleNodes );
83
if ( hashVariant.isValid() && hashVariant.type() == QVariant::Hash ) {
84
hash = hashVariant.toHash();
86
QObject *nodeObject = node;
87
QVariant nodeVariant = QVariant::fromValue( nodeObject );
88
hash.insert( name, nodeVariant );
89
p->setProperty( _namedCycleNodes, QVariant( hash ) );
92
QStringList list = expr.mid( 1, exprSize - 1 );
93
return new CycleNode( getFilterExpressionList( list, p ), QString(), p );
97
CycleNode::CycleNode( QList<FilterExpression> list, const QString &name, QObject *parent )
98
: Node( parent ), m_variableIterator( list )
103
void CycleNode::render( OutputStream *stream, Context *c )
106
QTextStream textStream( &value );
107
QSharedPointer<OutputStream> temp = stream->clone( &textStream );
109
m_variableIterator.next().resolve( temp.data(), c );
110
if ( !m_name.isEmpty() ) {
111
c->insert( m_name, value );
113
( *stream ) << value;