SDKs
Learn how to update Agility Containers and Lists programmatically using JavaScript.
This page has moved โ the Management SDK is now documented elsewhere. The JavaScript and .NET guides have been merged into a single set with per-language code tabs. Read the current guide.
This guide covers container operations using the Agility Management SDK, including creating, managing, and organizing content containers (content lists).
Containers (also called Content Views) are collections that hold content items of a specific model type. They act as the "lists" that organize your content. They can also be made to hold just a single item.
// Container links content model to content items
Content Model (blog-posts) โ Container (posts) โ Content Items// Get list of all containers
const containers = await apiClient.containerMethods.getContainerList(guid);
containers.forEach(container => {
console.log(`Container: ${container.referenceName}`);
console.log(`- Model ID: ${container.contentDefinitionID}`);
console.log(`- Container ID: ${container.contentViewID}`);
});// Get specific container by ID
const container = await apiClient.containerMethods.getContainerByID(
contentViewID, // Container ID
guid // Instance GUID
);
console.log('Container details:', container);// Primary method for finding containers
const container = await apiClient.containerMethods.getContainerByReferenceName(
'posts', // Container reference name
guid // Instance GUID
);
if (container) {
console.log('Found container:', container.referenceName);
} else {
console.log('Container not found');
}// First, get the content model
const model = await apiClient.modelMethods.getModelByReferenceName('blog-posts', guid);
if (!model) {
throw new Error('Content model not found');
}
// Create container payload
const containerPayload = {
contentViewID: -1, // -1 for new containers
referenceName: 'posts',
contentDefinitionID: model.id, // Link to model
contentDefinitionType: 1, // Content type
contentDefinitionTypeID: model.id
};
// Save container
const savedContainer = await apiClient.containerMethods.saveContainer(
containerPayload,
guid,
false // forceReferenceName
);
console.log('Created container:', savedContainer.referenceName);const advancedContainer = {
contentViewID: -1,
referenceName: 'featured-posts',
contentDefinitionID: model.id,
contentDefinitionType: 1,
contentDefinitionTypeID: model.id,
settings: {
defaultSort: 'publishDate',
defaultSortDirection: 'desc',
itemsPerPage: 10
}
};
const container = await apiClient.containerMethods.saveContainer(
advancedContainer,
guid,
true // Force specific reference name
);// Get existing container
const existingContainer = await apiClient.containerMethods.getContainerByReferenceName(
'posts',
guid
);
if (existingContainer) {
// Update properties
existingContainer.displayName = 'Updated Posts Container';
existingContainer.description = 'Updated description';
// Save updates
const updatedContainer = await apiClient.containerMethods.saveContainer(
existingContainer,
guid,
false
);
console.log('Updated container:', updatedContainer.referenceName);
}// Get new model
const newModel = await apiClient.modelMethods.getModelByReferenceName('articles', guid);
// Update container to use new model
existingContainer.contentDefinitionID = newModel.id;
existingContainer.contentDefinitionTypeID = newModel.id;
// Save changes
await apiClient.containerMethods.saveContainer(existingContainer, guid, false);
console.log('Container now uses new model');// Delete by container ID
await apiClient.containerMethods.deleteContainer(contentViewID, guid);
console.log('Container deleted successfully');async function safeDeleteContainer(containerName: string, guid: string, locale: string) {
try {
// Get container
const container = await apiClient.containerMethods.getContainerByReferenceName(
containerName,
guid
);
if (!container) {
console.log('Container not found');
return false;
}
// Check for existing content
const contentList = await apiClient.contentMethods.getContentList(
containerName,
guid,
locale,
null
);
if (contentList.length > 0) {
console.warn(`Cannot delete container - contains ${contentList.length} content items`);
return false;
}
// Safe to delete
await apiClient.containerMethods.deleteContainer(container.contentViewID, guid);
console.log('Container deleted successfully');
return true;
} catch (error) {
console.error('Error deleting container:', error);
return false;
}
}function validateContainer(container: any): string[] {
const errors: string[] = [];
if (!container.referenceName) {
errors.push('Reference name is required');
}
if (!container.contentDefinitionID || container.contentDefinitionID <= 0) {
errors.push('Valid content definition ID is required');
}
// Check reference name format
if (container.referenceName && !/^[a-z][a-z0-9-]*$/.test(container.referenceName)) {
errors.push('Reference name must be lowercase, start with letter, and contain only letters, numbers, and hyphens');
}
return errors;
}
// Usage
const errors = validateContainer(containerPayload);
if (errors.length > 0) {
console.error('Container validation failed:', errors);
} else {
// Proceed with save
}async function createContainerForModel(
modelReferenceName: string,
containerReferenceName: string,
guid: string
) {
// Get the model
const model = await apiClient.modelMethods.getModelByReferenceName(
modelReferenceName,
guid
);
if (!model) {
throw new Error(`Model '${modelReferenceName}' not found`);
}
// Check if container already exists
const existingContainer = await apiClient.containerMethods.getContainerByReferenceName(
containerReferenceName,
guid
);
if (existingContainer) {
console.log('Container already exists:', existingContainer.referenceName);
return existingContainer;
}
// Create new container
const containerPayload = {
contentViewID: -1,
referenceName: containerReferenceName,
contentDefinitionID: model.id,
contentDefinitionType: 1,
contentDefinitionTypeID: model.id
};
const container = await apiClient.containerMethods.saveContainer(
containerPayload,
guid,
true
);
console.log(`Created container '${container.referenceName}' for model '${model.referenceName}'`);
return container;
}async function createMultipleContainers(
containerConfigs: Array<{
containerName: string;
modelName: string;
}>,
guid: string
) {
const results = [];
for (const config of containerConfigs) {
try {
const container = await createContainerForModel(
config.modelName,
config.containerName,
guid
);
results.push({
success: true,
containerName: config.containerName,
modelName: config.modelName,
containerID: container.contentViewID
});
} catch (error) {
results.push({
success: false,
containerName: config.containerName,
modelName: config.modelName,
error: error.message
});
}
}
return results;
}
// Usage
const containerConfigs = [
{ containerName: 'posts', modelName: 'blog-posts' },
{ containerName: 'pages', modelName: 'static-pages' },
{ containerName: 'products', modelName: 'product-catalog' }
];
const results = await createMultipleContainers(containerConfigs, guid);
console.log('Container creation results:', results);// โ
Good: Clear, consistent naming
const goodContainerNames = [
'blog-posts', // Matches model name
'featured-posts', // Descriptive purpose
'product-catalog', // Clear function
'news-articles' // Descriptive content
];
// โ Avoid: Unclear or inconsistent naming
const badContainerNames = [
'container1', // Not descriptive
'BlogPosts', // Inconsistent casing
'posts_list', // Mixed conventions
'p' // Too short
];// Organize containers by purpose
const containerStructure = {
content: ['posts', 'articles', 'news'],
products: ['catalog', 'featured-products', 'categories'],
pages: ['static-pages', 'landing-pages'],
media: ['images', 'documents', 'videos']
};
// Create organized container hierarchy
async function createOrganizedContainers(guid: string) {
for (const [category, containers] of Object.entries(containerStructure)) {
console.log(`Creating ${category} containers...`);
for (const containerName of containers) {
// Implementation depends on your model structure
await createContainerForModel(`${category}-model`, containerName, guid);
}
}
}