Skip to main content
Glama

createPage

Create new pages in Adobe Experience Manager by specifying parent path, title, and template for structured content management.

Instructions

Create a new page in AEM

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
parentPathYes
titleYes
templateYes
nameNo
propertiesNo

Implementation Reference

  • Core implementation of createPage tool: validates input, auto-selects template, creates cq:Page and jcr:content nodes via Sling POST, verifies creation and accessibility.
    async createPage(request) {
        return safeExecute(async () => {
            const { parentPath, title, template, name, properties = {} } = request;
            if (!isValidContentPath(parentPath)) {
                throw createAEMError(AEM_ERROR_CODES.INVALID_PARAMETERS, `Invalid parent path: ${String(parentPath)}`, { parentPath });
            }
            // Auto-select template if not provided
            let selectedTemplate = template;
            if (!selectedTemplate) {
                const templatesResponse = await this.getTemplates(parentPath);
                const availableTemplates = templatesResponse.data.availableTemplates;
                if (availableTemplates.length === 0) {
                    throw createAEMError(AEM_ERROR_CODES.INVALID_PARAMETERS, 'No templates available for this path', { parentPath });
                }
                selectedTemplate = availableTemplates[0].path;
                this.logger.info(`Auto-selected template: ${selectedTemplate}`);
            }
            // Validate template exists
            try {
                await this.httpClient.get(`${selectedTemplate}.json`);
            }
            catch (error) {
                if (error.response?.status === 404) {
                    throw createAEMError(AEM_ERROR_CODES.INVALID_PARAMETERS, `Template not found: ${selectedTemplate}`, { template: selectedTemplate });
                }
                throw handleAEMHttpError(error, 'createPage');
            }
            const pageName = name || title.replace(/[^a-zA-Z0-9-_]/g, '-').toLowerCase();
            const newPagePath = `${parentPath}/${pageName}`;
            // Create page with proper structure
            const pageData = {
                'jcr:primaryType': 'cq:Page',
                'jcr:content': {
                    'jcr:primaryType': 'cq:PageContent',
                    'jcr:title': title,
                    'cq:template': selectedTemplate,
                    'sling:resourceType': 'foundation/components/page',
                    'cq:lastModified': new Date().toISOString(),
                    'cq:lastModifiedBy': 'admin',
                    ...properties
                }
            };
            // Create the page using Sling POST servlet
            const formData = new URLSearchParams();
            formData.append('jcr:primaryType', 'cq:Page');
            // Create page first
            await this.httpClient.post(newPagePath, formData, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            });
            // Then create jcr:content node
            const contentFormData = new URLSearchParams();
            Object.entries(pageData['jcr:content']).forEach(([key, value]) => {
                if (key === 'jcr:created' || key === 'jcr:createdBy') {
                    return;
                }
                if (typeof value === 'object') {
                    contentFormData.append(key, JSON.stringify(value));
                }
                else {
                    contentFormData.append(key, String(value));
                }
            });
            await this.httpClient.post(`${newPagePath}/jcr:content`, contentFormData, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            });
            // Verify page creation
            const verificationResponse = await this.httpClient.get(`${newPagePath}.json`);
            const hasJcrContent = verificationResponse.data['jcr:content'] !== undefined;
            // Check if page is accessible in author mode
            let pageAccessible = false;
            try {
                const authorResponse = await this.httpClient.get(`${newPagePath}.html`, {
                    validateStatus: (status) => status < 500
                });
                pageAccessible = authorResponse.status === 200;
            }
            catch (error) {
                pageAccessible = false;
            }
            return createSuccessResponse({
                pagePath: newPagePath,
                title,
                templateUsed: selectedTemplate,
                jcrContentCreated: hasJcrContent,
                pageAccessible,
                errorLogCheck: {
                    hasErrors: false,
                    errors: []
                },
                creationDetails: {
                    timestamp: new Date().toISOString(),
                    steps: [
                        'Template validation completed',
                        'Page node created',
                        'jcr:content node created',
                        'Page structure verified',
                        'Accessibility check completed'
                    ]
                },
                pageStructure: verificationResponse.data
            }, 'createPage');
        }, 'createPage');
    }
  • MCP handler registration: dispatches createPage calls to AEMConnector.createPage in the handleRequest switch statement.
    case 'createPage':
        return await this.aemConnector.createPage(params);
  • Tool schema definition in getAvailableMethods(): defines name, description, and parameters for the createPage tool.
    { name: 'createPage', description: 'Create a new page in AEM', parameters: ['parentPath', 'title', 'template', 'name', 'properties'] },
  • Wrapper method in AEMConnector that delegates createPage to PageOperations module.
    async createPage(request) {
        return this.pageOps.createPage(request);
  • TypeScript interface definition for createPage method signature and return type.
    createPage(request: any): Promise<import("./interfaces/index.js").PageResponse>;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/indrasishbanerjee/aem-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server