Snippets Dependencies Management

Dependency Philosophy

Elemental CMS follows a straightforward and efficient approach to dependency management:

  • Load dependencies only when and where they are needed
  • Keep files separate and focused - no bundling or minification required
  • Direct inclusion of CSS and JavaScript files
  • Clean, readable source code for easy maintenance

This philosophy prioritizes:

  • Clarity over artificial optimization
  • Maintainability over build complexity
  • Direct file management over bundling
  • Specific loading over generic inclusion

Dependency Levels

The system uses three distinct levels of dependencies, each serving a specific purpose:

1. Global Dependencies ├── Shared across all pages ├── Core functionality (e.g., jQuery, Bootstrap) └── Managed via global-deps commands 2. Page Dependencies ├── Specific to individual pages ├── Language-specific resources └── Loaded with page content 3. Snippet Dependencies ├── Loaded only when snippet is used ├── Self-contained in snippet spec └── Injected during rendering

Global Dependencies

Global dependencies are organized by type in separate folders:

GLOBAL_DEPS_FOLDER/ ├── text_css/ │ ├── bootstrap.json # Core styling │ └── custom-theme.json # Site-wide theme ├── application_javascript/ │ ├── jquery.json # Core functionality │ └── bootstrap.json # UI components └── module/ └── app-module.json # Application logic

Each global dependency has its own specification file:

{ "_id": ObjectId("..."), "order": 1, "name": "jquery", "type": "application/javascript", "url": "js/jquery.js", "meta": { "crossorigin": "anonymous" } }

Page Dependencies

Pages can include their own specific dependencies:

{ "name": "about", "language": "en", "cssDeps": [ { "name": "about-styles", "type": "text/css", "url": "css/about.css" } ], "jsDeps": [ { "name": "about-interactions", "type": "application/javascript", "url": "js/about.js" } ] }

Snippet Dependencies

Snippets include only the dependencies they need:

{ "name": "product-gallery", "cssDeps": [ { "name": "gallery-styles", "type": "text/css", "url": "css/gallery.css" } ], "jsDeps": [ { "name": "gallery-behavior", "type": "application/javascript", "url": "js/gallery.js" } ] }

Working with Dependencies

Creating Dependencies

Create dependencies directly and clearly:

# Global dependency elemental-cms global-deps create -d datepicker application/javascript # Snippet with dependencies elemental-cms snippets create -s contact-form # Edit contact-form.json { "name": "contact-form", "cssDeps": [ { "name": "form-styles", "type": "text/css", "url": "css/contact-form.css" } ], "jsDeps": [ { "name": "form-validation", "type": "application/javascript", "url": "js/contact-form.js" } ] }

Managing Dependencies

Simple and direct dependency management:

# List all global dependencies elemental-cms global-deps list # Push snippet with dependencies elemental-cms snippets push -s contact-form # Pull snippet with dependencies elemental-cms snippets pull -s contact-form

Best Practices

Follow these guidelines for clean dependency management:

1. Keep Dependencies Focused ├── One file = one purpose ├── Clear, descriptive names └── Direct file references 2. Load Only What's Needed ├── Global deps for truly shared resources ├── Page deps for page-specific features └── Snippet deps for snippet functionality 3. Maintain Readability ├── Use descriptive file names ├── Keep source files clean and commented └── Organize files logically 4. Simple is Better ├── Avoid unnecessary build steps ├── Keep files separate and focused └── Direct file inclusion

Examples and Use Cases

Navigation Snippet

# nav-bar.json { "name": "nav-bar", "cssDeps": [ { "name": "nav-styles", "type": "text/css", "url": "css/nav-bar.css" } ], "jsDeps": [ { "name": "nav-behavior", "type": "application/javascript", "url": "js/nav-bar.js" } ] } # nav-bar.html <nav class="site-nav"> <ul class="nav-list"> <li><a href="/">nav.home</a></li> <li><a href="/about">nav.about</a></li> </ul> </nav>

Form Snippet with Validation

# contact-form.json { "name": "contact-form", "cssDeps": [ { "name": "form-styles", "type": "text/css", "url": "css/contact-form.css" } ], "jsDeps": [ { "name": "form-validation", "type": "application/javascript", "url": "js/contact-form.js" } ] } # contact-form.html <form class="contact-form" id="contactForm"> <div class="form-group"> <label>form.name</label> <input type="text" name="name" required> </div> <button type="submit">form.submit</button> </form>

Using Snippets in Pages

{# Each snippet loads only its required dependencies #} {{ render_snippet('nav-bar', page, inject_inline_deps=True) }} {{ render_snippet('contact-form', page, inject_inline_deps=True) }}

This approach ensures that each component loads exactly what it needs, when it needs it, without unnecessary complexity or overhead.

Content