---
title: Creating macro namespaces
related:
  - https://docs.kentico.com/k81/macro-expressions/extending-the-macro-engine/registering-custom-macro-methods.md
  - https://docs.kentico.com/k81/macro-expressions/extending-the-macro-engine/adding-custom-macro-fields.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

Macro namespaces serve as containers for static macro methods and fields. Users can access the members of namespaces when writing macro expressions, for example _{% Math.Pi %}_ or _{% _Math.Log(x)_ %}_. Namespaces also appear in the macro autocomplete help. The system uses several default namespaces such as _Math_, _String_ or _Util_, and you can create your own namespaces for custom macros.

To add a custom macro namespace:

1. Create a class inheriting from **MacroNamespace**. In _web site_ projects, you can either add the class into the **App\_Code** folder or as part of a custom assembly.
2. Register macro fields or methods into the namespace — add **Extension** attributes to the class, with the types of the appropriate container classes as parameters.

```csharp

using CMS.Base;
using CMS.MacroEngine;

[Extension(typeof(CustomMacroFields))]
[Extension(typeof(CustomMacroMethods))]
public class CustomMacroNamespace : MacroNamespace<CustomMacroNamespace>
{
}

```

See [Registering custom macro methods](https://docs.kentico.com/k81/macro-expressions/extending-the-macro-engine/registering-custom-macro-methods.md) and [Adding custom macro fields](https://docs.kentico.com/k81/macro-expressions/extending-the-macro-engine/adding-custom-macro-fields.md) to learn about creating container classes for macro fields and methods.

## Registering macro namespaces

Once you have defined the macro namespace class, you need to register the namespace as a source into a [macro resolver](https://docs.kentico.com/k81/macro-expressions/extending-the-macro-engine.md) (typically the global resolver).

We recommend registering your macro namespaces at the beginning of the application's life cycle. Choose one of the following options:

- During the initialization process of the application itself — use the **CMSModuleLoader** partial class in the **App\_Code** folder.
- When initializing [custom modules](https://docs.kentico.com/k81/custom-development/creating-custom-modules/initializing-modules-to-run-custom-code.md) — override the **OnInit** method of the module class.

The following steps describe how to register a macro namespace into the global resolver using the App\_Code folder:

1. Create a class file in the **App\_Code** folder (or **CMSApp\_AppCode -> Old\_App\_Code** on web application projects).
2. Extend the **CMSModuleLoader** [partial class](http://msdn.microsoft.com/en-us/library/wa80x488%28v=vs.80%29.aspx).
3. Create a new class inside _CMSModuleLoader_ that inherits from **CMSLoaderAttribute**.
4. Add the attribute defined by the internal class before the definition of the _CMSModuleLoader_ partial class.
5. Override the **Init** method inside the attribute class.
6. Call the **SetNamedSourceData** method for the global resolver with the following parameters:

   - A string that sets the visible name of the namespace (used in macro syntax).
   - An instance of your macro namespace class.
   - (Optional) By default, the registered namespace appears in the high priority section of the autocomplete help and macro tree. To add namespaces with normal priority, add **false** as the third parameter.

```csharp

using CMS.Base;
using CMS.MacroEngine;

[MacroNamespaceLoader]
public partial class CMSModuleLoader
{
    /// <summary>
    /// Attribute class that ensures the registration of custom macro namespaces.
    /// </summary>
    private class MacroNamespaceLoaderAttribute : CMSLoaderAttribute
    {
        /// <summary>
        /// Called automatically when the application starts.
        /// </summary>
        public override void Init()
        {
            // Registers "CustomNamespace" into the macro engine
            MacroContext.GlobalResolver.SetNamedSourceData("CustomNamespace", CustomMacroNamespace.Instance);
        }
    }
}

```

The system registers your custom macro namespace when the application starts. Users can access the namespace's members when writing macro expressions.

### Registering namespaces as anonymous sources

By registering a macro namespace as an anonymous source, you can allow users to access the namespace's members directly without writing the namespace as a prefix. For example, _{% Field %}_ instead of _{% Namespace.Field %}_.

```csharp

// Registers "CustomNamespace" as an anonymous macro source
MacroContext.GlobalResolver.AddAnonymousSourceData(CustomMacroNamespace.Instance);

```

You can register the same namespace as both a named and anonymous source. If you only register a namespace as an anonymous source, users cannot access the members using the prefix notation, and the namespace does not appear in the macro autocomplete help.

> **Note:** **Note**: Data items registered through anonymous macro sources do NOT appear in the macro autocomplete help. As a result, the autocomplete help only displays namespace members when using the prefix notation, even when the namespace is registered as both a named and anonymous source.
