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