Package Development Guidelines
How to name, compose, organize, code, document, and test Marketpath CMS packages.
These guidelines apply to every Marketpath CMS package. They aim for packages that are small, predictable, and safe to install and update on sites you do not control. Marketpath Site Standards 1 (MPSS1) builds on them, so a package that follows MPSS1 should also follow these guidelines.
Package Naming and Standards
Give each package a descriptive unique name with a short identifier, and declare the standard it follows with a standard label.
Packages should have descriptive and unique names. For asset organization it helps for a package with a long name to also have a unique shortened identifier (for example, "Personal Portfolio Site" by Marketpath becomes "mp-pps1"). Use kebab-case for all paths so they stay consistent.
Where applicable, a package should conform to a predefined set of standards and identify it with the "standard" label (for example, standard:mpss1-bootstrap5). Packages that share a standard can guarantee interoperability to the greatest extent reasonably possible. Marketpath Site Standards 1 (MPSS1) is an example of such a standard.
Package Composition and Types
Break large packages into smaller single-purpose packages, and choose the package type that matches what the package delivers.
Wherever possible, break large packages into smaller component packages. This centralizes the creation and maintenance of components used by many packages, which improves both the quality and the build time of new sites and packages. It only works if each package used is high quality and follows these guidelines. Only assets specific to the current package should be unique to it.
Full site
• Use only for packages that can and should be installed when a site is first created. A full site package must also follow the full site requirements below.
• Generally includes numerous packages of every other type (but no other full site packages), plus every asset on the site that is not part of another package.
Page
• Use for packages with a small number of page templates (ideally one, though bundling several sometimes makes sense) and their related assets such as javascript and stylesheets. Keep them as lightweight as possible while still complete.
• Do not include sample pages. Describe the sample on the package's demo or documentation page instead, which keeps the package reusable inside full site packages.
• Generally includes several widget packages, and possibly others.
Widget
• Use for packages that add a visible widget to a site, such as pagination, a banner, a CTA, a blogroll, or a tag cloud. A widget does nothing on its own; another template must include it, usually with some configuration, before it outputs anything.
• Typically includes one or more component packages, and possibly a data package.
Form
• Use for packages with a small number of form templates (ideally one) and their related assets. Keep them as lightweight as possible while still complete.
• Do not include a sample form. Describe it on the package's demo or documentation page instead.
• Generally includes one or more component packages.
• Test form templates with every field type, condition, and validation option.
• Form packages should generally auto-update by default, which makes form maintenance easier for everyone. That also means a form package must not be updated until the update is thoroughly tested.
Gallery
• Use for packages with a small number of gallery templates (ideally one) and their related assets. Keep them as lightweight as possible while still complete.
• Do not include a sample gallery. Describe it on the package's demo or documentation page instead.
• Generally includes one or more component packages.
Data
• Use for packages of reusable data or configuration, such as a reusable datastore definition, a reusable list of objects (for example, US states), or a snippet to include in the header or footer of many sites.
• Does not typically include other packages, and includes only the fewest assets its purpose needs.
Component
• Use for packages of reusable building blocks such as partials and javascript libraries. A component does nothing on its own; it must be used according to its instructions. Ideally each component package accomplishes a single purpose.
• May include other component or data packages, but is often the smallest unit, containing only the assets and packages its single purpose requires.
Full Site Package Requirements
What a full site (theme) package must include and clean up: shared UI components, a complete set of templates, branding, SEO, one domain, styling, and mobile support.
Full site packages carry extra requirements because every site created from them starts with their contents.
Common UI components
Include common UI components as partial templates so developers can change the site and add new sections easily. Ideally these come from reputable packages, though some may be custom to the site. Common components include:
• Menus and navigation
• Banners
• Buckets and cards
• Galleries and carousels
• Form and table elements and filters
• Accordions and tabs
• Related and recent content
• Any other element repeated on the site
A common approach is to start with two templates: one for the UI component that takes raw data as input, and a second that fetches the data and includes the UI component template.
Completeness
A full site package should have everything a developer needs to get started. At a minimum:
• A form component template (from a package)
• A gallery component template (from a package)
• A specialized template for each entity type: blog, tag, author, and folder; article and blog post; calendar; calendar entry; document and image; form and gallery
• A generic template
• A home page template
• A landing page template
• A 404 error page
• A catch-all error page
• A search page, or at least a working search template
• A contact page with a working contact form
• A sitemap.xml file
• A robots.txt file
Marketpath branding
Although it is not enforced for third-party themes, every site's footer should include "Powered by Marketpath CMS", linked to https://www.marketpath.com, optionally with the Marketpath logo in place of the words "Marketpath CMS".
Clean
Sites commonly contain old assets that are no longer used. Before creating a full site package, trash old assets so new sites do not start with extra clutter. Find candidates under All Content, Filters, Not Referenced. Some unreferenced items are fine (robots.txt, sitemap.xml, landing pages), and some content is pulled in dynamically by templates (for example, images by tag), so do not trash everything listed. Also review menus, snippets, image presets, custom site settings, and custom profile settings.
SEO
Keeping a site clean includes setting Include in Search correctly on every page. Leave it checked for most pages, but uncheck it for pages that should not appear in on-site search results, such as meta pages, private pages, thank-you pages, and pages driven by query parameters. For pages without Include in Search, also set Meta Robots, which for most means "noindex, nofollow".
Domains
A full site package should have a single active domain, typically a development domain. Multiple domains on the source site are combined into one when the package is installed on a new site.
Free plan compatibility
A theme that may be offered as a free site must have fewer than 20 pages (URLs). To keep the page count down:
1. For tags, authors, folders, blog posts, calendar entries, and datastore items without a URL, link to a generic page that loads the entity from a query parameter. Do not link to items (such as folders) that do not need it.
2. For forms, show the thank-you message on the same page as the form, using AJAX or a query parameter.
3. Limit the meta pages the site needs, such as JSON, XML, or RSS feeds.
The 20-page limit suits very simple sites. If you struggle with it, consider whether the site should be a paid site. If you are creating a paid full site package, contact Marketpath about going live with the source or demo site for free.
Styling
Style every theme with SCSS or LESS and use customizable variables wherever possible, most importantly for colors and font styles, so sites built from the theme are easier to customize.
Mobile friendly
Usually through responsive markup, though other approaches are acceptable. Mobile-first design is preferred but not required. Check every relevant component for mobile responsiveness.
Package Organization and Asset Paths
Organize folders, sample content, and asset paths by company, package, version, and asset type, and never rename an asset once the package is active.
A site is easier to maintain with a clear organizational structure. Use folders and paths that make sense, are intuitive, and are consistent between assets, packages, and sites.
Sample content and install-only content
• Start the Name (not the Title) of all sample content with "SAMPLE: " unless it must be named differently for a specific reason.
• Place sample content under a folder called "samples", and sample images under "samples/images", unless they must be elsewhere for a specific reason.
• Include content that is not central to the package's function as Install Only, so editors can change it without fear that an update will overwrite their changes, and so updates stay simple. This applies doubly to folders.
• Wherever possible, restrict folders and templates to specific entity types so users find the right folder or template while creating content. Also set default root paths for folders, blogs, and datastores, and set default templates, such as the template for blog posts.
Asset paths and naming
Organize templates, javascript, and stylesheets by company, package name, and asset type.
• Start every path with your lowercase company name (for example, "marketpath") followed by the package identifier (for example, "mp-pps1").
• If a package includes more than one version, follow the package identifier with the version number. Including a version number in the first release often makes future updates easier.
• Put javascript under a "js" path and stylesheets under a "css" path.
• Use other sub-paths only when the package has many assets, or when you copy assets from another source and keep its file organization.
• Start the names of assets consumed by other assets (partial templates, SCSS partials, non-compiled javascript) with an underscore, for example _partial.liquid.
• End asset names in an appropriate extension, such as .liquid, .txt, .js, .css, .scss, or .less.
Examples:
• /marketpath/superbanner/v1/_banner.liquid
• /marketpath/superbanner/v1/js/mpbanner.js
• /marketpath/superbanner/v1/js/_mpbanner.js
• /marketpath/logisticall/home.liquid
• /marketpath/logisticall/contact.liquid
• /marketpath/logisticall/_sidebar.liquid
• /marketpath/logisticall/_menu.liquid
• /marketpath/logisticall/css/main.scss
• /marketpath/logisticall/js/main.js
Consider keeping overrides under a different root path, for example /overrides/marketpath/superbanner/v1.
If javascript or stylesheet assets come from another source (git, a third-party website), keep the original file structure and naming under the relevant root path.
Do not change template, javascript, or stylesheet names or paths once the package is activated, so other developers can reuse your assets without fear that an update will break their code.
Package Code Standards
Keep original package code simple, consistently named, and scoped: vanilla javascript where practical, versioned third-party libraries, and customizable partial stylesheets.
Code standards apply only to original code. Backporting new standards onto existing third-party code is impractical, improper, and unhelpful.
General
• Do not get fancy unless it is clearly called for. Fancy code takes more time, has more bugs, and needs more maintenance. If you need it, put it in its own package with clear documentation.
• Use full, descriptive names for functions, mixins, filenames, and variables, and use indentation to group code visually.
• Follow one consistent methodology inside a package or group of packages. If one component uses BEM class names, use them everywhere, and do not mix variable naming schemes (for example, $primary-color, $orange, and $color-theme-background).
Javascript
• When writing small amounts of javascript, prefer vanilla javascript over a framework so the code is portable and reusable. Good: document.getElementById("menubtn").addEventListener("click", doSomething); Bad: jQuery("#menubtn").click(doSomething);
• If a framework genuinely helps with a lot of javascript, use it, but put the framework in its own package and reference that package rather than bundling it into your javascript files.
• Include a version number in the path or filename of every third-party library. First-party code may optionally include one. Usually only the major version is needed, as long as minor updates are backwards compatible.
• Scope functions and variables to a single global object (or a small number of them) with a name unique enough to avoid conflicts. Writing code inside an IIFE helps avoid polluting the global scope. Good: marketpath_maps.init() Bad: init_maps()
• End every javascript asset in .js.
Stylesheets
• When copying stylesheets from a third-party library, keep the library's original type: CSS stays CSS, SCSS stays SCSS.
• For your own stylesheets, use SCSS or LESS, which are easier to customize, and consider splitting them into partial stylesheets imported by a main stylesheet.
• Mark partial stylesheets as not compiled.
• Do not hide visual indicators such as bullets in editable content areas, which makes content hard to edit. Light or white text is also hard to see in a content area; when it is needed, add a CSS override for body.cke_editable so text stays visible in the HTML editor.
• End every stylesheet asset in .css, .less, .scss, or .sass.
Package Template Standards
Keep package templates few, restricted by entity type, DRY, documented at the top, and include CSS and javascript so consumers can bundle or disable it.
Templates should be clean, well organized, and labeled intuitively.
Templates
• Limit the number of page templates and restrict each to the entity types it should be used with. Ideally each page template is restricted to a single entity type, which makes creating new pages easier.
• Where possible, add an image to each page template that shows what a page built with it looks like once the package is installed.
• Break partial templates into logically organized templates for each section of the site, and keep them DRY ("Don't Repeat Yourself") wherever reasonable. Partials for common functionality work almost like reusable functions.
• Open every template with the contract comment described in Template Best Practices. For a package, the comment should also list the CSS and javascript assets the template requires, any CSS or javascript framework it relies on (such as Bootstrap), and any override or customization options.
• Follow Variable Scopes when choosing between var, set, and assign. When a package does write a variable to the root scope with assign, give it a name unique enough to avoid collisions and describe it in the package documentation.
• End every template asset in .html, .liquid, .txt, or another extension that makes sense for the asset.
Including CSS and javascript
Add all CSS and javascript to the page with {% add_javascript %} and {% add_stylesheet %}. Adding the same file more than once is fine, because the page outputs it only once. Clearly document how to customize or disable your javascript and stylesheets.
When a template includes javascript or stylesheets, make every reasonable effort to ensure that:
1. You include only the minimum code needed for the package to look and behave correctly: no unnecessary code or placeholders, and no compiling an entire CSS or javascript framework for a few small members.
2. The code works when included more than once on a page. Do not rely on unique ids unless you can reasonably guarantee the id appears once in the DOM.
3. A consumer can easily include your scripts and styles in the site's main javascript and stylesheet instead of from within your component.
Good: {% unless exclude_component_css %}{% add_stylesheet "/developer/v1/component.scss" %}{% endunless %}
Bad: {% add_stylesheet "/developer/v1/component.scss" %}
To make it easy to bundle your styles into the main site stylesheet, create two stylesheets for each component, one compiled and one partial. The compiled stylesheet includes the dependencies (such as variables and frameworks) and the partial. The partial holds only the styles, assumes the variables are declared, and opens with a comment describing what it requires. For example:
• /developer/v1/component.scss (compiled) includes "/_variables.scss" and then "_component.scss"
• /developer/v1/_component.scss (partial) opens with a comment such as "Depends on variables defined in the _variables.scss file", followed by the component's rules
Package Documentation and Customization
Publish developer documentation, editor instructions, and a demo for each package, and make it customizable without overriding its core assets.
Documentation
Each package should have:
• A publicly accessible documentation page for developers
• Site Instructions for editors, if applicable
• A publicly accessible demo page, if possible
In particular, note any functionality that uses custom or core site settings, because those values must be reviewed and set deliberately after the package is installed.
Customization
A package must be customizable without overriding its core assets (assets set to Install and Update). Its documentation should state clearly how the package can be customized without overriding core assets.
Sometimes that means passing configuration variables into components. Other times it means install-only assets, such as template and variable override files. Wherever possible, provide default values even when nothing is passed in or overridden. That makes components more robust and package updates smoother.
Multi-lingual friendly
Packages do not all need to be multi-lingual. If a package should be usable on a multi-lingual site, every piece of text must be customizable by language. Some ways to do that:
1. Define separate templates for each language. This produces many extra templates when only a few pieces of text change.
2. Define the text as a dictionary or as individual variables in a template. Switching language then only requires including a configurable language-specific template that loads the alternate text into the dictionary or variables.
3. Define the text in custom fields. If you do, provide a good fallback or lookup so the text is not copied onto every new page and updating it in one place applies across the site. For example, define the word for "Event" on the calendar page rather than on every calendar entry.
Valid Output, Accessibility, and Distribution Rights
Package output must validate and be accessible, every asset must be yours to distribute, and third-party resources should be served from the site rather than hot-linked.
Valid output
All templates and pages should produce valid HTML that passes W3C validation (https://validator.w3.org/). JSON, XML, RSS, and any other output should pass the validation relevant to its format.
Accessibility
Every package should make a good-faith effort to output accessible markup. Before activating a package, consider how screen readers and different users and browsers will interpret the output. Simple ways to improve accessibility include:
• Proper heading order (no skipping from H1 to H3), using real heading tags rather than styled paragraphs, divs, or spans
• Alt text on every image. A purely decorative image should have an empty alt="" attribute; aria-label or aria-labelledby are less common alternatives.
• ARIA roles and attributes, plus alt, title, and the other HTML accessibility attributes
• Semantic markup
• Screen reader utilities, such as the visually hidden classes in Bootstrap
• Proper color contrast and clearly visible controls
• No significant navigation or functionality that depends on hover
• Keyboard navigation support, through tabindex attributes, javascript, and other methods
• Distinct, identifiable styles for focused elements, often an outline
• Respect for browser preferences and browser zoom
Intellectual property
A package must not include any asset you do not have the right to distribute to everyone with access to the package, so public packages cannot include assets that are not free for commercial use. When you do have the right to distribute content such as scripts or images, document it in the code and follow any other requirement set by the owner.
If package content requires agreement to terms and conditions, include those terms in the package agreement. Do not include agreements for child packages in the parent package; users agree to child packages when they are installed. A package should not need more than one agreement. If it requires agreement to several sets of terms, it should probably be split into separate packages with their own agreements.
In particular, double-check that you have permission to distribute every image and document in each package.
External resources
Avoid referencing outside javascript or other resources where possible; serve those assets from the Marketpath CMS site instead.
Fine to use from their original source:
• Fonts (Google Fonts, Adobe Fonts, Font Awesome, and similar)
• Google Tag Manager, Analytics, and similar
• Other proprietary third-party services that instruct you to use their URL (for example, Appcues or LogRocket)
Copy to the Marketpath CMS site:
• Bootstrap
• jQuery
• Angular
• Vue
• Images and documents from other sites or services (no hot-linking)
Any third-party API that requires a key or token should read it from a custom site setting with no default value. Otherwise the key is exposed to every developer who installs the package.
Package Editor Experience
Design package templates for the editors who use them: clear fields in page order, repeated content managed in one place, safe defaults, and no more options than needed.
When building templates, consider how easily a user can create and edit pages. Field names should be obvious, and most fields should have descriptions. Use field conditions and validation where possible. Field values should be easy to edit and, where possible, follow the same order as their position on the page.
Repeated content
The main content of each page should be unique, but much of a site's supplemental content repeats across pages. Where possible, manage repeated content (testimonials, projects, featured content) in one location and reference it across the site.
It can be useful to customize repeated content on one page while every other page keeps the shared version. In that case, default to the standard values and use custom values only when the user explicitly overrides them. For example:
• A testimonials template may pull random testimonials from a datastore, with an option to select the testimonials for a given page manually.
• A "Core Values" article list may default to the values from another page (such as the home page), with an option to set custom values.
• An "Our Story" section may reference a snippet with a default selected. Changing it means selecting a different snippet, and updating the snippet updates every page that shows it.
Default values
Set a default value on a custom field only when that value makes sense on most websites, because defaults are likely to end up on live sites. Default values must never contain dummy text (Lorem Ipsum or similar) or proprietary intellectual property.
Do not over-engineer
An option that helps a few users is not worth adding for every conceivable scenario. Keep it simple: too many options add confusion.
Package Development Guidelines Revision History
Dated changes to the Package Development Guidelines.
• 2026-09-16: Moved from the Guidelines & Standards article into the Building Sites documentation. The guidance is unchanged; template comment and variable scope rules now point to Template Best Practices and Variable Scopes, the accessibility list names Bootstrap's current visually hidden classes, and typos and headings were cleaned up.
• 2025-04-24: Added a short section about output validation.
• 2023-03-14: Recommended restricting page templates to a single entity type and adding a representative image.
• 2023-01-12: Added Repeated Content and Default Values under the editor experience, and multi-lingual guidance under customization.