Skip to content

Latest commit

 

History

History
192 lines (147 loc) · 9.15 KB

File metadata and controls

192 lines (147 loc) · 9.15 KB

Code Snippets

This file is the single source of truth for project standards, coding conventions, and development workflows in this repository. All contributors — human or automated — should follow these rules.

Tool-specific configuration lives in dedicated locations:

  • GitHub Copilot: .github/copilot-instructions.md and .github/instructions/*.instructions.md
  • Cursor: .cursor/rules/*.mdc
  • Claude: claude.md

Project Overview

Code Snippets is a WordPress plugin that lets site owners manage and execute PHP, HTML, CSS, and JavaScript code snippets through a graphical interface — replacing the need to edit functions.php or maintain multiple single-purpose plugins.


Repository Structure

<root>/
├── src/                   # Shipped plugin root
│   ├── code-snippets.php  # Plugin bootstrap
│   ├── php/               # PHP application code (PSR-4: Code_Snippets\)
│   │   ├── Plugin.php     # Main orchestrator
│   │   ├── Admin/         # Admin UI, menus
│   │   ├── Core/          # Bootstrap, safe mode
│   │   ├── REST_API/      # REST endpoint controllers
│   │   ├── Model/         # Snippet data model
│   │   ├── Flat_Files/    # File-based snippet storage
│   │   ├── Integration/   # Third-party integrations
│   │   ├── Migration/     # Data migration logic
│   │   ├── Settings/      # Plugin settings
│   │   └── Utils/         # Shared utilities
│   ├── js/                # TypeScript / React source
│   │   ├── entries/       # Webpack entrypoints
│   │   ├── components/    # Feature-grouped React UI
│   │   ├── hooks/         # Custom React hooks
│   │   ├── services/      # API service layer
│   │   ├── types/         # TypeScript type definitions
│   │   └── utils/         # JS utilities
│   ├── css/               # SCSS source files
│   ├── dist/              # Webpack output (built assets, not committed)
│   ├── vendor/            # Composer dependencies
│   └── composer.json      # PHP dependency management
├── config/                # Webpack and PostCSS configuration
├── scripts/               # Release, versioning, and linter scripts
├── tests/                 # PHPUnit suites, Playwright E2E specs
├── assets/                # WordPress.org screenshots, icons, and banners
└── .github/               # CI workflows, issue templates, Copilot instructions

Tech Stack

Layer Technology
Backend PHP 7.4+, WordPress APIs, PSR-4 via Composer
Frontend TypeScript, React 18, @wordpress/components, CodeMirror 5
Styling SCSS (PostCSS, logical properties via stylelint-use-logical)
Build Webpack 5, Babel, ts-loader, sass-loader
PHP linting PHPCS + WPCS (npm run lint:php)
JS/TS linting ESLint 9 flat config (npm run lint:js)
CSS linting Stylelint (npm run lint:styles)
PHP tests PHPUnit (npm run test:php)
E2E tests Playwright (npm run test:playwright)
WP dev env @wordpress/env / wp-env (npm run wp-env:start)
Pre-commit Husky + lint-staged (auto-fix on commit)
PHP deps Composer with Imposter (namespace-prefixing)

Coding Standards

General

  • Follow the WordPress Coding Standards for PHP, JS, CSS, and HTML.
  • strict_types=1 is not enforced project-wide — match the style of the file being edited.
  • Keep lines under 120 characters for PHP; 100 for JS/TS.
  • All user-visible strings must be wrapped in a WordPress i18n function with the text domain code-snippets.
  • Use __(), _e(), esc_html__(), esc_attr__(), _x(), _n() as appropriate — never echo raw translatable strings.
  • Do not load translations before init or plugins_loaded.

PHP

  • Namespace: Code_Snippets\ — all new classes must live under this namespace and be PSR-4 autoloaded.
  • Vendor dependencies: always use the prefixed namespace Code_Snippets\Vendor\… (Imposter-prefixed).
  • Guard direct execution at the top of every standalone file: defined('ABSPATH') || exit;
  • Use wp_die() for fatal admin errors; never die() or exit with user-facing output.
  • In src/php/Plugin.php (and Core bootstrap), rely on autoload.php; avoid manual require_once chains.
  • Avoid creating custom database tables. Prefer WordPress-native storage: wp_options for settings/flags, transients for cached/temporary data, or hidden custom post types for structured content. Custom tables require manual schema management, migration, and uninstall logic — only justify them when native storage genuinely cannot meet the requirement.

TypeScript / React

  • Export types that appear in exported function signatures — do not leak unexported shapes.
  • Use @wordpress/api-fetch or the service layer in src/js/services/ for all WP REST calls.
  • Prefer @wordpress/components for UI; avoid reimplementing existing WP admin patterns.

SCSS

  • Use logical CSS properties (e.g., margin-inline-start not margin-left) — enforced by stylelint.

Architecture Patterns

  • PSR-4 autoloading via Composer — class files are discovered automatically; do not require them manually.
  • Imposter prefixing — all vendor/ code is rewritten to Code_Snippets\Vendor\… to prevent conflicts with other plugins using the same libraries.
  • Snippet model — core data unit is Code_Snippets\Model\Snippet; use its API for reading/writing snippet data, not raw DB access.
  • Hook-driven extensibility — use WordPress filters and actions as the primary extension mechanism; expose a filter before changing any default behaviour that may be preference-driven.
  • Safe modesrc/php/Core/load.php boots a recovery path when safe mode is active; any change to snippet execution must preserve this path.

Branching & Git Workflow

  • Production branch: core
  • Pre-release branch: core-beta
  • Development branches: feat/…, fix/…, chore/…, hotfix/…
  • Branch from core-beta for all feature and fix work.
  • Open PRs back into core-beta.
  • Use merge commits (not squash/rebase) when merging dev branches into core-beta.
  • Hotfixes branch from core and merge directly back into core.

Development Commands

# Install dependencies
npm install                  # Node deps + Husky hooks
cd src && composer install   # PHP deps (or: npm run bundle)

# WordPress environment
npm run wp-env:start         # Start local WP instance
npm run wp-env:stop
npm run wp-env:clean         # Reset all data

# Build
npm run build                # Webpack build (JS + CSS → src/dist/)
npm run watch                # Webpack watch mode
npm run bundle               # Full distribution build → bundle/

# Lint
npm run lint                 # All: PHP + JS + CSS
npm run lint:php             # PHPCS with WPCS
npm run lint:js              # ESLint
npm run lint:styles          # Stylelint

# Tests
npm run test:php             # PHPUnit
npm run test:playwright      # Playwright E2E (requires wp-env running)
./test-playwright.sh         # Helper script for Playwright

Security Checklist

Apply to every change:

  • Sanitize all user inputs server-side before use.
  • Escape all outputs at the correct boundary (HTML, attribute, JS, URL).
  • Verify a WordPress nonce on every state-changing request.
  • Verify current_user_can() alongside nonce checks.
  • Never use eval, create_function, or call_user_func with untrusted input.
  • Apply rel="noopener noreferrer" to every target="_blank" link.
  • Use $wpdb->prepare() for every dynamic SQL value.
  • Any feature fetching remote content must document its trust model.

Testing Requirements

  • Unit tests (PHPUnit) — required for all PHP logic changes.
  • Integration tests (PHPUnit) — required when changing DB schema, REST endpoints, or hook behaviour.
  • E2E tests (Playwright) — required for changes affecting snippet create/edit/execute flows.
  • Minimum requirements - Tests must be compatible with the minimum supported PHP 7.4 and WordPress 5.5.
  • Build - Generated build artifacts (src/dist/, Composer autoload maps) must be regenerated when source changes.

Do Not

  • Do not create custom database tables without strong justification — use wp_options, transients, or custom post types instead.
  • Do not echo raw user input — always escape at output.
  • Do not concatenate translated string fragments — translate full sentences.
  • Do not place HTML markup inside translated strings.
  • Do not rely on "deactivate the plugin" as a recovery path — safe mode must remain functional.
  • Do not ship build artifacts to feature branches — src/dist/ and bundle/ are built in CI.