This guide demonstrates how to set up multiple collections in md0 CMS for a complete website with blog posts, documentation, pages, team members, and more using the visual collection builder.
Use Case
A company website with:
- Marketing pages
- Blog with multiple categories
- Documentation
- Team member profiles
- Case studies
- Product pages
Repository Structure
First, create this folder structure in your GitHub repository:
company-site/
├── content/
│ ├── pages/
│ │ ├── about.md
│ │ ├── contact.md
│ │ └── pricing.md
│ ├── blog/
│ │ ├── getting-started-guide.md
│ │ ├── new-feature-announcement.md
│ │ └── team-update.md
│ ├── team/
│ │ ├── jane-doe.md
│ │ └── john-smith.md
│ └── products/
│ ├── product-a.md
│ └── product-b.md
└── public/
└── images/
Note: Currently, md0 CMS supports single-folder patterns (e.g.,
content/blog/*.md). Nested folder support (e.g.,content/blog/**/*.md) is coming soon.
Creating Collections in md0 CMS
Collection 1: Pages
Static marketing pages.
- Go to Collections → Create Collection
- Fill in the basic info:
- Name: Pages
- Path:
content/pages/*.md - Description: Marketing and informational pages
- Click Add Field to create the schema:
- title (Text, Required)
- description (Long Text, Required)
- hero (Group)
- title (Text)
- subtitle (Long Text)
- image (Image)
- cta_text (Text)
- cta_link (Text)
- seo (Group)
- meta_title (Text)
- meta_description (Long Text)
- Click Save Collection
Collection 2: Blog Posts
Blog articles in a single folder.
- Collections → Create Collection
- Basic info:
- Name: Blog Posts
- Path:
content/blog/*.md - Description: Blog articles, news, and tutorials
- Add fields:
- title (Text, Required)
- date (Date, Required, Default: Today)
- excerpt (Long Text, Required)
- author (Text, Required)
- category (Select, Required)
- Options: News, Tutorials, Case Studies, Company Updates
- tags (List of Text)
- featured_image (Image)
- published (Toggle, Default: Off)
- Save Collection
Collection 3: Team Members
Employee profiles.
- Collections → Create Collection
- Basic info:
- Name: Team Members
- Path:
content/team/*.md - Description: Team member profiles and bios
- Add fields:
- name (Text, Required)
- role (Text, Required)
- department (Select)
- Options: Engineering, Design, Marketing, Sales, Support
- bio (Long Text, Required)
- avatar (Image, Required)
- email (Email)
- social (Group)
- twitter (Text)
- linkedin (Text)
- github (Text)
- order (Number, Default: 0, Help: "Display order on team page")
- Save Collection
Collection 4: Products
Product pages.
- Collections → Create Collection
- Basic info:
- Name: Products
- Path:
content/products/*.md - Description: Product information and features
- Add fields:
- name (Text, Required)
- tagline (Text, Required)
- description (Long Text, Required)
- price (Group)
- monthly (Number)
- annual (Number)
- currency (Text, Default: "USD")
- features (List of Text)
- gallery (List of Images)
- status (Select)
- Options: Active, Beta, Coming Soon, Deprecated
- Save Collection
Example Content
Page Example
content/pages/about.md
---
title: "About Us"
description: "Learn about our mission, values, and the team behind the product."
hero:
title: "We're building the future of content management"
subtitle: "A team of developers and designers passionate about making content management simple."
image: "/images/team-photo.jpg"
cta_text: "Meet the Team"
cta_link: "/team"
seo:
meta_title: "About md0 CMS - Our Mission and Team"
meta_description: "Learn about md0 CMS, our mission to simplify content management, and the team making it happen."
---
# About md0 CMS
We believe content management should be simple...
Blog Post Example
content/blog/getting-started-guide.md
---
title: "Getting Started with md0 CMS"
date: 2024-01-15
excerpt: "Learn how to set up md0 CMS in under 5 minutes."
author: "Jane Doe"
category: "Tutorials"
tags: ["beginner", "setup", "quickstart"]
featured_image: "/images/blog/getting-started.jpg"
published: true
---
# Getting Started with md0 CMS
In this tutorial, we'll walk through...
Team Member Example
content/team/jane-doe.md
---
name: "Jane Doe"
role: "Head of Engineering"
department: "Engineering"
bio: "Jane leads our engineering team with 10+ years of experience in web development and content management systems."
avatar: "/images/team/jane-doe.jpg"
email: "jane@company.com"
social:
twitter: "janedoe"
linkedin: "janedoe"
github: "janedoe"
order: 1
---
Jane has been building web applications for over a decade...
Product Example
content/products/pro-plan.md
---
name: "Pro Plan"
tagline: "For growing teams and businesses"
description: "Everything in Free, plus advanced features for teams."
price:
monthly: 49
annual: 490
currency: "USD"
features:
- "Unlimited repositories"
- "Team collaboration"
- "Priority support"
- "Advanced schemas"
- "Custom integrations"
gallery:
- "/images/products/pro-dashboard.jpg"
- "/images/products/pro-editor.jpg"
status: "Active"
---
# Pro Plan Features
The Pro Plan is designed for...
Collection Organization Tips
By Content Type
Separate by what the content represents:
- Pages → Static content
- Blog → Time-based content
- Team → People profiles
- Products → Product info
By Workflow
Separate by how content is managed:
- Published content
- Draft content
- Archived content
By Access Level
Separate by who can edit:
- Public content
- Internal content
- Restricted content
Querying Multiple Collections
In Next.js
// Get all content types
const pages = getAllContent("pages");
const posts = getAllContent("blog");
const team = getAllContent("team");
const products = getAllContent("products");
// Homepage data
export async function getStaticProps() {
return {
props: {
featuredPosts: posts.filter((p) => p.published).slice(0, 3),
teamMembers: team.sort((a, b) => a.order - b.order),
products: products.filter((p) => p.status === "Active"),
},
};
}
In Gatsby
export const query = graphql`
query HomePage {
blogPosts: allMarkdownRemark(
filter: { fileAbsolutePath: { regex: "/blog/" } }
sort: { frontmatter: { date: DESC } }
limit: 3
) {
nodes {
frontmatter {
title
excerpt
}
}
}
teamMembers: allMarkdownRemark(
filter: { fileAbsolutePath: { regex: "/team/" } }
sort: { frontmatter: { order: ASC } }
) {
nodes {
frontmatter {
name
role
avatar
}
}
}
}
`;
Cross-Referencing
Linking Between Collections
# In blog post
related_products:
- "pro-plan"
- "enterprise-plan"
# In blog post
author_profile: "jane-doe"
Query related content:
const post = await getPost(slug);
const relatedProducts = await Promise.all(
post.related_products.map((id) => getProduct(id))
);
Collection Relationships
One-to-Many
Blog posts → Author (one author, many posts)
# In blog post
author_id: "jane-doe"
Many-to-Many
Blog posts → Tags (many posts, many tags)
# In blog post
tags: ["javascript", "tutorial", "beginner"]
Nested Content
Products → Features
# In product
features:
- title: "Advanced Editor"
description: "Visual markdown editing"
image: "/images/features/editor.jpg"
Best Practices
Consistent Schemas
Reuse field patterns:
# SEO fields (reuse in multiple collections)
seo:
meta_title: string
meta_description: text
keywords: array
Clear Naming
Use descriptive collection names:
- "Blog Posts" not "Posts"
- "Team Members" not "Team"
- "Documentation" not "Docs"
Logical Paths
Match collection paths to content types:
content/blog/*.md → Blog Posts
content/team/*.md → Team Members
content/products/*.md → Products
Order Fields
Add order field to sortable collections:
order: number (for custom sorting)
Troubleshooting
Collection Overlap
If collections overlap (same path pattern):
- Make patterns more specific
- Use exclusion patterns
- Reorganize file structure
Too Many Collections
If managing becomes complex:
- Combine related collections
- Use categories instead
- Simplify structure
Performance
For large sites (1000+ files):
- Use specific path patterns
- Split into smaller collections
- Consider pagination
Next Steps
- Collection Patterns - Advanced patterns
- Schema Configuration - Schema details
- Markdown Editing - Content editing