---
title: Creating macro namespaces
related:
  - https://docs.kentico.com/13/macro-expressions/extending-the-macro-engine/registering-custom-macro-methods.md
  - https://docs.kentico.com/13/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.

> **Note:** **Adding macro namespaces for the live site**
>
> Deploy all customizations described below to both your Xperience administration project and the separate live site application. This ensures that the custom macros are available in both applications.
>
> For more information, see [Applying customizations in the Xperience environment](https://docs.kentico.com/13/custom-development/applying-customizations-in-the-xperience-environment.md).

To add a custom macro namespace:

1. Create a class inheriting from **MacroNamespace**. Add the class as part of a custom assembly (_Class Library_ project).
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/13/macro-expressions/extending-the-macro-engine/registering-custom-macro-methods.md) and [Adding custom macro fields](https://docs.kentico.com/13/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 (typically the global resolver).

We recommend registering your macro namespaces at the beginning of the application's life cycle (during initialization). The following steps describe how to register a macro namespace into the global resolver:

1. Create a [custom module class](https://docs.kentico.com/13/custom-development/creating-custom-modules/initializing-modules-to-run-custom-code.md).
   - Add the class into a custom _Class Library_ project (assembly).

> **Info:** For basic execution of initialization code, you only need to register a "code-only" module through the API. You do NOT need to create a new module within the **Modules** application in the Xperience administration interface.

2. Override the module's **OnInit** method.
3. 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;
using CMS.Base;
using CMS.DataEngine;
using CMS.MacroEngine;

// Registers the custom module into the system
[assembly: RegisterModule(typeof(CustomMacroModule))]

public class CustomMacroModule : Module
{
    // Module class constructor, the system registers the module under the name "CustomMacros"
    public CustomMacroModule()
        : base("CustomMacros")
    {
    }

    // Contains initialization code that is executed when the application starts
    protected override void OnInit()
    {
        base.OnInit();

        // 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.
