File indexing completed on 2025-02-09 04:28:37
0001 /* 0002 This file is part of the KTextTemplate library 0003 0004 SPDX-FileCopyrightText: 2009, 2010 Stephen Kelly <steveire@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 0008 */ 0009 0010 #ifndef KTEXTTEMPLATE_CONTEXT_H 0011 #define KTEXTTEMPLATE_CONTEXT_H 0012 0013 #include "abstractlocalizer.h" 0014 #include "ktexttemplate_export.h" 0015 0016 #include <QVariantHash> 0017 0018 namespace KTextTemplate 0019 { 0020 0021 class RenderContext; 0022 0023 class ContextPrivate; 0024 0025 /// @headerfile context.h <KTextTemplate/Context> 0026 0027 /** 0028 @brief The **%Context** class holds the context to render a Template with. 0029 0030 For application developers, using the **%Context** class is a matter of 0031 inserting keys and values as appropriate for rendering a Template using the 0032 @ref insert method. 0033 0034 @code 0035 auto t = engine->newTemplate( 0036 "Name is {% name %} and age is {% age %}.", "some_template" ); 0037 0038 Context c1; 0039 c1.insert( "name", "Tom" ); 0040 c1.insert( "age", 34 ); 0041 0042 Context c2; 0043 c2.insert( "name", "Harry" ); 0044 c2.insert( "age", 43 ); 0045 0046 t->render(c1); // Returns "Name is Tom and age is 43." 0047 t->render(c2); // Returns "Name is Harry and age is 34." 0048 @endcode 0049 0050 Note that one Template may be rendered multiple times with different contexts. 0051 Note also that any QVariant may be inserted into a **%Context** object. Most 0052 commonly, QObjects will be used here. 0053 @see @ref custom_objects 0054 0055 @section context_stack Context Stack. 0056 0057 For template tag developers, some other **%Context** API is relevant. 0058 0059 It is possible to @ref push and @ref pop layers of context while a template 0060 is being rendered. This is useful if your template tag makes additional 0061 variables temporarily available in a part of a template. %Template tags 0062 should only modify layers of context that they @ref push themselves, and 0063 should @ref pop any layers created before finishing its rendering step. 0064 0065 See for example the @gr_tag{with} tag. In a template such as 0066 0067 @code 0068 Some content 0069 {% with person.name|toUpper as lowerName %} 0070 Name is {% lowerName %} 0071 {% endwith %} 0072 @endcode 0073 0074 In this case, lowerName is available in the context only between the 0075 @gr_tag{with} and @gr_tag{endwith} tags. The implementation of 0076 the @gr_tag{with} tag render method is: 0077 0078 @code 0079 void WithNode::render( OutputStream *stream, Context *c ) const 0080 { 0081 c->push(); 0082 // {% with m_filterExpression as m_name %} 0083 c->insert( m_name, m_filterExpression.resolve( c ) ); 0084 m_list.render( stream, c ); 0085 c->pop(); // The section of context defining m_name is removed. 0086 } 0087 @endcode 0088 0089 Note that a **%Context** may temporarily override a variable in a parent 0090 context. This is why it is important to @ref push a new context when adding 0091 items to context and @ref pop it when finished. 0092 0093 @code 0094 Some content 0095 {% with "foo" as var %} 0096 Var is {% var %} // Var is "foo" 0097 {% with "bar" as var %} 0098 Var is {% var %} // Var is "bar" 0099 {% endwith %} 0100 Var is {% var %} // Var is "foo" 0101 {% endwith %} 0102 @endcode 0103 0104 @author Stephen Kelly <steveire@gmail.com> 0105 */ 0106 class KTEXTTEMPLATE_EXPORT Context 0107 { 0108 public: 0109 /** 0110 Creates an empty context 0111 */ 0112 Context(); 0113 /** 0114 Sets every key in the hash as a property name with the variant as the 0115 value. 0116 */ 0117 explicit Context(const QVariantHash &hash); 0118 0119 /** 0120 Copy Constructor 0121 */ 0122 Context(const Context &other); 0123 0124 /** 0125 Assignmant operator 0126 */ 0127 Context &operator=(const Context &other); 0128 0129 #ifndef K_DOXYGEN 0130 /** 0131 @internal 0132 0133 Whether to automatically escape all context content. This is not usually 0134 used directly. Use the @gr_tag{autoescape} tag instead. 0135 */ 0136 bool autoEscape() const; 0137 0138 /** 0139 @internal 0140 0141 Sets whether to automatically escape all context content. This is not 0142 usually used directly. Use the @gr_tag{autoescape} tag instead. 0143 */ 0144 void setAutoEscape(bool autoescape); 0145 #endif 0146 /** 0147 Destructor 0148 */ 0149 ~Context(); 0150 0151 /** 0152 Returns the context object identified by the key @p str 0153 */ 0154 QVariant lookup(const QString &str) const; 0155 0156 /** 0157 Insert the context object @p object identified by @p name into 0158 the **%Context**. 0159 */ 0160 void insert(const QString &name, QObject *object); 0161 0162 /** 0163 Insert the context object @p variant identified by @p name into 0164 the **%Context**. 0165 */ 0166 void insert(const QString &name, const QVariant &variant); 0167 0168 /** 0169 Pushes a new context. 0170 @see @ref context_stack 0171 */ 0172 void push(); 0173 0174 /** 0175 Pops the context. 0176 @see @ref context_stack 0177 */ 0178 void pop(); 0179 0180 #ifndef K_DOXYGEN 0181 /** 0182 @internal Returns the context hash at depth @p depth. 0183 */ 0184 QVariantHash stackHash(int depth) const; 0185 0186 /** 0187 @internal 0188 Returns whether template being rendered is being mutated. 0189 */ 0190 bool isMutating() const; 0191 0192 /** 0193 @internal 0194 Sets whether template being rendered is being mutated to @p mutating. 0195 */ 0196 void setMutating(bool mutating); 0197 0198 /** 0199 @internal 0200 */ 0201 void addExternalMedia(const QString &absolutePart, const QString &relativePart); 0202 0203 /** 0204 @internal 0205 */ 0206 void clearExternalMedia(); 0207 #endif 0208 0209 /** 0210 Sets the @p localizer to be used. 0211 0212 The **%Context** takes ownerwhip of the localizer. 0213 */ 0214 void setLocalizer(QSharedPointer<AbstractLocalizer> localizer); 0215 0216 /** 0217 Returns the localizer currently in use. 0218 */ 0219 QSharedPointer<AbstractLocalizer> localizer() const; 0220 0221 /** 0222 Returns the external media encountered in the Template while rendering. 0223 */ 0224 QList<std::pair<QString, QString>> externalMedia() const; 0225 0226 /** 0227 The type of urls to external media that should be put in the template. 0228 */ 0229 enum UrlType { 0230 AbsoluteUrls, ///< Absolute URLs should be put in the template. 0231 RelativeUrls ///< Relative URLs should be put in the template. 0232 }; 0233 0234 /** 0235 Sets the type of external media URL to be used in the template to @p type. 0236 @see @ref media_finder_tag 0237 */ 0238 void setUrlType(UrlType type); 0239 0240 /** 0241 The type of URL used in the template. 0242 */ 0243 UrlType urlType() const; 0244 0245 /** 0246 Sets the relative path to external media to be used in templates to @p 0247 relativePath 0248 0249 @see @ref media_finder_tag 0250 */ 0251 void setRelativeMediaPath(const QString &relativePath); 0252 0253 /** 0254 The relative path to external media to be used in templates. 0255 */ 0256 QString relativeMediaPath() const; 0257 0258 /** 0259 Returns a modifiable RenderContext. This may be used to make 0260 Template rendering threadsafe so that render state does not need to be 0261 stored in the Node implementation itself. 0262 */ 0263 RenderContext *renderContext() const; 0264 0265 private: 0266 Q_DECLARE_PRIVATE(Context) 0267 ContextPrivate *const d_ptr; 0268 }; 0269 } 0270 0271 #endif