void BlockNode::render( OutputStream *stream, Context *c ) { QVariant &variant = c->renderContext()->data( BLOCK_CONTEXT_KEY ); BlockContext blockContext = variant.value<BlockContext>(); c->push(); if ( blockContext.isEmpty() ) { m_context = c; m_stream = stream; c->insert( QLatin1String( "block" ), QVariant::fromValue( static_cast<QObject *>( this ) ) ); m_list.render( stream, c ); m_stream = 0; } else { BlockNode *block = blockContext.pop( m_name ); variant.setValue( blockContext ); BlockNode *push = block; if ( !block ) block = this; // BIC Make const when render() is const. NodeList list = block->m_list; block = new BlockNode( block->m_name, 0 ); block->setNodeList( list ); block->m_context = c; block->m_stream = stream; c->insert( QLatin1String( "block" ), QVariant::fromValue( static_cast<QObject *>( block ) ) ); list.render( stream, c ); delete block; if ( push ) { blockContext.push( m_name, push ); variant.setValue( blockContext ); } } c->pop(); }
Node* BlockNodeFactory::getNode( const QString &tagContent, Parser *p ) const { const QStringList expr = smartSplit( tagContent ); if ( expr.size() != 2 ) { throw Grantlee::Exception( TagSyntaxError, QLatin1String( "block tag takes one argument" ) ); } const QString blockName = expr.at( 1 ); QVariant loadedBlocksVariant = p->property( __loadedBlocks ); QVariantList blockVariantList; if ( loadedBlocksVariant.isValid() && loadedBlocksVariant.type() == QVariant::List ) { blockVariantList = loadedBlocksVariant.toList(); QListIterator<QVariant> it( blockVariantList ); while ( it.hasNext() ) { const QString blockNodeName = it.next().toString(); if ( blockNodeName == blockName ) { throw Grantlee::Exception( TagSyntaxError, QString::fromLatin1( "%1 appears more than once." ).arg( blockName ) ); } } } // Block not already in list. blockVariantList.append( blockName ); loadedBlocksVariant = QVariant( blockVariantList ); p->setProperty( __loadedBlocks, loadedBlocksVariant ); BlockNode *n = new BlockNode( blockName, p ); const NodeList list = p->parse( n, QStringList() << QLatin1String( "endblock" ) << QLatin1String( "endblock " ) + blockName ); n->setNodeList( list ); p->removeNextToken(); return n; }