cfsa-antigravity 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.mjs +324 -0
- package/package.json +34 -0
- package/template/.agent/instructions/commands.md +48 -0
- package/template/.agent/instructions/patterns.md +61 -0
- package/template/.agent/instructions/structure.md +29 -0
- package/template/.agent/instructions/tech-stack.md +43 -0
- package/template/.agent/instructions/workflow.md +41 -0
- package/template/.agent/kit-sync.md +15 -0
- package/template/.agent/rules/boundary-not-placeholder.md +146 -0
- package/template/.agent/rules/completion-checklist.md +48 -0
- package/template/.agent/rules/decision-classification.md +103 -0
- package/template/.agent/rules/extensibility.md +47 -0
- package/template/.agent/rules/question-vs-command.md +81 -0
- package/template/.agent/rules/security-first.md +43 -0
- package/template/.agent/rules/specificity-standards.md +54 -0
- package/template/.agent/rules/tdd-contract-first.md +57 -0
- package/template/.agent/rules/vertical-slices.md +42 -0
- package/template/.agent/skill-library/MANIFEST.md +480 -0
- package/template/.agent/skill-library/README.md +38 -0
- package/template/.agent/skill-library/meta/brand-guidelines/SKILL.md +73 -0
- package/template/.agent/skill-library/meta/claude-code/README.md +9 -0
- package/template/.agent/skill-library/meta/claude-code/agent-development/SKILL.md +415 -0
- package/template/.agent/skill-library/meta/claude-code/hook-development/SKILL.md +712 -0
- package/template/.agent/skill-library/meta/claude-code/plugin-structure/SKILL.md +476 -0
- package/template/.agent/skill-library/meta/git-advanced/SKILL.md +972 -0
- package/template/.agent/skill-library/meta/mcp-builder/SKILL.md +236 -0
- package/template/.agent/skill-library/meta/product-marketing-context/SKILL.md +241 -0
- package/template/.agent/skill-library/meta/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skill-library/meta/tmux-processes/SKILL.md +210 -0
- package/template/.agent/skill-library/meta/using-tmux-for-interactive-commands/SKILL.md +178 -0
- package/template/.agent/skill-library/stack/3d/threejs-pro/SKILL.md +300 -0
- package/template/.agent/skill-library/stack/ai/ai-sdk/SKILL.md +77 -0
- package/template/.agent/skill-library/stack/ai/langchain/SKILL.md +530 -0
- package/template/.agent/skill-library/stack/ai/ollama/SKILL.md +321 -0
- package/template/.agent/skill-library/stack/ai/openai-sdk/SKILL.md +549 -0
- package/template/.agent/skill-library/stack/analytics/google-analytics/SKILL.md +153 -0
- package/template/.agent/skill-library/stack/api/graphql/SKILL.md +1061 -0
- package/template/.agent/skill-library/stack/api/trpc/SKILL.md +576 -0
- package/template/.agent/skill-library/stack/auth/authjs/SKILL.md +569 -0
- package/template/.agent/skill-library/stack/auth/clerk/SKILL.md +590 -0
- package/template/.agent/skill-library/stack/auth/firebase-auth/SKILL.md +734 -0
- package/template/.agent/skill-library/stack/cms/payload-cms/SKILL.md +573 -0
- package/template/.agent/skill-library/stack/cms/shopify/SKILL.md +1193 -0
- package/template/.agent/skill-library/stack/cms/wordpress/SKILL.md +1104 -0
- package/template/.agent/skill-library/stack/css/sass-scss/SKILL.md +1121 -0
- package/template/.agent/skill-library/stack/css/tailwind-css-patterns/SKILL.md +863 -0
- package/template/.agent/skill-library/stack/css/tailwind-design-system/SKILL.md +490 -0
- package/template/.agent/skill-library/stack/css/vanilla-css/SKILL.md +1078 -0
- package/template/.agent/skill-library/stack/databases/clickhouse/SKILL.md +311 -0
- package/template/.agent/skill-library/stack/databases/influxdb/SKILL.md +280 -0
- package/template/.agent/skill-library/stack/databases/lancedb/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/databases/mongodb/SKILL.md +1169 -0
- package/template/.agent/skill-library/stack/databases/neo4j/SKILL.md +839 -0
- package/template/.agent/skill-library/stack/databases/pgvector/SKILL.md +241 -0
- package/template/.agent/skill-library/stack/databases/pinecone/SKILL.md +212 -0
- package/template/.agent/skill-library/stack/databases/postgresql/SKILL.md +658 -0
- package/template/.agent/skill-library/stack/databases/qdrant/SKILL.md +312 -0
- package/template/.agent/skill-library/stack/databases/redis/SKILL.md +1079 -0
- package/template/.agent/skill-library/stack/databases/spacetimedb/SKILL.md +532 -0
- package/template/.agent/skill-library/stack/databases/sqlite/SKILL.md +1132 -0
- package/template/.agent/skill-library/stack/databases/supabase/SKILL.md +640 -0
- package/template/.agent/skill-library/stack/databases/surrealdb-expert/SKILL.md +945 -0
- package/template/.agent/skill-library/stack/databases/timescaledb/SKILL.md +745 -0
- package/template/.agent/skill-library/stack/databases/weaviate/SKILL.md +218 -0
- package/template/.agent/skill-library/stack/devops/github-actions/SKILL.md +554 -0
- package/template/.agent/skill-library/stack/devops/kubernetes/SKILL.md +950 -0
- package/template/.agent/skill-library/stack/devops/nginx/SKILL.md +841 -0
- package/template/.agent/skill-library/stack/devops/terraform/SKILL.md +860 -0
- package/template/.agent/skill-library/stack/email/resend/SKILL.md +391 -0
- package/template/.agent/skill-library/stack/engines/godot/SKILL.md +488 -0
- package/template/.agent/skill-library/stack/extensions/chrome-extension/SKILL.md +375 -0
- package/template/.agent/skill-library/stack/extensions/vscode-extension/SKILL.md +453 -0
- package/template/.agent/skill-library/stack/frameworks/astro-framework/SKILL.md +162 -0
- package/template/.agent/skill-library/stack/frameworks/electron/SKILL.md +1286 -0
- package/template/.agent/skill-library/stack/frameworks/fastapi/SKILL.md +650 -0
- package/template/.agent/skill-library/stack/frameworks/hono/SKILL.md +90 -0
- package/template/.agent/skill-library/stack/frameworks/nestjs/SKILL.md +878 -0
- package/template/.agent/skill-library/stack/frameworks/nextjs/SKILL.md +635 -0
- package/template/.agent/skill-library/stack/frameworks/nuxt/SKILL.md +564 -0
- package/template/.agent/skill-library/stack/frameworks/sveltekit/SKILL.md +614 -0
- package/template/.agent/skill-library/stack/frameworks/tauri/SKILL.md +920 -0
- package/template/.agent/skill-library/stack/gamedev/godot/SKILL.md +1032 -0
- package/template/.agent/skill-library/stack/gamedev/unity/SKILL.md +1175 -0
- package/template/.agent/skill-library/stack/hosting/aws/SKILL.md +467 -0
- package/template/.agent/skill-library/stack/hosting/cloudflare/SKILL.md +201 -0
- package/template/.agent/skill-library/stack/hosting/docker-expert/SKILL.md +409 -0
- package/template/.agent/skill-library/stack/hosting/vercel/SKILL.md +484 -0
- package/template/.agent/skill-library/stack/languages/bash-scripting/SKILL.md +773 -0
- package/template/.agent/skill-library/stack/languages/c-cpp/SKILL.md +712 -0
- package/template/.agent/skill-library/stack/languages/gdscript/SKILL.md +789 -0
- package/template/.agent/skill-library/stack/languages/go/SKILL.md +664 -0
- package/template/.agent/skill-library/stack/languages/java/SKILL.md +778 -0
- package/template/.agent/skill-library/stack/languages/kotlin/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/languages/python/SKILL.md +678 -0
- package/template/.agent/skill-library/stack/languages/rust/SKILL.md +673 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/SKILL.md +141 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/advanced-generics.md +90 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/branded-types.md +57 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/builder-pattern.md +71 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/common-pitfalls.md +135 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/conditional-types.md +27 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/decorators.md +98 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/discriminated-unions.md +62 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/mapped-types.md +53 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/performance-best-practices.md +104 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/template-literal-types.md +49 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/testing-types.md +112 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-guards.md +70 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/type-inference.md +101 -0
- package/template/.agent/skill-library/stack/languages/typescript-advanced-patterns/references/utility-types.md +98 -0
- package/template/.agent/skill-library/stack/languages/vanilla-javascript/SKILL.md +803 -0
- package/template/.agent/skill-library/stack/messaging/kafka/SKILL.md +235 -0
- package/template/.agent/skill-library/stack/mobile/expo-react-native/SKILL.md +665 -0
- package/template/.agent/skill-library/stack/mobile/flutter/SKILL.md +316 -0
- package/template/.agent/skill-library/stack/mobile/react-native/SKILL.md +337 -0
- package/template/.agent/skill-library/stack/monitoring/posthog/SKILL.md +396 -0
- package/template/.agent/skill-library/stack/monitoring/sentry/SKILL.md +509 -0
- package/template/.agent/skill-library/stack/observability/datadog/SKILL.md +179 -0
- package/template/.agent/skill-library/stack/observability/distributed-tracing/SKILL.md +140 -0
- package/template/.agent/skill-library/stack/observability/logging-best-practices/SKILL.md +168 -0
- package/template/.agent/skill-library/stack/observability/opentelemetry/SKILL.md +164 -0
- package/template/.agent/skill-library/stack/observability/prometheus-grafana/SKILL.md +246 -0
- package/template/.agent/skill-library/stack/observability/python-observability/SKILL.md +158 -0
- package/template/.agent/skill-library/stack/orm/drizzle-orm/SKILL.md +613 -0
- package/template/.agent/skill-library/stack/orm/prisma/SKILL.md +744 -0
- package/template/.agent/skill-library/stack/payments/lemonsqueezy/SKILL.md +393 -0
- package/template/.agent/skill-library/stack/payments/stripe-integration/SKILL.md +457 -0
- package/template/.agent/skill-library/stack/queue/bullmq/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/queue/inngest/SKILL.md +438 -0
- package/template/.agent/skill-library/stack/realtime/socketio/SKILL.md +595 -0
- package/template/.agent/skill-library/stack/search/elasticsearch/SKILL.md +248 -0
- package/template/.agent/skill-library/stack/search/meilisearch/SKILL.md +385 -0
- package/template/.agent/skill-library/stack/security/crypto-patterns/SKILL.md +437 -0
- package/template/.agent/skill-library/stack/security/csp-cors-headers/SKILL.md +588 -0
- package/template/.agent/skill-library/stack/security/dependency-auditing/SKILL.md +560 -0
- package/template/.agent/skill-library/stack/security/input-sanitization/SKILL.md +430 -0
- package/template/.agent/skill-library/stack/security/owasp-web-security/SKILL.md +421 -0
- package/template/.agent/skill-library/stack/state/tanstack-query/SKILL.md +637 -0
- package/template/.agent/skill-library/stack/state/zustand/SKILL.md +483 -0
- package/template/.agent/skill-library/stack/storage/aws-s3/SKILL.md +415 -0
- package/template/.agent/skill-library/stack/testing/playwright/SKILL.md +641 -0
- package/template/.agent/skill-library/stack/testing/storybook/SKILL.md +923 -0
- package/template/.agent/skill-library/stack/testing/testing-library/SKILL.md +872 -0
- package/template/.agent/skill-library/stack/testing/vitest/SKILL.md +714 -0
- package/template/.agent/skill-library/stack/ui/react-best-practices/SKILL.md +877 -0
- package/template/.agent/skill-library/stack/ui/react-composition-patterns/SKILL.md +1107 -0
- package/template/.agent/skill-library/stack/ui/react-flow/SKILL.md +425 -0
- package/template/.agent/skill-library/stack/ui/shadcn-ui/SKILL.md +703 -0
- package/template/.agent/skill-library/surface/api/api-caching/SKILL.md +458 -0
- package/template/.agent/skill-library/surface/api/api-documentation-openapi/SKILL.md +697 -0
- package/template/.agent/skill-library/surface/api/api-error-handling/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/api-security-checklist/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/api-versioning/SKILL.md +420 -0
- package/template/.agent/skill-library/surface/api/email-best-practices/SKILL.md +59 -0
- package/template/.agent/skill-library/surface/api/rate-limiting-abuse-protection/SKILL.md +147 -0
- package/template/.agent/skill-library/surface/api/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skill-library/surface/api/webhook-design/SKILL.md +752 -0
- package/template/.agent/skill-library/surface/cli/cli-configuration-management/SKILL.md +445 -0
- package/template/.agent/skill-library/surface/cli/cli-error-diagnostics/SKILL.md +515 -0
- package/template/.agent/skill-library/surface/cli/cli-shell-integration/SKILL.md +479 -0
- package/template/.agent/skill-library/surface/cli/cli-ux-design/SKILL.md +477 -0
- package/template/.agent/skill-library/surface/desktop/desktop-app-distribution/SKILL.md +416 -0
- package/template/.agent/skill-library/surface/desktop/desktop-security-sandboxing/SKILL.md +407 -0
- package/template/.agent/skill-library/surface/desktop/desktop-ux-conventions/SKILL.md +361 -0
- package/template/.agent/skill-library/surface/desktop/native-os-integration/SKILL.md +563 -0
- package/template/.agent/skill-library/surface/extension/browser-extension-patterns/SKILL.md +482 -0
- package/template/.agent/skill-library/surface/extension/plugin-architecture-design/SKILL.md +632 -0
- package/template/.agent/skill-library/surface/extension/vscode-extension-development/SKILL.md +728 -0
- package/template/.agent/skill-library/surface/mobile/app-store-submission/SKILL.md +304 -0
- package/template/.agent/skill-library/surface/mobile/mobile-offline-sync/SKILL.md +443 -0
- package/template/.agent/skill-library/surface/mobile/mobile-responsive-patterns/SKILL.md +432 -0
- package/template/.agent/skill-library/surface/mobile/push-notifications/SKILL.md +495 -0
- package/template/.agent/skill-library/surface/web/accessibility-compliance/SKILL.md +827 -0
- package/template/.agent/skill-library/surface/web/ai-seo/SKILL.md +398 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/content-patterns.md +285 -0
- package/template/.agent/skill-library/surface/web/ai-seo/references/platform-ranking-factors.md +152 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/SKILL.md +309 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/event-library.md +260 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/ga4-implementation.md +300 -0
- package/template/.agent/skill-library/surface/web/analytics-tracking/references/gtm-implementation.md +390 -0
- package/template/.agent/skill-library/surface/web/authentication-ui-flows/SKILL.md +530 -0
- package/template/.agent/skill-library/surface/web/dark-mode-theming/SKILL.md +516 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/SKILL.md +105 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/charts.csv +26 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/colors.csv +97 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/landing.csv +31 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/styles.csv +59 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/typography.csv +58 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/data/ux-guidelines.csv +100 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/core.py +258 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/design_system.py +1067 -0
- package/template/.agent/skill-library/surface/web/design-reference-data/scripts/search.py +106 -0
- package/template/.agent/skill-library/surface/web/form-handling-validation/SKILL.md +675 -0
- package/template/.agent/skill-library/surface/web/frontend-design/SKILL.md +1393 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/cppn-hero.tsx +299 -0
- package/template/.agent/skill-library/surface/web/frontend-design/templates/wave-hero.tsx +875 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/SKILL.md +111 -0
- package/template/.agent/skill-library/surface/web/frontend-verification/scripts/ux_audit.py +739 -0
- package/template/.agent/skill-library/surface/web/i18n-localization/SKILL.md +154 -0
- package/template/.agent/skill-library/surface/web/offline-first-pwa/SKILL.md +657 -0
- package/template/.agent/skill-library/surface/web/page-cro/SKILL.md +182 -0
- package/template/.agent/skill-library/surface/web/page-cro/references/experiments.md +248 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/SKILL.md +238 -0
- package/template/.agent/skill-library/surface/web/programmatic-seo/references/playbooks.md +308 -0
- package/template/.agent/skill-library/surface/web/schema-markup/SKILL.md +179 -0
- package/template/.agent/skill-library/surface/web/schema-markup/references/schema-examples.md +398 -0
- package/template/.agent/skill-library/surface/web/seo-audit/SKILL.md +394 -0
- package/template/.agent/skill-library/surface/web/seo-audit/references/ai-writing-detection.md +200 -0
- package/template/.agent/skill-library/surface/web/web-performance-optimization/SKILL.md +646 -0
- package/template/.agent/skill-library/surface/web/web-scraping/SKILL.md +58 -0
- package/template/.agent/skills/accessibility/SKILL.md +522 -0
- package/template/.agent/skills/accessibility/references/WCAG.md +162 -0
- package/template/.agent/skills/adversarial-review/SKILL.md +90 -0
- package/template/.agent/skills/antigravity-workflows/SKILL.md +81 -0
- package/template/.agent/skills/antigravity-workflows/resources/implementation-playbook.md +36 -0
- package/template/.agent/skills/api-design-principles/SKILL.md +37 -0
- package/template/.agent/skills/api-design-principles/assets/api-design-checklist.md +155 -0
- package/template/.agent/skills/api-design-principles/assets/rest-api-template.py +182 -0
- package/template/.agent/skills/api-design-principles/references/graphql-schema-design.md +583 -0
- package/template/.agent/skills/api-design-principles/references/rest-best-practices.md +408 -0
- package/template/.agent/skills/api-design-principles/resources/implementation-playbook.md +513 -0
- package/template/.agent/skills/api-versioning/SKILL.md +420 -0
- package/template/.agent/skills/architecture-mapping/SKILL.md +219 -0
- package/template/.agent/skills/bootstrap-agents/SKILL.md +259 -0
- package/template/.agent/skills/brainstorming/SKILL.md +236 -0
- package/template/.agent/skills/brand-guidelines/SKILL.md +44 -0
- package/template/.agent/skills/clean-code/SKILL.md +94 -0
- package/template/.agent/skills/code-review-pro/SKILL.md +152 -0
- package/template/.agent/skills/concise-planning/SKILL.md +68 -0
- package/template/.agent/skills/cross-layer-consistency/SKILL.md +117 -0
- package/template/.agent/skills/database-schema-design/SKILL.md +429 -0
- package/template/.agent/skills/deployment-procedures/SKILL.md +241 -0
- package/template/.agent/skills/design-anti-cliche/SKILL.md +159 -0
- package/template/.agent/skills/design-direction/SKILL.md +45 -0
- package/template/.agent/skills/error-handling-patterns/SKILL.md +721 -0
- package/template/.agent/skills/find-skills/SKILL.md +145 -0
- package/template/.agent/skills/git-advanced/SKILL.md +972 -0
- package/template/.agent/skills/git-workflow/SKILL.md +420 -0
- package/template/.agent/skills/idea-extraction/SKILL.md +271 -0
- package/template/.agent/skills/logging-best-practices/SKILL.md +851 -0
- package/template/.agent/skills/migration-management/SKILL.md +384 -0
- package/template/.agent/skills/minimalist-surgical-development/SKILL.md +69 -0
- package/template/.agent/skills/parallel-agents/SKILL.md +165 -0
- package/template/.agent/skills/parallel-debugging/SKILL.md +135 -0
- package/template/.agent/skills/parallel-feature-development/SKILL.md +166 -0
- package/template/.agent/skills/performance-budgeting/SKILL.md +144 -0
- package/template/.agent/skills/pipeline-rubrics/SKILL.md +51 -0
- package/template/.agent/skills/pipeline-rubrics/references/architecture-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/be-rubric.md +21 -0
- package/template/.agent/skills/pipeline-rubrics/references/fe-rubric.md +20 -0
- package/template/.agent/skills/pipeline-rubrics/references/ia-rubric.md +19 -0
- package/template/.agent/skills/pipeline-rubrics/references/scoring.md +28 -0
- package/template/.agent/skills/pipeline-rubrics/references/vision-rubric.md +11 -0
- package/template/.agent/skills/prd-templates/SKILL.md +88 -0
- package/template/.agent/skills/prd-templates/references/architecture-design-template.md +88 -0
- package/template/.agent/skills/prd-templates/references/be-spec-template.md +101 -0
- package/template/.agent/skills/prd-templates/references/data-placement-template.md +74 -0
- package/template/.agent/skills/prd-templates/references/decomposition-templates.md +211 -0
- package/template/.agent/skills/prd-templates/references/design-system-decisions.md +198 -0
- package/template/.agent/skills/prd-templates/references/engineering-standards-template.md +124 -0
- package/template/.agent/skills/prd-templates/references/fe-classification-procedures.md +47 -0
- package/template/.agent/skills/prd-templates/references/fe-spec-template.md +84 -0
- package/template/.agent/skills/prd-templates/references/infrastructure-report-template.md +71 -0
- package/template/.agent/skills/prd-templates/references/operational-templates.md +116 -0
- package/template/.agent/skills/prd-templates/references/placeholder-guard-template.md +21 -0
- package/template/.agent/skills/prd-templates/references/surface-model.md +61 -0
- package/template/.agent/skills/prd-templates/references/vision-template.md +66 -0
- package/template/.agent/skills/prompt-engineer/README.md +659 -0
- package/template/.agent/skills/prompt-engineer/SKILL.md +249 -0
- package/template/.agent/skills/regex-patterns/SKILL.md +751 -0
- package/template/.agent/skills/resolve-ambiguity/SKILL.md +278 -0
- package/template/.agent/skills/rest-api-design/SKILL.md +478 -0
- package/template/.agent/skills/security-scanning-security-hardening/SKILL.md +231 -0
- package/template/.agent/skills/session-continuity/SKILL.md +730 -0
- package/template/.agent/skills/session-continuity/protocols/01-session-resumption.md +38 -0
- package/template/.agent/skills/session-continuity/protocols/02-progress-generation.md +85 -0
- package/template/.agent/skills/session-continuity/protocols/03-progress-update.md +70 -0
- package/template/.agent/skills/session-continuity/protocols/04-pattern-extraction.md +60 -0
- package/template/.agent/skills/session-continuity/protocols/05-session-close.md +37 -0
- package/template/.agent/skills/session-continuity/protocols/06-decision-analysis.md +84 -0
- package/template/.agent/skills/session-continuity/protocols/07-spec-pipeline-generation.md +48 -0
- package/template/.agent/skills/session-continuity/protocols/08-spec-pipeline-update.md +43 -0
- package/template/.agent/skills/session-continuity/protocols/09-parallel-claim.md +122 -0
- package/template/.agent/skills/session-continuity/protocols/10-placeholder-verification-gate.md +104 -0
- package/template/.agent/skills/session-continuity/protocols/ambiguity-gates.md +48 -0
- package/template/.agent/skills/skill-creator/LICENSE.txt +202 -0
- package/template/.agent/skills/skill-creator/README.md +270 -0
- package/template/.agent/skills/skill-creator/SKILL.md +590 -0
- package/template/.agent/skills/skill-creator/references/output-patterns.md +82 -0
- package/template/.agent/skills/skill-creator/references/workflows.md +28 -0
- package/template/.agent/skills/skill-creator/scripts/init_skill.py +303 -0
- package/template/.agent/skills/skill-creator/scripts/package_skill.py +110 -0
- package/template/.agent/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/template/.agent/skills/spec-writing/SKILL.md +110 -0
- package/template/.agent/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/template/.agent/skills/systematic-debugging/SKILL.md +297 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/template/.agent/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/template/.agent/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/template/.agent/skills/systematic-debugging/find-polluter.sh +63 -0
- package/template/.agent/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/template/.agent/skills/systematic-debugging/test-academic.md +14 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/template/.agent/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/template/.agent/skills/tdd-workflow/SKILL.md +409 -0
- package/template/.agent/skills/tech-stack-catalog/SKILL.md +49 -0
- package/template/.agent/skills/tech-stack-catalog/references/constraint-questions.md +21 -0
- package/template/.agent/skills/tech-stack-catalog/references/dev-tooling-decisions.md +37 -0
- package/template/.agent/skills/tech-stack-catalog/references/surface-decision-tables.md +69 -0
- package/template/.agent/skills/technical-writer/SKILL.md +242 -0
- package/template/.agent/skills/testing-strategist/SKILL.md +932 -0
- package/template/.agent/skills/verification-before-completion/SKILL.md +145 -0
- package/template/.agent/skills/workflow-automation/SKILL.md +73 -0
- package/template/.agent/workflows/audit-ambiguity-execute.md +165 -0
- package/template/.agent/workflows/audit-ambiguity-rubrics.md +83 -0
- package/template/.agent/workflows/audit-ambiguity.md +64 -0
- package/template/.agent/workflows/bootstrap-agents-fill.md +201 -0
- package/template/.agent/workflows/bootstrap-agents-provision.md +197 -0
- package/template/.agent/workflows/bootstrap-agents.md +66 -0
- package/template/.agent/workflows/create-prd-architecture.md +119 -0
- package/template/.agent/workflows/create-prd-compile.md +138 -0
- package/template/.agent/workflows/create-prd-design-system.md +135 -0
- package/template/.agent/workflows/create-prd-security.md +113 -0
- package/template/.agent/workflows/create-prd-stack.md +91 -0
- package/template/.agent/workflows/create-prd.md +168 -0
- package/template/.agent/workflows/decompose-architecture-structure.md +82 -0
- package/template/.agent/workflows/decompose-architecture-validate.md +119 -0
- package/template/.agent/workflows/decompose-architecture.md +111 -0
- package/template/.agent/workflows/evolve-contract.md +98 -0
- package/template/.agent/workflows/evolve-feature-cascade.md +140 -0
- package/template/.agent/workflows/evolve-feature-classify.md +116 -0
- package/template/.agent/workflows/evolve-feature.md +56 -0
- package/template/.agent/workflows/ideate-discover.md +144 -0
- package/template/.agent/workflows/ideate-extract.md +129 -0
- package/template/.agent/workflows/ideate-validate.md +117 -0
- package/template/.agent/workflows/ideate.md +113 -0
- package/template/.agent/workflows/implement-slice-setup.md +113 -0
- package/template/.agent/workflows/implement-slice-tdd.md +198 -0
- package/template/.agent/workflows/implement-slice.md +50 -0
- package/template/.agent/workflows/plan-phase.md +202 -0
- package/template/.agent/workflows/propagate-decision-apply.md +135 -0
- package/template/.agent/workflows/propagate-decision-scan.md +147 -0
- package/template/.agent/workflows/propagate-decision.md +56 -0
- package/template/.agent/workflows/remediate-pipeline-assess.md +138 -0
- package/template/.agent/workflows/remediate-pipeline-execute.md +135 -0
- package/template/.agent/workflows/remediate-pipeline.md +55 -0
- package/template/.agent/workflows/resolve-ambiguity.md +82 -0
- package/template/.agent/workflows/sync-kit.md +209 -0
- package/template/.agent/workflows/update-architecture-map.md +74 -0
- package/template/.agent/workflows/validate-phase.md +219 -0
- package/template/.agent/workflows/verify-infrastructure.md +207 -0
- package/template/.agent/workflows/write-architecture-spec-deepen.md +139 -0
- package/template/.agent/workflows/write-architecture-spec-design.md +202 -0
- package/template/.agent/workflows/write-architecture-spec.md +63 -0
- package/template/.agent/workflows/write-be-spec-classify.md +165 -0
- package/template/.agent/workflows/write-be-spec-write.md +98 -0
- package/template/.agent/workflows/write-be-spec.md +76 -0
- package/template/.agent/workflows/write-fe-spec-classify.md +170 -0
- package/template/.agent/workflows/write-fe-spec-write.md +94 -0
- package/template/.agent/workflows/write-fe-spec.md +71 -0
- package/template/AGENTS.md +176 -0
- package/template/GEMINI.md +177 -0
- package/template/docs/README.md +187 -0
- package/template/docs/audits/.gitkeep +0 -0
- package/template/docs/audits/README.md +10 -0
- package/template/docs/plans/.gitkeep +0 -0
- package/template/docs/plans/README.md +21 -0
- package/template/docs/plans/be/.gitkeep +0 -0
- package/template/docs/plans/be/README.md +11 -0
- package/template/docs/plans/fe/.gitkeep +0 -0
- package/template/docs/plans/fe/README.md +11 -0
- package/template/docs/plans/ia/.gitkeep +0 -0
- package/template/docs/plans/ia/README.md +17 -0
- package/template/docs/plans/ia/deep-dives/.gitkeep +0 -0
- package/template/docs/plans/ia/deep-dives/README.md +5 -0
- package/template/docs/plans/phases/.gitkeep +0 -0
- package/template/docs/plans/phases/README.md +11 -0
|
@@ -0,0 +1,1104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wordpress
|
|
3
|
+
description: "Expert WordPress development guide covering block themes, theme.json, template hierarchy, custom post types, taxonomies, ACF/meta fields, REST API, WP-CLI, hooks (actions/filters), plugin development, Gutenberg blocks (React-based), WP_Query optimization, wpdb, security (nonces, capabilities, escaping), caching, multisite, and headless WordPress patterns."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# WordPress Expert
|
|
8
|
+
|
|
9
|
+
## 1. Theme Development
|
|
10
|
+
|
|
11
|
+
### Block Themes (Full Site Editing)
|
|
12
|
+
|
|
13
|
+
Block themes replace traditional PHP templates with HTML template files and `theme.json` for global settings. This is the modern standard as of WordPress 6.0+.
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
my-theme/
|
|
17
|
+
style.css # Theme metadata (Name, Version, etc.)
|
|
18
|
+
theme.json # Global settings and styles
|
|
19
|
+
functions.php # Enqueues, supports, hooks
|
|
20
|
+
templates/ # Full-page templates (HTML)
|
|
21
|
+
index.html
|
|
22
|
+
single.html
|
|
23
|
+
page.html
|
|
24
|
+
archive.html
|
|
25
|
+
404.html
|
|
26
|
+
home.html
|
|
27
|
+
search.html
|
|
28
|
+
parts/ # Reusable template parts (HTML)
|
|
29
|
+
header.html
|
|
30
|
+
footer.html
|
|
31
|
+
sidebar.html
|
|
32
|
+
patterns/ # Block patterns (PHP)
|
|
33
|
+
hero.php
|
|
34
|
+
cta.php
|
|
35
|
+
assets/
|
|
36
|
+
css/
|
|
37
|
+
js/
|
|
38
|
+
images/
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### theme.json Configuration
|
|
42
|
+
|
|
43
|
+
`theme.json` controls design tokens, block settings, and style presets globally.
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"$schema": "https://schemas.wp.org/wp/6.5/theme.json",
|
|
48
|
+
"version": 3,
|
|
49
|
+
"settings": {
|
|
50
|
+
"color": {
|
|
51
|
+
"palette": [
|
|
52
|
+
{ "slug": "primary", "color": "#1a1a2e", "name": "Primary" },
|
|
53
|
+
{ "slug": "secondary", "color": "#e94560", "name": "Secondary" },
|
|
54
|
+
{ "slug": "surface", "color": "#f5f5f5", "name": "Surface" }
|
|
55
|
+
],
|
|
56
|
+
"custom": false,
|
|
57
|
+
"defaultPalette": false
|
|
58
|
+
},
|
|
59
|
+
"typography": {
|
|
60
|
+
"fontFamilies": [
|
|
61
|
+
{
|
|
62
|
+
"fontFamily": "Inter, sans-serif",
|
|
63
|
+
"slug": "body",
|
|
64
|
+
"name": "Body",
|
|
65
|
+
"fontFace": [
|
|
66
|
+
{
|
|
67
|
+
"fontFamily": "Inter",
|
|
68
|
+
"fontWeight": "400 700",
|
|
69
|
+
"fontStyle": "normal",
|
|
70
|
+
"fontDisplay": "swap",
|
|
71
|
+
"src": ["file:./assets/fonts/inter.woff2"]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"fontSizes": [
|
|
77
|
+
{ "slug": "small", "size": "0.875rem", "name": "Small" },
|
|
78
|
+
{ "slug": "medium", "size": "1rem", "name": "Medium" },
|
|
79
|
+
{ "slug": "large", "size": "1.5rem", "name": "Large" },
|
|
80
|
+
{ "slug": "x-large", "size": "2.25rem", "name": "Extra Large" }
|
|
81
|
+
],
|
|
82
|
+
"fluid": true
|
|
83
|
+
},
|
|
84
|
+
"spacing": {
|
|
85
|
+
"units": ["px", "rem", "%"],
|
|
86
|
+
"spacingSizes": [
|
|
87
|
+
{ "slug": "10", "size": "0.5rem", "name": "Tight" },
|
|
88
|
+
{ "slug": "20", "size": "1rem", "name": "Base" },
|
|
89
|
+
{ "slug": "30", "size": "1.5rem", "name": "Loose" },
|
|
90
|
+
{ "slug": "40", "size": "2rem", "name": "Wide" }
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"layout": {
|
|
94
|
+
"contentSize": "720px",
|
|
95
|
+
"wideSize": "1200px"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"styles": {
|
|
99
|
+
"color": {
|
|
100
|
+
"background": "var(--wp--preset--color--surface)",
|
|
101
|
+
"text": "var(--wp--preset--color--primary)"
|
|
102
|
+
},
|
|
103
|
+
"typography": {
|
|
104
|
+
"fontFamily": "var(--wp--preset--font-family--body)",
|
|
105
|
+
"fontSize": "var(--wp--preset--font-size--medium)",
|
|
106
|
+
"lineHeight": "1.6"
|
|
107
|
+
},
|
|
108
|
+
"elements": {
|
|
109
|
+
"link": {
|
|
110
|
+
"color": { "text": "var(--wp--preset--color--secondary)" }
|
|
111
|
+
},
|
|
112
|
+
"heading": {
|
|
113
|
+
"typography": { "fontWeight": "700" }
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Template Hierarchy
|
|
121
|
+
|
|
122
|
+
WordPress resolves templates in a specific priority order. Understand this to control which template renders.
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Single Post: single-{post-type}-{slug}.html -> single-{post-type}.html -> single.html -> singular.html -> index.html
|
|
126
|
+
Page: page-{slug}.html -> page-{id}.html -> page.html -> singular.html -> index.html
|
|
127
|
+
Category: category-{slug}.html -> category-{id}.html -> category.html -> archive.html -> index.html
|
|
128
|
+
Taxonomy: taxonomy-{taxonomy}-{term}.html -> taxonomy-{taxonomy}.html -> taxonomy.html -> archive.html -> index.html
|
|
129
|
+
Author: author-{nicename}.html -> author-{id}.html -> author.html -> archive.html -> index.html
|
|
130
|
+
Custom PT: archive-{post-type}.html -> archive.html -> index.html
|
|
131
|
+
Search: search.html -> index.html
|
|
132
|
+
404: 404.html -> index.html
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Block Template Example
|
|
136
|
+
|
|
137
|
+
```html
|
|
138
|
+
<!-- templates/single.html -->
|
|
139
|
+
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
|
|
140
|
+
|
|
141
|
+
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
|
|
142
|
+
<main class="wp-block-group">
|
|
143
|
+
<!-- wp:post-title {"level":1} /-->
|
|
144
|
+
<!-- wp:post-featured-image {"sizeSlug":"large"} /-->
|
|
145
|
+
<!-- wp:post-date /-->
|
|
146
|
+
<!-- wp:post-content {"layout":{"type":"constrained"}} /-->
|
|
147
|
+
<!-- wp:post-terms {"term":"category"} /-->
|
|
148
|
+
</main>
|
|
149
|
+
<!-- /wp:group -->
|
|
150
|
+
|
|
151
|
+
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 2. Custom Post Types and Taxonomies
|
|
157
|
+
|
|
158
|
+
### Registering a Custom Post Type
|
|
159
|
+
|
|
160
|
+
```php
|
|
161
|
+
// functions.php or a custom plugin
|
|
162
|
+
add_action('init', function () {
|
|
163
|
+
register_post_type('project', [
|
|
164
|
+
'labels' => [
|
|
165
|
+
'name' => 'Projects',
|
|
166
|
+
'singular_name' => 'Project',
|
|
167
|
+
'add_new_item' => 'Add New Project',
|
|
168
|
+
'edit_item' => 'Edit Project',
|
|
169
|
+
'view_item' => 'View Project',
|
|
170
|
+
'search_items' => 'Search Projects',
|
|
171
|
+
'not_found' => 'No projects found',
|
|
172
|
+
],
|
|
173
|
+
'public' => true,
|
|
174
|
+
'has_archive' => true,
|
|
175
|
+
'show_in_rest' => true, // Required for Gutenberg and REST API
|
|
176
|
+
'supports' => ['title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'],
|
|
177
|
+
'menu_icon' => 'dashicons-portfolio',
|
|
178
|
+
'rewrite' => ['slug' => 'projects', 'with_front' => false],
|
|
179
|
+
'capability_type' => 'post',
|
|
180
|
+
'map_meta_cap' => true,
|
|
181
|
+
]);
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Registering a Custom Taxonomy
|
|
186
|
+
|
|
187
|
+
```php
|
|
188
|
+
add_action('init', function () {
|
|
189
|
+
register_taxonomy('project_type', ['project'], [
|
|
190
|
+
'labels' => [
|
|
191
|
+
'name' => 'Project Types',
|
|
192
|
+
'singular_name' => 'Project Type',
|
|
193
|
+
'add_new_item' => 'Add New Project Type',
|
|
194
|
+
],
|
|
195
|
+
'public' => true,
|
|
196
|
+
'hierarchical' => true, // true = categories, false = tags
|
|
197
|
+
'show_in_rest' => true,
|
|
198
|
+
'show_admin_column' => true,
|
|
199
|
+
'rewrite' => ['slug' => 'project-type'],
|
|
200
|
+
]);
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### ACF / Custom Meta Fields
|
|
205
|
+
|
|
206
|
+
```php
|
|
207
|
+
// Register meta fields for REST API exposure (without ACF)
|
|
208
|
+
add_action('init', function () {
|
|
209
|
+
register_post_meta('project', 'project_url', [
|
|
210
|
+
'show_in_rest' => true,
|
|
211
|
+
'single' => true,
|
|
212
|
+
'type' => 'string',
|
|
213
|
+
'sanitize_callback' => 'esc_url_raw',
|
|
214
|
+
]);
|
|
215
|
+
|
|
216
|
+
register_post_meta('project', 'project_year', [
|
|
217
|
+
'show_in_rest' => true,
|
|
218
|
+
'single' => true,
|
|
219
|
+
'type' => 'integer',
|
|
220
|
+
'sanitize_callback' => 'absint',
|
|
221
|
+
]);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
// With ACF: fields are auto-registered. Access with get_field():
|
|
225
|
+
$url = get_field('project_url', $post_id);
|
|
226
|
+
$year = get_field('project_year', $post_id);
|
|
227
|
+
|
|
228
|
+
// ACF fields in REST API (requires ACF to REST API plugin or manual registration):
|
|
229
|
+
add_filter('acf/settings/rest_api_format', function () {
|
|
230
|
+
return 'standard';
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## 3. REST API
|
|
237
|
+
|
|
238
|
+
### Custom Endpoints
|
|
239
|
+
|
|
240
|
+
```php
|
|
241
|
+
add_action('rest_api_init', function () {
|
|
242
|
+
register_rest_route('myapp/v1', '/projects', [
|
|
243
|
+
'methods' => 'GET',
|
|
244
|
+
'callback' => 'myapp_get_projects',
|
|
245
|
+
'permission_callback' => '__return_true', // Public endpoint
|
|
246
|
+
'args' => [
|
|
247
|
+
'per_page' => [
|
|
248
|
+
'default' => 10,
|
|
249
|
+
'validate_callback' => function ($value) {
|
|
250
|
+
return is_numeric($value) && $value > 0 && $value <= 100;
|
|
251
|
+
},
|
|
252
|
+
'sanitize_callback' => 'absint',
|
|
253
|
+
],
|
|
254
|
+
'project_type' => [
|
|
255
|
+
'default' => '',
|
|
256
|
+
'sanitize_callback' => 'sanitize_text_field',
|
|
257
|
+
],
|
|
258
|
+
],
|
|
259
|
+
]);
|
|
260
|
+
|
|
261
|
+
register_rest_route('myapp/v1', '/projects/(?P<id>\d+)', [
|
|
262
|
+
'methods' => 'GET',
|
|
263
|
+
'callback' => 'myapp_get_project',
|
|
264
|
+
'permission_callback' => '__return_true',
|
|
265
|
+
'args' => [
|
|
266
|
+
'id' => [
|
|
267
|
+
'validate_callback' => function ($value) {
|
|
268
|
+
return is_numeric($value);
|
|
269
|
+
},
|
|
270
|
+
],
|
|
271
|
+
],
|
|
272
|
+
]);
|
|
273
|
+
|
|
274
|
+
register_rest_route('myapp/v1', '/projects', [
|
|
275
|
+
'methods' => 'POST',
|
|
276
|
+
'callback' => 'myapp_create_project',
|
|
277
|
+
'permission_callback' => function () {
|
|
278
|
+
return current_user_can('edit_posts');
|
|
279
|
+
},
|
|
280
|
+
]);
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
function myapp_get_projects(WP_REST_Request $request): WP_REST_Response {
|
|
284
|
+
$args = [
|
|
285
|
+
'post_type' => 'project',
|
|
286
|
+
'posts_per_page' => $request->get_param('per_page'),
|
|
287
|
+
'post_status' => 'publish',
|
|
288
|
+
];
|
|
289
|
+
|
|
290
|
+
$type = $request->get_param('project_type');
|
|
291
|
+
if (!empty($type)) {
|
|
292
|
+
$args['tax_query'] = [[
|
|
293
|
+
'taxonomy' => 'project_type',
|
|
294
|
+
'field' => 'slug',
|
|
295
|
+
'terms' => $type,
|
|
296
|
+
]];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
$query = new WP_Query($args);
|
|
300
|
+
$data = array_map('myapp_format_project', $query->posts);
|
|
301
|
+
|
|
302
|
+
return new WP_REST_Response([
|
|
303
|
+
'data' => $data,
|
|
304
|
+
'total' => $query->found_posts,
|
|
305
|
+
'pages' => $query->max_num_pages,
|
|
306
|
+
], 200);
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### REST API Authentication
|
|
311
|
+
|
|
312
|
+
```php
|
|
313
|
+
// Application Passwords (built-in since WP 5.6)
|
|
314
|
+
// Users generate passwords in their profile.
|
|
315
|
+
// Client sends: Authorization: Basic base64(username:app-password)
|
|
316
|
+
|
|
317
|
+
// Nonce-based auth (for logged-in frontend JS)
|
|
318
|
+
wp_localize_script('my-script', 'myAppData', [
|
|
319
|
+
'restUrl' => rest_url('myapp/v1/'),
|
|
320
|
+
'nonce' => wp_create_nonce('wp_rest'),
|
|
321
|
+
]);
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
```javascript
|
|
325
|
+
// Frontend JS with nonce auth
|
|
326
|
+
const response = await fetch(myAppData.restUrl + 'projects', {
|
|
327
|
+
method: 'POST',
|
|
328
|
+
headers: {
|
|
329
|
+
'Content-Type': 'application/json',
|
|
330
|
+
'X-WP-Nonce': myAppData.nonce,
|
|
331
|
+
},
|
|
332
|
+
body: JSON.stringify({ title: 'New Project' }),
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 4. WP-CLI
|
|
339
|
+
|
|
340
|
+
### Essential Commands
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
# Core
|
|
344
|
+
wp core download
|
|
345
|
+
wp core install --url="example.com" --title="Site" --admin_user=admin --admin_email=admin@example.com
|
|
346
|
+
wp core update
|
|
347
|
+
wp core version
|
|
348
|
+
|
|
349
|
+
# Plugins
|
|
350
|
+
wp plugin install woocommerce --activate
|
|
351
|
+
wp plugin list --status=active --format=table
|
|
352
|
+
wp plugin deactivate akismet
|
|
353
|
+
wp plugin delete hello
|
|
354
|
+
|
|
355
|
+
# Themes
|
|
356
|
+
wp theme install flavor --activate
|
|
357
|
+
wp theme list
|
|
358
|
+
|
|
359
|
+
# Database
|
|
360
|
+
wp db export backup.sql
|
|
361
|
+
wp db import backup.sql
|
|
362
|
+
wp db query "SELECT ID, user_login FROM wp_users LIMIT 5"
|
|
363
|
+
wp db optimize
|
|
364
|
+
wp db repair
|
|
365
|
+
|
|
366
|
+
# Search and replace (safe for serialized data)
|
|
367
|
+
wp search-replace 'http://old.com' 'https://new.com' --dry-run
|
|
368
|
+
wp search-replace 'http://old.com' 'https://new.com' --all-tables
|
|
369
|
+
|
|
370
|
+
# Users
|
|
371
|
+
wp user create editor editor@example.com --role=editor --user_pass=secure123
|
|
372
|
+
wp user list --role=administrator
|
|
373
|
+
|
|
374
|
+
# Posts
|
|
375
|
+
wp post create --post_type=project --post_title='My Project' --post_status=publish
|
|
376
|
+
wp post list --post_type=project --format=json
|
|
377
|
+
wp post delete 123 --force
|
|
378
|
+
|
|
379
|
+
# Transients and cache
|
|
380
|
+
wp transient delete --all
|
|
381
|
+
wp cache flush
|
|
382
|
+
|
|
383
|
+
# Cron
|
|
384
|
+
wp cron event list
|
|
385
|
+
wp cron event run --all
|
|
386
|
+
|
|
387
|
+
# Scaffold
|
|
388
|
+
wp scaffold post-type project --label="Project" --textdomain="mytheme"
|
|
389
|
+
wp scaffold taxonomy project_type --post_types=project --textdomain="mytheme"
|
|
390
|
+
wp scaffold block my-block --title="My Block" --namespace="myapp"
|
|
391
|
+
wp scaffold plugin my-plugin
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## 5. Hooks System (Actions and Filters)
|
|
397
|
+
|
|
398
|
+
### Actions -- Execute Code at Specific Points
|
|
399
|
+
|
|
400
|
+
```php
|
|
401
|
+
// Register an action
|
|
402
|
+
add_action('save_post_project', function (int $post_id, WP_Post $post, bool $update): void {
|
|
403
|
+
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
if (wp_is_post_revision($post_id)) {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Clear cached project list when a project is saved
|
|
411
|
+
delete_transient('myapp_projects_list');
|
|
412
|
+
|
|
413
|
+
// Sync to external API
|
|
414
|
+
myapp_sync_project_to_external($post_id);
|
|
415
|
+
}, 10, 3);
|
|
416
|
+
|
|
417
|
+
// Common action hooks and when they fire:
|
|
418
|
+
// init -- After WP loads, before headers sent
|
|
419
|
+
// wp_enqueue_scripts -- Enqueue frontend CSS/JS
|
|
420
|
+
// admin_enqueue_scripts -- Enqueue admin CSS/JS
|
|
421
|
+
// rest_api_init -- Register REST routes
|
|
422
|
+
// save_post -- After a post is saved
|
|
423
|
+
// delete_post -- Before a post is deleted
|
|
424
|
+
// wp_login -- After user logs in
|
|
425
|
+
// wp_logout -- After user logs out
|
|
426
|
+
// template_redirect -- Before template loads, after query is set
|
|
427
|
+
// wp_head -- Inside <head> tag
|
|
428
|
+
// wp_footer -- Before </body> tag
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Filters -- Modify Data in the Pipeline
|
|
432
|
+
|
|
433
|
+
```php
|
|
434
|
+
// Modify the main query
|
|
435
|
+
add_filter('pre_get_posts', function (WP_Query $query): WP_Query {
|
|
436
|
+
if (!is_admin() && $query->is_main_query() && is_post_type_archive('project')) {
|
|
437
|
+
$query->set('posts_per_page', 12);
|
|
438
|
+
$query->set('orderby', 'menu_order');
|
|
439
|
+
$query->set('order', 'ASC');
|
|
440
|
+
}
|
|
441
|
+
return $query;
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
// Modify REST API response
|
|
445
|
+
add_filter('rest_prepare_project', function (WP_REST_Response $response, WP_Post $post): WP_REST_Response {
|
|
446
|
+
$response->data['project_url'] = get_post_meta($post->ID, 'project_url', true);
|
|
447
|
+
$response->data['project_year'] = (int) get_post_meta($post->ID, 'project_year', true);
|
|
448
|
+
return $response;
|
|
449
|
+
}, 10, 2);
|
|
450
|
+
|
|
451
|
+
// Add custom image sizes
|
|
452
|
+
add_action('after_setup_theme', function (): void {
|
|
453
|
+
add_image_size('project-card', 600, 400, true);
|
|
454
|
+
add_image_size('project-hero', 1200, 600, true);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// Filter the image sizes available in the editor
|
|
458
|
+
add_filter('image_size_names_choose', function (array $sizes): array {
|
|
459
|
+
$sizes['project-card'] = 'Project Card';
|
|
460
|
+
$sizes['project-hero'] = 'Project Hero';
|
|
461
|
+
return $sizes;
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## 6. Plugin Development
|
|
468
|
+
|
|
469
|
+
### Plugin Structure
|
|
470
|
+
|
|
471
|
+
```
|
|
472
|
+
my-plugin/
|
|
473
|
+
my-plugin.php # Main plugin file with header
|
|
474
|
+
includes/
|
|
475
|
+
class-admin.php # Admin functionality
|
|
476
|
+
class-api.php # REST API endpoints
|
|
477
|
+
class-cpt.php # Custom post types
|
|
478
|
+
assets/
|
|
479
|
+
css/
|
|
480
|
+
js/
|
|
481
|
+
templates/ # Frontend templates
|
|
482
|
+
languages/ # Translation files
|
|
483
|
+
readme.txt # WordPress.org readme
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Main Plugin File
|
|
487
|
+
|
|
488
|
+
```php
|
|
489
|
+
<?php
|
|
490
|
+
/**
|
|
491
|
+
* Plugin Name: My Plugin
|
|
492
|
+
* Description: A well-structured WordPress plugin.
|
|
493
|
+
* Version: 1.0.0
|
|
494
|
+
* Author: Developer Name
|
|
495
|
+
* Text Domain: my-plugin
|
|
496
|
+
* Requires at least: 6.0
|
|
497
|
+
* Requires PHP: 8.1
|
|
498
|
+
*/
|
|
499
|
+
|
|
500
|
+
defined('ABSPATH') || exit;
|
|
501
|
+
|
|
502
|
+
define('MY_PLUGIN_VERSION', '1.0.0');
|
|
503
|
+
define('MY_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
|
504
|
+
define('MY_PLUGIN_URL', plugin_dir_url(__FILE__));
|
|
505
|
+
|
|
506
|
+
// Autoload classes
|
|
507
|
+
spl_autoload_register(function (string $class): void {
|
|
508
|
+
$prefix = 'MyPlugin\\';
|
|
509
|
+
if (strpos($class, $prefix) !== 0) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
$relative = substr($class, strlen($prefix));
|
|
513
|
+
$file = MY_PLUGIN_DIR . 'includes/class-' . strtolower(str_replace('\\', '-', $relative)) . '.php';
|
|
514
|
+
if (file_exists($file)) {
|
|
515
|
+
require $file;
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
// Activation hook
|
|
520
|
+
register_activation_hook(__FILE__, function (): void {
|
|
521
|
+
flush_rewrite_rules();
|
|
522
|
+
// Create custom tables, set default options, etc.
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// Deactivation hook
|
|
526
|
+
register_deactivation_hook(__FILE__, function (): void {
|
|
527
|
+
flush_rewrite_rules();
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// Initialize the plugin
|
|
531
|
+
add_action('plugins_loaded', function (): void {
|
|
532
|
+
new MyPlugin\Admin();
|
|
533
|
+
new MyPlugin\API();
|
|
534
|
+
new MyPlugin\CPT();
|
|
535
|
+
});
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## 7. Gutenberg Block Development
|
|
541
|
+
|
|
542
|
+
### Block Registration (React-based)
|
|
543
|
+
|
|
544
|
+
```javascript
|
|
545
|
+
// src/blocks/project-card/index.js
|
|
546
|
+
import { registerBlockType } from '@wordpress/blocks';
|
|
547
|
+
import { useBlockProps, InspectorControls, RichText } from '@wordpress/block-editor';
|
|
548
|
+
import { PanelBody, TextControl, ToggleControl } from '@wordpress/components';
|
|
549
|
+
|
|
550
|
+
registerBlockType('myapp/project-card', {
|
|
551
|
+
title: 'Project Card',
|
|
552
|
+
icon: 'portfolio',
|
|
553
|
+
category: 'widgets',
|
|
554
|
+
attributes: {
|
|
555
|
+
title: { type: 'string', default: '' },
|
|
556
|
+
description: { type: 'string', default: '' },
|
|
557
|
+
url: { type: 'string', default: '' },
|
|
558
|
+
showYear: { type: 'boolean', default: true },
|
|
559
|
+
},
|
|
560
|
+
|
|
561
|
+
edit({ attributes, setAttributes }) {
|
|
562
|
+
const blockProps = useBlockProps({ className: 'project-card' });
|
|
563
|
+
|
|
564
|
+
return (
|
|
565
|
+
<>
|
|
566
|
+
<InspectorControls>
|
|
567
|
+
<PanelBody title="Project Settings">
|
|
568
|
+
<TextControl
|
|
569
|
+
label="Project URL"
|
|
570
|
+
value={attributes.url}
|
|
571
|
+
onChange={(url) => setAttributes({ url })}
|
|
572
|
+
/>
|
|
573
|
+
<ToggleControl
|
|
574
|
+
label="Show Year"
|
|
575
|
+
checked={attributes.showYear}
|
|
576
|
+
onChange={(showYear) => setAttributes({ showYear })}
|
|
577
|
+
/>
|
|
578
|
+
</PanelBody>
|
|
579
|
+
</InspectorControls>
|
|
580
|
+
<div {...blockProps}>
|
|
581
|
+
<RichText
|
|
582
|
+
tagName="h3"
|
|
583
|
+
value={attributes.title}
|
|
584
|
+
onChange={(title) => setAttributes({ title })}
|
|
585
|
+
placeholder="Project title..."
|
|
586
|
+
/>
|
|
587
|
+
<RichText
|
|
588
|
+
tagName="p"
|
|
589
|
+
value={attributes.description}
|
|
590
|
+
onChange={(description) => setAttributes({ description })}
|
|
591
|
+
placeholder="Project description..."
|
|
592
|
+
/>
|
|
593
|
+
</div>
|
|
594
|
+
</>
|
|
595
|
+
);
|
|
596
|
+
},
|
|
597
|
+
|
|
598
|
+
save({ attributes }) {
|
|
599
|
+
const blockProps = useBlockProps.save({ className: 'project-card' });
|
|
600
|
+
|
|
601
|
+
return (
|
|
602
|
+
<div {...blockProps}>
|
|
603
|
+
<RichText.Content tagName="h3" value={attributes.title} />
|
|
604
|
+
<RichText.Content tagName="p" value={attributes.description} />
|
|
605
|
+
{attributes.url && (
|
|
606
|
+
<a href={attributes.url} target="_blank" rel="noopener noreferrer">
|
|
607
|
+
View Project
|
|
608
|
+
</a>
|
|
609
|
+
)}
|
|
610
|
+
</div>
|
|
611
|
+
);
|
|
612
|
+
},
|
|
613
|
+
});
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### block.json
|
|
617
|
+
|
|
618
|
+
```json
|
|
619
|
+
{
|
|
620
|
+
"$schema": "https://schemas.wp.org/trunk/block.json",
|
|
621
|
+
"apiVersion": 3,
|
|
622
|
+
"name": "myapp/project-card",
|
|
623
|
+
"title": "Project Card",
|
|
624
|
+
"category": "widgets",
|
|
625
|
+
"icon": "portfolio",
|
|
626
|
+
"description": "Display a project card with title, description, and link.",
|
|
627
|
+
"textdomain": "myapp",
|
|
628
|
+
"editorScript": "file:./index.js",
|
|
629
|
+
"editorStyle": "file:./index.css",
|
|
630
|
+
"style": "file:./style-index.css",
|
|
631
|
+
"attributes": {
|
|
632
|
+
"title": { "type": "string", "default": "" },
|
|
633
|
+
"description": { "type": "string", "default": "" },
|
|
634
|
+
"url": { "type": "string", "default": "" },
|
|
635
|
+
"showYear": { "type": "boolean", "default": true }
|
|
636
|
+
},
|
|
637
|
+
"supports": {
|
|
638
|
+
"html": false,
|
|
639
|
+
"align": ["wide", "full"],
|
|
640
|
+
"color": { "background": true, "text": true },
|
|
641
|
+
"spacing": { "margin": true, "padding": true }
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
---
|
|
647
|
+
|
|
648
|
+
## 8. WP_Query Optimization
|
|
649
|
+
|
|
650
|
+
### Efficient Query Patterns
|
|
651
|
+
|
|
652
|
+
```php
|
|
653
|
+
// GOOD: Fetch only what you need
|
|
654
|
+
$projects = new WP_Query([
|
|
655
|
+
'post_type' => 'project',
|
|
656
|
+
'posts_per_page' => 12,
|
|
657
|
+
'post_status' => 'publish',
|
|
658
|
+
'fields' => 'ids', // Return only IDs if you do not need full objects
|
|
659
|
+
'no_found_rows' => true, // Skip SQL_CALC_FOUND_ROWS if you do not need pagination
|
|
660
|
+
'update_post_meta_cache' => false, // Skip meta cache priming if you do not use meta
|
|
661
|
+
'update_post_term_cache' => false, // Skip term cache priming if you do not use terms
|
|
662
|
+
]);
|
|
663
|
+
|
|
664
|
+
// BAD: Querying all posts with all caches
|
|
665
|
+
$projects = new WP_Query([
|
|
666
|
+
'post_type' => 'project',
|
|
667
|
+
'posts_per_page' => -1, // Never use -1 in production queries
|
|
668
|
+
]);
|
|
669
|
+
|
|
670
|
+
// Meta query with index-friendly patterns
|
|
671
|
+
$featured = new WP_Query([
|
|
672
|
+
'post_type' => 'project',
|
|
673
|
+
'posts_per_page' => 6,
|
|
674
|
+
'meta_query' => [
|
|
675
|
+
'relation' => 'AND',
|
|
676
|
+
[
|
|
677
|
+
'key' => 'is_featured',
|
|
678
|
+
'value' => '1',
|
|
679
|
+
'compare' => '=',
|
|
680
|
+
],
|
|
681
|
+
[
|
|
682
|
+
'key' => 'project_year',
|
|
683
|
+
'value' => 2024,
|
|
684
|
+
'compare' => '>=',
|
|
685
|
+
'type' => 'NUMERIC',
|
|
686
|
+
],
|
|
687
|
+
],
|
|
688
|
+
'orderby' => 'meta_value_num',
|
|
689
|
+
'meta_key' => 'project_year',
|
|
690
|
+
'order' => 'DESC',
|
|
691
|
+
]);
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### Direct Database Queries (wpdb)
|
|
695
|
+
|
|
696
|
+
```php
|
|
697
|
+
global $wpdb;
|
|
698
|
+
|
|
699
|
+
// ALWAYS use prepared statements
|
|
700
|
+
$results = $wpdb->get_results(
|
|
701
|
+
$wpdb->prepare(
|
|
702
|
+
"SELECT p.ID, p.post_title, pm.meta_value AS project_url
|
|
703
|
+
FROM {$wpdb->posts} p
|
|
704
|
+
INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = %s
|
|
705
|
+
WHERE p.post_type = %s AND p.post_status = %s
|
|
706
|
+
ORDER BY p.post_date DESC
|
|
707
|
+
LIMIT %d",
|
|
708
|
+
'project_url',
|
|
709
|
+
'project',
|
|
710
|
+
'publish',
|
|
711
|
+
20
|
|
712
|
+
)
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
// Insert with prepared statements
|
|
716
|
+
$wpdb->insert(
|
|
717
|
+
$wpdb->prefix . 'custom_table',
|
|
718
|
+
[
|
|
719
|
+
'user_id' => $user_id,
|
|
720
|
+
'score' => $score,
|
|
721
|
+
'created_at' => current_time('mysql'),
|
|
722
|
+
],
|
|
723
|
+
['%d', '%d', '%s']
|
|
724
|
+
);
|
|
725
|
+
|
|
726
|
+
// Update with prepared statements
|
|
727
|
+
$wpdb->update(
|
|
728
|
+
$wpdb->prefix . 'custom_table',
|
|
729
|
+
['score' => $new_score], // data
|
|
730
|
+
['id' => $row_id], // where
|
|
731
|
+
['%d'], // data format
|
|
732
|
+
['%d'] // where format
|
|
733
|
+
);
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
---
|
|
737
|
+
|
|
738
|
+
## 9. Security
|
|
739
|
+
|
|
740
|
+
### Nonces -- CSRF Protection
|
|
741
|
+
|
|
742
|
+
```php
|
|
743
|
+
// Generate nonce in form
|
|
744
|
+
wp_nonce_field('myapp_save_project', 'myapp_nonce');
|
|
745
|
+
|
|
746
|
+
// Verify nonce on submission
|
|
747
|
+
if (!isset($_POST['myapp_nonce']) || !wp_verify_nonce($_POST['myapp_nonce'], 'myapp_save_project')) {
|
|
748
|
+
wp_die('Security check failed.');
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// Nonce URLs for action links
|
|
752
|
+
$delete_url = wp_nonce_url(
|
|
753
|
+
admin_url('admin-post.php?action=delete_project&id=' . $post_id),
|
|
754
|
+
'delete_project_' . $post_id
|
|
755
|
+
);
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
### Capability Checks
|
|
759
|
+
|
|
760
|
+
```php
|
|
761
|
+
// Always check capabilities before performing actions
|
|
762
|
+
if (!current_user_can('edit_post', $post_id)) {
|
|
763
|
+
wp_die('You do not have permission to edit this post.');
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// Custom capabilities for custom post types
|
|
767
|
+
register_post_type('project', [
|
|
768
|
+
'capability_type' => ['project', 'projects'],
|
|
769
|
+
'map_meta_cap' => true,
|
|
770
|
+
]);
|
|
771
|
+
|
|
772
|
+
// Grant capabilities to a role
|
|
773
|
+
$editor = get_role('editor');
|
|
774
|
+
$editor->add_cap('edit_projects');
|
|
775
|
+
$editor->add_cap('publish_projects');
|
|
776
|
+
$editor->add_cap('delete_projects');
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### Escaping Output
|
|
780
|
+
|
|
781
|
+
```php
|
|
782
|
+
// ALWAYS escape output based on context
|
|
783
|
+
echo esc_html($user_input); // HTML body text
|
|
784
|
+
echo esc_attr($user_input); // HTML attribute values
|
|
785
|
+
echo esc_url($user_input); // URLs (href, src)
|
|
786
|
+
echo esc_js($user_input); // Inline JavaScript strings
|
|
787
|
+
echo wp_kses_post($user_input); // Allow safe HTML (post content subset)
|
|
788
|
+
echo wp_kses($input, ['a' => ['href' => []]]); // Custom allowed HTML
|
|
789
|
+
|
|
790
|
+
// Sanitize input on save
|
|
791
|
+
$clean_title = sanitize_text_field($_POST['title']);
|
|
792
|
+
$clean_email = sanitize_email($_POST['email']);
|
|
793
|
+
$clean_url = esc_url_raw($_POST['url']);
|
|
794
|
+
$clean_html = wp_kses_post($_POST['content']);
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
## 10. Caching
|
|
800
|
+
|
|
801
|
+
### Transients API
|
|
802
|
+
|
|
803
|
+
```php
|
|
804
|
+
// Cache expensive query results
|
|
805
|
+
function myapp_get_featured_projects(): array {
|
|
806
|
+
$cached = get_transient('myapp_featured_projects');
|
|
807
|
+
if ($cached !== false) {
|
|
808
|
+
return $cached;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
$query = new WP_Query([
|
|
812
|
+
'post_type' => 'project',
|
|
813
|
+
'posts_per_page' => 6,
|
|
814
|
+
'meta_key' => 'is_featured',
|
|
815
|
+
'meta_value' => '1',
|
|
816
|
+
]);
|
|
817
|
+
|
|
818
|
+
$projects = array_map(function ($post) {
|
|
819
|
+
return [
|
|
820
|
+
'id' => $post->ID,
|
|
821
|
+
'title' => $post->post_title,
|
|
822
|
+
'url' => get_permalink($post),
|
|
823
|
+
];
|
|
824
|
+
}, $query->posts);
|
|
825
|
+
|
|
826
|
+
set_transient('myapp_featured_projects', $projects, HOUR_IN_SECONDS);
|
|
827
|
+
|
|
828
|
+
return $projects;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
// Invalidate cache when projects change
|
|
832
|
+
add_action('save_post_project', function (): void {
|
|
833
|
+
delete_transient('myapp_featured_projects');
|
|
834
|
+
});
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
### Object Cache (Persistent)
|
|
838
|
+
|
|
839
|
+
```php
|
|
840
|
+
// Object cache works with Redis/Memcached via drop-in plugins
|
|
841
|
+
// (redis-cache, memcached, etc.)
|
|
842
|
+
|
|
843
|
+
// Store in object cache (survives the request if persistent cache is configured)
|
|
844
|
+
wp_cache_set('user_scores', $scores, 'myapp', 3600);
|
|
845
|
+
|
|
846
|
+
// Retrieve from object cache
|
|
847
|
+
$scores = wp_cache_get('user_scores', 'myapp');
|
|
848
|
+
if ($scores === false) {
|
|
849
|
+
$scores = myapp_calculate_scores();
|
|
850
|
+
wp_cache_set('user_scores', $scores, 'myapp', 3600);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
// Delete from cache
|
|
854
|
+
wp_cache_delete('user_scores', 'myapp');
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
### Fragment Caching
|
|
858
|
+
|
|
859
|
+
```php
|
|
860
|
+
// Cache expensive template fragments
|
|
861
|
+
function myapp_render_sidebar(): string {
|
|
862
|
+
$cache_key = 'myapp_sidebar_' . get_the_ID();
|
|
863
|
+
$output = wp_cache_get($cache_key, 'myapp_fragments');
|
|
864
|
+
|
|
865
|
+
if ($output === false) {
|
|
866
|
+
ob_start();
|
|
867
|
+
// Expensive rendering logic here
|
|
868
|
+
get_template_part('parts/sidebar-widgets');
|
|
869
|
+
$output = ob_get_clean();
|
|
870
|
+
wp_cache_set($cache_key, $output, 'myapp_fragments', 300);
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
return $output;
|
|
874
|
+
}
|
|
875
|
+
```
|
|
876
|
+
|
|
877
|
+
---
|
|
878
|
+
|
|
879
|
+
## 11. Multisite
|
|
880
|
+
|
|
881
|
+
### Multisite Configuration
|
|
882
|
+
|
|
883
|
+
```php
|
|
884
|
+
// wp-config.php additions for multisite
|
|
885
|
+
define('WP_ALLOW_MULTISITE', true);
|
|
886
|
+
|
|
887
|
+
// After network setup:
|
|
888
|
+
define('MULTISITE', true);
|
|
889
|
+
define('SUBDOMAIN_INSTALL', false); // true for subdomain, false for subdirectory
|
|
890
|
+
define('DOMAIN_CURRENT_SITE', 'example.com');
|
|
891
|
+
define('PATH_CURRENT_SITE', '/');
|
|
892
|
+
define('SITE_ID_CURRENT_SITE', 1);
|
|
893
|
+
define('BLOG_ID_CURRENT_SITE', 1);
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
### Site Switching
|
|
897
|
+
|
|
898
|
+
```php
|
|
899
|
+
// Switch to another site in the network
|
|
900
|
+
switch_to_blog(2);
|
|
901
|
+
$posts = get_posts(['post_type' => 'post', 'numberposts' => 5]);
|
|
902
|
+
restore_current_blog(); // Always restore
|
|
903
|
+
|
|
904
|
+
// Get all sites
|
|
905
|
+
$sites = get_sites(['number' => 100, 'public' => 1]);
|
|
906
|
+
foreach ($sites as $site) {
|
|
907
|
+
switch_to_blog($site->blog_id);
|
|
908
|
+
// Do something per site
|
|
909
|
+
restore_current_blog();
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// Network-wide queries (use sparingly)
|
|
913
|
+
global $wpdb;
|
|
914
|
+
$blog_ids = $wpdb->get_col("SELECT blog_id FROM {$wpdb->blogs} WHERE public = 1");
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
---
|
|
918
|
+
|
|
919
|
+
## 12. Headless WordPress
|
|
920
|
+
|
|
921
|
+
### WPGraphQL
|
|
922
|
+
|
|
923
|
+
```graphql
|
|
924
|
+
# Query posts with WPGraphQL
|
|
925
|
+
query GetProjects {
|
|
926
|
+
projects(first: 10, where: { status: PUBLISH }) {
|
|
927
|
+
nodes {
|
|
928
|
+
id
|
|
929
|
+
title
|
|
930
|
+
slug
|
|
931
|
+
excerpt
|
|
932
|
+
featuredImage {
|
|
933
|
+
node {
|
|
934
|
+
sourceUrl(size: LARGE)
|
|
935
|
+
altText
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
projectFields {
|
|
939
|
+
projectUrl
|
|
940
|
+
projectYear
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
pageInfo {
|
|
944
|
+
hasNextPage
|
|
945
|
+
endCursor
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
# Mutations
|
|
951
|
+
mutation CreateProject($title: String!, $content: String!) {
|
|
952
|
+
createProject(input: { title: $title, content: $content, status: PUBLISH }) {
|
|
953
|
+
project {
|
|
954
|
+
id
|
|
955
|
+
slug
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
### Headless Frontend Pattern (Next.js)
|
|
962
|
+
|
|
963
|
+
```typescript
|
|
964
|
+
// lib/wordpress.ts
|
|
965
|
+
const WP_GRAPHQL_URL = process.env.NEXT_PUBLIC_WP_GRAPHQL_URL;
|
|
966
|
+
|
|
967
|
+
export async function fetchGraphQL<T>(query: string, variables?: Record<string, unknown>): Promise<T> {
|
|
968
|
+
const response = await fetch(WP_GRAPHQL_URL, {
|
|
969
|
+
method: 'POST',
|
|
970
|
+
headers: {
|
|
971
|
+
'Content-Type': 'application/json',
|
|
972
|
+
},
|
|
973
|
+
body: JSON.stringify({ query, variables }),
|
|
974
|
+
next: { revalidate: 60 }, // ISR: revalidate every 60 seconds
|
|
975
|
+
});
|
|
976
|
+
|
|
977
|
+
if (!response.ok) {
|
|
978
|
+
throw new Error('WordPress GraphQL request failed: ' + response.statusText);
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
const json = await response.json();
|
|
982
|
+
if (json.errors) {
|
|
983
|
+
throw new Error('GraphQL errors: ' + JSON.stringify(json.errors));
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
return json.data as T;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
// Usage in a Next.js page
|
|
990
|
+
export async function getStaticProps() {
|
|
991
|
+
const data = await fetchGraphQL<{ projects: { nodes: Project[] } }>(`
|
|
992
|
+
query {
|
|
993
|
+
projects(first: 12) {
|
|
994
|
+
nodes { id title slug excerpt }
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
`);
|
|
998
|
+
|
|
999
|
+
return {
|
|
1000
|
+
props: { projects: data.projects.nodes },
|
|
1001
|
+
revalidate: 60,
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
```
|
|
1005
|
+
|
|
1006
|
+
### REST API for Headless
|
|
1007
|
+
|
|
1008
|
+
```typescript
|
|
1009
|
+
// Fetching from WP REST API
|
|
1010
|
+
const WP_API_URL = process.env.NEXT_PUBLIC_WP_API_URL;
|
|
1011
|
+
|
|
1012
|
+
export async function getProjects(page = 1, perPage = 12): Promise<{ data: Project[]; total: number }> {
|
|
1013
|
+
const url = new URL(`${WP_API_URL}/wp/v2/projects`);
|
|
1014
|
+
url.searchParams.set('page', String(page));
|
|
1015
|
+
url.searchParams.set('per_page', String(perPage));
|
|
1016
|
+
url.searchParams.set('_embed', 'true'); // Include featured images, terms, etc.
|
|
1017
|
+
|
|
1018
|
+
const response = await fetch(url.toString(), {
|
|
1019
|
+
next: { revalidate: 60 },
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
return {
|
|
1023
|
+
data: await response.json(),
|
|
1024
|
+
total: parseInt(response.headers.get('X-WP-Total') || '0', 10),
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
---
|
|
1030
|
+
|
|
1031
|
+
## 13. Common Anti-Patterns
|
|
1032
|
+
|
|
1033
|
+
### Querying Without Limits
|
|
1034
|
+
|
|
1035
|
+
```php
|
|
1036
|
+
// BAD: Loads all posts into memory
|
|
1037
|
+
$all = new WP_Query(['post_type' => 'project', 'posts_per_page' => -1]);
|
|
1038
|
+
|
|
1039
|
+
// GOOD: Paginate or set a reasonable limit
|
|
1040
|
+
$page = new WP_Query(['post_type' => 'project', 'posts_per_page' => 20, 'paged' => $current_page]);
|
|
1041
|
+
```
|
|
1042
|
+
|
|
1043
|
+
### Direct Database Access Without Preparation
|
|
1044
|
+
|
|
1045
|
+
```php
|
|
1046
|
+
// BAD: SQL injection vulnerability
|
|
1047
|
+
$wpdb->query("DELETE FROM {$wpdb->posts} WHERE ID = " . $_GET['id']);
|
|
1048
|
+
|
|
1049
|
+
// GOOD: Always use prepare()
|
|
1050
|
+
$wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->posts} WHERE ID = %d", absint($_GET['id'])));
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
### Skipping Nonce Verification
|
|
1054
|
+
|
|
1055
|
+
```php
|
|
1056
|
+
// BAD: No CSRF protection
|
|
1057
|
+
if (isset($_POST['action']) && $_POST['action'] === 'save') {
|
|
1058
|
+
update_post_meta($id, 'key', $_POST['value']);
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
// GOOD: Verify nonce first
|
|
1062
|
+
if (!wp_verify_nonce($_POST['_nonce'], 'save_action')) {
|
|
1063
|
+
wp_die('Invalid nonce');
|
|
1064
|
+
}
|
|
1065
|
+
```
|
|
1066
|
+
|
|
1067
|
+
### Loading Everything in functions.php
|
|
1068
|
+
|
|
1069
|
+
```php
|
|
1070
|
+
// BAD: 2000-line functions.php
|
|
1071
|
+
// GOOD: Split into focused includes
|
|
1072
|
+
require_once get_template_directory() . '/inc/post-types.php';
|
|
1073
|
+
require_once get_template_directory() . '/inc/taxonomies.php';
|
|
1074
|
+
require_once get_template_directory() . '/inc/rest-api.php';
|
|
1075
|
+
require_once get_template_directory() . '/inc/blocks.php';
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
---
|
|
1079
|
+
|
|
1080
|
+
## 14. Critical Reminders
|
|
1081
|
+
|
|
1082
|
+
### ALWAYS
|
|
1083
|
+
|
|
1084
|
+
- Use `show_in_rest => true` on custom post types and taxonomies for Gutenberg compatibility
|
|
1085
|
+
- Escape all output with the appropriate function (`esc_html`, `esc_attr`, `esc_url`)
|
|
1086
|
+
- Sanitize all input (`sanitize_text_field`, `absint`, `esc_url_raw`)
|
|
1087
|
+
- Verify nonces on form submissions and AJAX handlers
|
|
1088
|
+
- Check capabilities before performing privileged actions
|
|
1089
|
+
- Use `$wpdb->prepare()` for all direct database queries
|
|
1090
|
+
- Use `no_found_rows => true` when pagination is not needed
|
|
1091
|
+
- Invalidate caches (transients, object cache) when underlying data changes
|
|
1092
|
+
- Prefix all function names, hooks, meta keys, and option names with your namespace
|
|
1093
|
+
|
|
1094
|
+
### NEVER
|
|
1095
|
+
|
|
1096
|
+
- Use `posts_per_page => -1` on user-facing queries
|
|
1097
|
+
- Echo unsanitized user input
|
|
1098
|
+
- Concatenate user input into SQL strings
|
|
1099
|
+
- Use `extract()` -- it creates variables from arrays and obscures data flow
|
|
1100
|
+
- Store sensitive data in post meta without encryption
|
|
1101
|
+
- Modify core WordPress files (use hooks and filters instead)
|
|
1102
|
+
- Skip `wp_die()` after `wp_redirect()`
|
|
1103
|
+
- Trust `$_GET`, `$_POST`, or `$_REQUEST` values without sanitization
|
|
1104
|
+
- Use `query_posts()` -- use `WP_Query` or `pre_get_posts` filter instead
|