neticrm-frontend
netiCRM/CiviCRM frontend development standards and patterns for HTML, CSS, JavaScript, and Smarty templates. Use this skill when working with frontend code in the netiCRM project to ensure code quality, maintainability, and consistency with project conventions. Apply this skill when writing, modifying, inspecting, reviewing, analyzing, or assessing code quality.
SKILL.md
| Name | neticrm-frontend |
| Description | netiCRM/CiviCRM frontend development standards and patterns for HTML, CSS, JavaScript, and Smarty templates. Use this skill when working with frontend code in the netiCRM project to ensure code quality, maintainability, and consistency with project conventions. Apply this skill when writing, modifying, inspecting, reviewing, analyzing, or assessing code quality. |
name: neticrm-frontend description: "netiCRM/CiviCRM frontend standards for HTML, CSS, JavaScript, and Smarty templates. Use when editing .tpl/.css/.js files, fixing CSS layout or responsiveness, writing jQuery code, implementing Smarty logic, or checking browser compatibility. Ensures code consistency and avoids project-specific anti-patterns."
netiCRM Frontend Development
Overview
This skill provides project-specific frontend development standards for netiCRM/CiviCRM. It ensures AI-generated code follows established patterns, naming conventions, and best practices specific to this codebase.
Key principle: Knowing syntax ≠ Writing high-quality code. This skill bridges the gap between general CSS/JS/HTML knowledge and project-specific quality standards.
Quick Reference
CSS
- Standards: See css-standards.md
- Browser Support: See browser-support-policy.md
JavaScript
- Patterns: See javascript-patterns.md
Smarty Templates
- Guide: See smarty-templates.md
HTML Structure
- Conventions: See html-conventions.md
Code Quality Principles
- Maintainability First: Code should be easy to understand and modify
- Consistency: Follow existing patterns in the codebase
- Performance: Consider CSS specificity, selector performance, and asset loading
- Accessibility: Use semantic HTML and proper ARIA attributes
- Localization: Always use translation functions for user-facing text
Development Workflow
- Check References First: Before writing code, review the relevant reference file
- Check Browser Support (MANDATORY for CSS): Before using any new or uncommon CSS technology, you MUST consult browser-support-policy.md to verify compatibility with the company's browser support policy. This includes:
- Any CSS technology that appears "new," "experimental," or "uncommon"
- Any technique using
::pseudo-elements or@rules (except basic @media) - Technologies containing keywords like
scroll-,container-,@layer,@property, etc. - You MUST perform a WebSearch or WebFetch to check current browser support - do NOT rely solely on your knowledge cutoff
- Follow Patterns: Look for similar existing code in the project
- Use CSS Variables: Always use defined CSS variables for colors and dimensions
- Test Responsively: Verify code works across breakpoints (
ncg-*grid) - Validate Translations: Ensure all user-facing text uses
{ts}orts()
Examples
Example 1: CSS — Fix mobile layout on a form
User says: "The contribution form looks broken on mobile"
Actions:
- Read
references/css-standards.md— Responsive Design and Grid System sections - Replace any
max-widthmedia queries with mobile-firstmin-width - Use
ncg-row/ncg-col-*classes instead of custom flex/grid - Scope all selectors under
.crm-container - Replace hardcoded colors with CSS variables (
--color-*,--rfm-*)
Result: Responsive layout that follows netiCRM standards and won't leak styles to the host site
Example 2: jQuery + JS — Add event handler for dynamic elements
User says: "Add a handler when user changes the payment method select"
Actions:
- Read
references/javascript-patterns.md— jQuery Usage and Event Handling sections - Use event delegation
cj(document).on('change', '#selector', fn)— never bind directly to dynamic elements - Wrap code in
(function($) { 'use strict'; ... })(cj)closure - If fetching CiviCRM data, use
.crmAPI()with bothsuccessanderrorcallbacks
Result: Correct jQuery pattern that avoids $ conflicts and works with dynamically rendered markup
Example 3: Smarty — Display translated text with dynamic values and a CRM link
User says: "Show a help message with the contact's name and a link to their profile"
Actions:
- Read
references/smarty-templates.md— Translation System, Security, and{crmURL}sections - Use
{ts 1=$var}text %1{/ts}for parameterized strings — never interpolate variables inside{ts} - Escape user-supplied output:
{$var|escape} - Generate URLs with
{crmURL p='...' q='...'}— never hardcode paths - If adding inline JS, wrap in
{literal}and use{ts escape='js'}for translated strings
Result: Properly translated, escaped, and CMS-portable template
Common Issues
CSS styles leaking to the host website
Cause: Selectors written without .crm-container prefix
Solution: Prefix all CiviCRM-specific selectors with .crm-container; use body:has(.crm-container) for body-level styles. See references/css-standards.md — CSS Selector Scoping section.
Layout breaks on mobile
Cause: Desktop-first max-width media queries, or custom breakpoints instead of ncg-* variables
Solution: Rewrite using mobile-first min-width with --ncg-breakpoint-* variables; use ncg-row / ncg-col-* grid classes. See references/css-standards.md — Responsive Design section.
jQuery $ is not defined / conflict with other libraries
Cause: Using $ directly instead of cj() outside a closure
Solution: Use cj() at the top level; pass $ as a parameter inside (function($) { ... })(cj) or cj(document).ready(function($) { ... }). See references/javascript-patterns.md — jQuery Usage section.
Event handler not firing on dynamically added elements
Cause: Binding events directly to elements that don't exist at DOM-ready time
Solution: Use event delegation — cj(document).on('event', '.selector', fn). See references/javascript-patterns.md — Event Handling section.
Smarty parse error with JavaScript { } braces
Cause: Smarty interprets { and } inside <script> blocks
Solution: Wrap all inline JavaScript in {literal}...{/literal}. See references/smarty-templates.md — Asset Loading section.
Translated string breaks JavaScript
Cause: {ts} output in JS context without escaping quotes
Solution: Always use {ts escape='js'} inside JavaScript strings. See references/smarty-templates.md — Translation System section.