From 70b60392a7c2fd698385f078f4909e03ad5fb1e9 Mon Sep 17 00:00:00 2001 From: Jasper Smet Date: Sat, 3 Oct 2026 10:32:25 +0200 Subject: [PATCH 1/2] Improve documentation navigation and homepage --- .vitepress/theme/components/HomeCard.vue | 17 + .vitepress/theme/components/HomeWelcome.vue | 22 + .vitepress/theme/homepage.css | 286 ++++++++ .vitepress/theme/index.js | 7 +- .vitepress/toc_en.json | 686 +++++++++++++------- .vitepress/toc_ja.json | 596 +++++++++++------ docs/en/index.md | 669 +++---------------- docs/en/quickstart.md | 4 +- 8 files changed, 1258 insertions(+), 1029 deletions(-) create mode 100644 .vitepress/theme/components/HomeCard.vue create mode 100644 .vitepress/theme/components/HomeWelcome.vue create mode 100644 .vitepress/theme/homepage.css diff --git a/.vitepress/theme/components/HomeCard.vue b/.vitepress/theme/components/HomeCard.vue new file mode 100644 index 0000000000..002706db95 --- /dev/null +++ b/.vitepress/theme/components/HomeCard.vue @@ -0,0 +1,17 @@ + + + diff --git a/.vitepress/theme/components/HomeWelcome.vue b/.vitepress/theme/components/HomeWelcome.vue new file mode 100644 index 0000000000..9f4a9c4669 --- /dev/null +++ b/.vitepress/theme/components/HomeWelcome.vue @@ -0,0 +1,22 @@ + + + diff --git a/.vitepress/theme/homepage.css b/.vitepress/theme/homepage.css new file mode 100644 index 0000000000..65030951a4 --- /dev/null +++ b/.vitepress/theme/homepage.css @@ -0,0 +1,286 @@ +.docs-home { + --home-surface: #f6f3ef; + --home-border: #cfc3b8; + --home-accent-surface: #f9eae3; +} + +.dark .docs-home { + --home-surface: #242120; + --home-border: #3d3532; + --home-accent-surface: #382623; +} + +.docs-home .VPDoc { + padding-top: 24px; +} + +.docs-home .VPDoc .content-container { + width: 100%; + max-width: none; +} + +.docs-home .VPDoc .content { + min-width: 0; +} + +.docs-home .vp-doc h1 { + max-width: 560px; + margin: 12px 0 18px; + font-size: clamp(30px, 3vw, 44px); + line-height: 1.15; + letter-spacing: -0.035em; + text-wrap: balance; +} + +.docs-home .home-welcome h1 .header-anchor { + display: none; +} + +.docs-home .vp-doc h2 { + margin: 40px 0 8px; + padding: 0; + border: 0; + font-size: 23px; + letter-spacing: -0.025em; +} + +.docs-home .vp-doc h2 .header-anchor { + top: 0; +} + +.docs-home .vp-doc p { + color: var(--vp-c-text-2); +} + +.docs-home .home-welcome { + display: flex; + align-items: center; + gap: 24px; + padding: 36px; + border: 1px solid var(--home-border); + border-radius: 16px; + background: var(--home-surface); +} + +.docs-home .home-welcome-copy { + flex: 1; + min-width: 0; +} + +.docs-home .home-welcome-copy > p { + max-width: 480px; + margin: 0; + font-size: 16px; + line-height: 1.7; +} + +.docs-home .home-welcome-copy .home-version { + display: inline-block; + color: var(--vp-c-brand-1); + font-size: 13px; + font-weight: 600; +} + +.docs-home .home-welcome-art { + display: grid; + flex: 0 0 160px; + place-items: center; + height: 160px; + border-radius: 50%; + background: var(--home-accent-surface); +} + +.docs-home .home-actions { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: 24px; +} + +.docs-home .vp-doc .home-button { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 12px; + min-height: 44px; + padding: 10px 20px; + border: 1px solid transparent; + border-radius: 8px; + font-size: 14px; + font-weight: 600; + line-height: 1.5; + text-decoration: none; +} + +.docs-home .vp-doc .home-button-primary { + color: #fff; + background: var(--vp-c-brand-3); +} + +.docs-home .vp-doc .home-button-primary:hover { + background: var(--vp-c-brand-2); +} + +.docs-home .vp-doc .home-button-secondary { + color: var(--vp-c-text-1); + border-color: var(--home-border); + background: var(--vp-c-bg); +} + +.docs-home .home-grid { + display: grid; + gap: 12px; + margin-top: 20px; +} + +.docs-home .home-paths { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.docs-home .home-guides { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.docs-home .vp-doc .home-card { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 12px; + padding: 22px; + border: 1px solid var(--home-border); + border-radius: 12px; + color: var(--vp-c-text-1); + text-decoration: none; + background: var(--vp-c-bg); +} + +.docs-home .vp-doc .home-paths .home-card { + background: var(--home-surface); +} + +.docs-home .vp-doc .home-card:hover, +.docs-home .vp-doc .home-button-secondary:hover { + border-color: var(--vp-c-brand-1); + background: var(--home-accent-surface); +} + +.docs-home .vp-doc .home-card h3 { + margin: 0 0 8px; + font-size: 16px; + line-height: 1.45; + letter-spacing: -0.015em; +} + +.docs-home .home-card p { + margin: 0; + font-size: 14px; + line-height: 1.65; +} + +.docs-home .home-card-arrow { + flex-shrink: 0; + color: var(--vp-c-brand-1); + line-height: 24px; +} + +.docs-home .home-more { + display: flex; + flex-wrap: wrap; + gap: 8px 24px; + margin: 18px 0 0; + font-size: 14px; +} + +.docs-home .home-quickstart { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr); + gap: 24px; + margin-top: 40px; + padding: 24px; + border: 1px solid var(--home-border); + border-radius: 12px; + background: var(--home-surface); +} + +.docs-home .home-quickstart h2 { + margin: 0 0 12px; +} + +.docs-home .home-quickstart p { + margin: 12px 0 0; + font-size: 14px; +} + +.docs-home .home-quickstart [class*='language-'] { + margin: 0; +} + +.docs-home .home-help { + margin-top: 40px; + padding: 24px; + border: 1px solid var(--home-border); + border-radius: 12px; + background: var(--home-surface); +} + +.docs-home .home-help h2 { + margin: 0 0 8px; + font-size: 20px; +} + +.docs-home .home-help p { + margin: 0; + font-size: 14px; +} + +.docs-home .home-help .home-more { + margin-top: 12px; +} + +.docs-home .vp-doc a:focus-visible { + outline: 3px solid var(--vp-c-brand-1); + outline-offset: 4px; +} + +@media (min-width: 960px) { + .docs-home .VPDoc .content { + padding-right: 0; + padding-left: 0; + } +} + +@media (max-width: 1100px) { + .docs-home .home-quickstart { + grid-template-columns: 1fr; + gap: 16px; + } + + .docs-home .home-welcome-art { + flex-basis: 112px; + height: 112px; + } + + .docs-home .home-welcome-art img { + width: 80px; + height: auto; + } +} + +@media (max-width: 639px) { + .docs-home .home-welcome { + padding: 24px; + } + + .docs-home .home-welcome-art { + display: none; + } + + .docs-home .home-paths, + .docs-home .home-guides { + grid-template-columns: 1fr; + } + + .docs-home .vp-doc h2 { + font-size: 21px; + } +} diff --git a/.vitepress/theme/index.js b/.vitepress/theme/index.js index e33e19ec96..b7942b5e3b 100644 --- a/.vitepress/theme/index.js +++ b/.vitepress/theme/index.js @@ -1 +1,6 @@ -export { default } from '@cakephp/docs-skeleton' +import CakeTheme from '@cakephp/docs-skeleton' +import './homepage.css' + +export default { + extends: CakeTheme, +} diff --git a/.vitepress/toc_en.json b/.vitepress/toc_en.json index 1a7097457b..40fe02196a 100644 --- a/.vitepress/toc_en.json +++ b/.vitepress/toc_en.json @@ -1,106 +1,145 @@ { "/": [ { - "text": "Getting Started", + "text": "Start Here", "collapsed": false, "items": [ - { "text": "Quickstart", "link": "/quickstart" }, - { "text": "Installation", "link": "/installation" }, - { "text": "Introduction", "link": "/intro" }, - { "text": "Structure & Conventions", "link": "/intro/conventions" }, { - "text": "Supported Versions", - "link": "/intro/supported-versions" + "text": "Introduction", + "link": "/intro" }, { - "text": "Where to Get Help", - "link": "/intro/where-to-get-help" + "text": "Quickstart", + "link": "/quickstart" + }, + { + "text": "Installation", + "link": "/installation" + }, + { + "text": "Structure & Conventions", + "link": "/intro/conventions" + }, + { + "text": "Configuration", + "link": "/development/configuration" + }, + { + "text": "Guide Overview", + "link": "/topics" }, { "text": "Tutorials & Examples", - "collapsed": true, - "items": [ - { "text": "Overview", "link": "/tutorials-and-examples" }, - { - "text": "CMS Tutorial", - "collapsed": true, - "items": [ - { - "text": "Installation", - "link": "/tutorials-and-examples/cms/installation" - }, - { - "text": "Database", - "link": "/tutorials-and-examples/cms/database" - }, - { - "text": "Articles Model", - "link": "/tutorials-and-examples/cms/articles-model" - }, - { - "text": "Articles Controller", - "link": "/tutorials-and-examples/cms/articles-controller" - }, - { - "text": "Tags and Users", - "link": "/tutorials-and-examples/cms/tags-and-users" - }, - { - "text": "Authentication", - "link": "/tutorials-and-examples/cms/authentication" - }, - { - "text": "Authorization", - "link": "/tutorials-and-examples/cms/authorization" - } - ] - } - ] + "link": "/tutorials-and-examples" }, { - "text": "Migration Guides", + "text": "CMS Tutorial", "collapsed": true, "items": [ { - "text": "Upgrading CakePHP", - "link": "/appendices/migration-guides" + "text": "Installation", + "link": "/tutorials-and-examples/cms/installation" + }, + { + "text": "Database", + "link": "/tutorials-and-examples/cms/database" + }, + { + "text": "Articles Model", + "link": "/tutorials-and-examples/cms/articles-model" }, { - "text": "6.0 Upgrade Guide", - "link": "/appendices/6-0-upgrade-guide" + "text": "Articles Controller", + "link": "/tutorials-and-examples/cms/articles-controller" }, { - "text": "6.0 Migration Guide", - "link": "/appendices/6-0-migration-guide" + "text": "Tags and Users", + "link": "/tutorials-and-examples/cms/tags-and-users" + }, + { + "text": "Authentication", + "link": "/tutorials-and-examples/cms/authentication" + }, + { + "text": "Authorization", + "link": "/tutorials-and-examples/cms/authorization" } ] } ] }, { - "text": "Controllers", + "text": "Application", + "collapsed": true, + "items": [ + { + "text": "Application Lifecycle", + "link": "/development/application" + }, + { + "text": "Dependency Injection", + "link": "/development/dependency-injection" + }, + { + "text": "Events", + "link": "/core-libraries/events" + }, + { + "text": "Loading Plugins", + "link": "/core-libraries/plugin" + }, + { + "text": "Creating Plugins", + "link": "/plugins" + } + ] + }, + { + "text": "HTTP", "collapsed": true, "items": [ - { "text": "Controllers", "link": "/controllers" }, + { + "text": "Routing", + "link": "/development/routing" + }, + { + "text": "Attribute Routing", + "link": "/development/attribute-routing" + }, { "text": "Request & Response", "link": "/controllers/request-response" }, - { "text": "Routing", "link": "/development/routing" }, - { "text": "Attribute Routing", "link": "/development/attribute-routing" }, - { "text": "Sessions", "link": "/development/sessions" }, - { "text": "Middleware", "link": "/controllers/middleware" }, + { + "text": "Middleware", + "link": "/controllers/middleware" + }, + { + "text": "Controllers", + "link": "/controllers" + }, + { + "text": "Sessions", + "link": "/development/sessions" + }, + { + "text": "Pagination", + "link": "/controllers/pagination" + }, + { + "text": "REST APIs", + "link": "/development/rest" + }, { "text": "Pages Controller", "link": "/controllers/pages-controller" }, - { "text": "Pagination", "link": "/controllers/pagination" }, { "text": "Components", "collapsed": true, "items": [ { - "text": "Components", + "text": "Overview", "link": "/controllers/components" }, { @@ -110,79 +149,63 @@ { "text": "Flash", "link": "/controllers/components/flash" - }, - { - "text": "Form Protection", - "link": "/controllers/components/form-protection" } ] } ] }, { - "text": "Views", + "text": "Database", "collapsed": true, "items": [ - { "text": "Views", "link": "/views" }, - { "text": "Cells", "link": "/views/cells" }, { - "text": "JSON and XML Views", - "link": "/views/json-and-xml-views" + "text": "Overview", + "link": "/orm" }, - { "text": "Themes", "link": "/views/themes" }, - { - "text": "Helpers", - "collapsed": true, - "items": [ - { "text": "Helpers", "link": "/views/helpers" }, - { - "text": "Breadcrumbs", - "link": "/views/helpers/breadcrumbs" - }, - { "text": "Flash", "link": "/views/helpers/flash" }, - { "text": "Form", "link": "/views/helpers/form" }, - { "text": "HTML", "link": "/views/helpers/html" }, - { - "text": "Number", - "link": "/views/helpers/number" - }, - { - "text": "Paginator", - "link": "/views/helpers/paginator" - }, - { "text": "Text", "link": "/views/helpers/text" }, - { "text": "Time", "link": "/views/helpers/time" }, - { "text": "URL", "link": "/views/helpers/url" } - ] - } - ] - }, - { - "text": "ORM", - "collapsed": true, - "items": [ - { "text": "ORM", "link": "/orm" }, { "text": "Database Basics", "link": "/orm/database-basics" }, - { "text": "Query Builder", "link": "/orm/query-builder" }, - { "text": "Table Objects", "link": "/orm/table-objects" }, - { "text": "Entities", "link": "/orm/entities" }, - { "text": "Associations", "link": "/orm/associations" }, + { + "text": "Table Objects", + "link": "/orm/table-objects" + }, + { + "text": "Entities", + "link": "/orm/entities" + }, + { + "text": "Associations", + "link": "/orm/associations" + }, + { + "text": "Query Builder", + "link": "/orm/query-builder" + }, { "text": "Retrieving Data and Resultsets", "link": "/orm/retrieving-data-and-resultsets" }, - { "text": "Saving Data", "link": "/orm/saving-data" }, - { "text": "Deleting Data", "link": "/orm/deleting-data" }, - { "text": "Validation", "link": "/orm/validation" }, - { "text": "Schema System", "link": "/orm/schema-system" }, + { + "text": "Saving Data", + "link": "/orm/saving-data" + }, + { + "text": "Deleting Data", + "link": "/orm/deleting-data" + }, + { + "text": "Validation & Application Rules", + "link": "/orm/validation" + }, { "text": "Behaviors", "collapsed": true, "items": [ - { "text": "Behaviors", "link": "/orm/behaviors" }, + { + "text": "Overview", + "link": "/orm/behaviors" + }, { "text": "Counter Cache", "link": "/orm/behaviors/counter-cache" @@ -195,204 +218,392 @@ "text": "Translate", "link": "/orm/behaviors/translate" }, - { "text": "Tree", "link": "/orm/behaviors/tree" } + { + "text": "Tree", + "link": "/orm/behaviors/tree" + } ] + }, + { + "text": "Schema System", + "link": "/orm/schema-system" + }, + { + "text": "Migrations ↗", + "link": "https://book.cakephp.org/migrations/" } ] }, { - "text": "Core Libraries", + "text": "Views", "collapsed": true, "items": [ - { "text": "Events", "link": "/core-libraries/events" }, - { "text": "Caching", "link": "/core-libraries/caching" }, - { "text": "Email", "link": "/core-libraries/email" }, - { "text": "Logging", "link": "/core-libraries/logging" }, - { "text": "Security", "link": "/core-libraries/security" }, { - "text": "Application Core", + "text": "Templates & Layouts", + "link": "/views" + }, + { + "text": "Form Helper", + "link": "/views/helpers/form" + }, + { + "text": "Modelless Forms", + "link": "/core-libraries/form" + }, + { + "text": "Helpers", + "collapsed": true, "items": [ - { "text": "App", "link": "/core-libraries/app" }, - { "text": "Plugin", "link": "/core-libraries/plugin" }, { - "text": "Attribute Resolver", - "link": "/core-libraries/attribute-resolver" + "text": "Overview", + "link": "/views/helpers" }, { - "text": "Registry Objects", - "link": "/core-libraries/registry-objects" + "text": "Breadcrumbs", + "link": "/views/helpers/breadcrumbs" }, { - "text": "Global Constants and Functions", - "link": "/core-libraries/global-constants-and-functions" + "text": "Flash", + "link": "/views/helpers/flash" }, { - "text": "HTTP Client", - "link": "/core-libraries/httpclient" - } - ] - }, - { - "text": "Data Handling", - "items": [ + "text": "HTML", + "link": "/views/helpers/html" + }, { - "text": "Collections", - "link": "/core-libraries/collections" + "text": "Number", + "link": "/views/helpers/number" }, { - "text": "Filesystem", - "link": "/core-libraries/filesystem" + "text": "Paginator", + "link": "/views/helpers/paginator" }, - { "text": "Hash", "link": "/core-libraries/hash" }, - { "text": "XML", "link": "/core-libraries/xml" } - ] - }, - { - "text": "Text & Formatting", - "items": [ { - "text": "Inflector", - "link": "/core-libraries/inflector" + "text": "Text", + "link": "/views/helpers/text" }, - { "text": "Number", "link": "/core-libraries/number" }, - { "text": "Text", "link": "/core-libraries/text" }, - { "text": "Time", "link": "/core-libraries/time" }, { - "text": "Internationalization and Localization", - "link": "/core-libraries/internationalization-and-localization" + "text": "Time", + "link": "/views/helpers/time" + }, + { + "text": "URL", + "link": "/views/helpers/url" } ] }, { - "text": "Forms & Validation", - "items": [ - { "text": "Form", "link": "/core-libraries/form" }, - { - "text": "Validation", - "link": "/core-libraries/validation" - } - ] + "text": "View Cells", + "link": "/views/cells" + }, + { + "text": "JSON and XML Views", + "link": "/views/json-and-xml-views" + }, + { + "text": "Themes", + "link": "/views/themes" } ] }, { - "text": "Console Commands", + "text": "Security", "collapsed": true, "items": [ - { "text": "Console Commands", "link": "/console-commands" }, { - "text": "Commands", - "link": "/console-commands/commands" + "text": "Security Overview", + "link": "/security" }, { - "text": "Input Output", - "link": "/console-commands/input-output" + "text": "Authentication ↗", + "link": "https://book.cakephp.org/authentication/" }, { - "text": "Option Parsers", - "link": "/console-commands/option-parsers" + "text": "Authorization ↗", + "link": "https://book.cakephp.org/authorization/" }, - { "text": "Cache", "link": "/console-commands/cache" }, { - "text": "Completion", - "link": "/console-commands/completion" + "text": "CSRF Protection", + "link": "/security/csrf" }, { - "text": "Counter Cache", - "link": "/console-commands/counter-cache" + "text": "Form Protection", + "link": "/controllers/components/form-protection" }, { - "text": "Cron Jobs", - "link": "/console-commands/cron-jobs" + "text": "Content Security Policy", + "link": "/security/content-security-policy" }, - { "text": "I18n", "link": "/console-commands/i18n" }, - { "text": "Plugin", "link": "/console-commands/plugin" }, - { "text": "REPL", "link": "/console-commands/repl" }, - { "text": "Routes", "link": "/console-commands/routes" }, { - "text": "Schema Cache", - "link": "/console-commands/schema-cache" + "text": "HTTPS Enforcer", + "link": "/security/https-enforcer" + }, + { + "text": "Security Headers", + "link": "/security/security-headers" }, - { "text": "Server", "link": "/console-commands/server" } + { + "text": "Encryption & Hashing", + "link": "/core-libraries/security" + } ] }, { - "text": "Development", + "text": "Testing & Deploy", "collapsed": true, "items": [ { - "text": "Application", - "link": "/development/application" + "text": "Testing", + "link": "/development/testing" }, { - "text": "Configuration", - "link": "/development/configuration" + "text": "Debugging", + "link": "/development/debugging" }, - { "text": "Debugging", "link": "/development/debugging" }, { - "text": "Dependency Injection", - "link": "/development/dependency-injection" + "text": "Error & Exception Handling", + "link": "/development/errors" + }, + { + "text": "Logging", + "link": "/core-libraries/logging" }, - { "text": "Errors", "link": "/development/errors" }, - { "text": "REST", "link": "/development/rest" }, - { "text": "Testing", "link": "/development/testing" } + { + "text": "Caching", + "link": "/core-libraries/caching" + }, + { + "text": "Locking", + "link": "/core-libraries/locking" + }, + { + "text": "Deployment", + "link": "/deployment" + }, + { + "text": "Cron Jobs", + "link": "/console-commands/cron-jobs" + }, + { + "text": "Debug Kit ↗", + "link": "https://book.cakephp.org/debugkit/" + } ] }, { - "text": "Plugins", + "text": "Console", "collapsed": true, "items": [ - { "text": "Creating Plugins", "link": "/plugins" }, { - "text": "Core Plugins", + "text": "Console Overview", + "link": "/console-commands" + }, + { + "text": "Writing Commands", + "link": "/console-commands/commands" + }, + { + "text": "Console Input & Output", + "link": "/console-commands/input-output" + }, + { + "text": "Option Parsers", + "link": "/console-commands/option-parsers" + }, + { + "text": "Built-in Commands", + "collapsed": true, "items": [ - { "text": "Authentication", "link": "https://book.cakephp.org/authentication/" }, - { "text": "Authorization", "link": "https://book.cakephp.org/authorization/" }, - { "text": "Bake", "link": "https://book.cakephp.org/bake/" }, - { "text": "Chronos", "link": "https://book.cakephp.org/chronos/" }, - { "text": "Debug Kit", "link": "https://book.cakephp.org/debugkit/" }, - { "text": "Elasticsearch", "link": "https://book.cakephp.org/elasticsearch/" }, - { "text": "Migrations", "link": "https://book.cakephp.org/migrations/" }, - { "text": "Phinx", "link": "https://book.cakephp.org/phinx/" } + { + "text": "Cache", + "link": "/console-commands/cache" + }, + { + "text": "Completion", + "link": "/console-commands/completion" + }, + { + "text": "Counter Cache", + "link": "/console-commands/counter-cache" + }, + { + "text": "I18n", + "link": "/console-commands/i18n" + }, + { + "text": "Plugin", + "link": "/console-commands/plugin" + }, + { + "text": "Routes", + "link": "/console-commands/routes" + }, + { + "text": "Schema Cache", + "link": "/console-commands/schema-cache" + }, + { + "text": "Server", + "link": "/console-commands/server" + } ] + }, + { + "text": "Bake ↗", + "link": "https://book.cakephp.org/bake/" + }, + { + "text": "REPL", + "link": "/console-commands/repl" } ] }, { - "text": "Security", + "text": "Utilities", "collapsed": true, "items": [ - { "text": "Security", "link": "/security" }, { - "text": "Content Security Policy", - "link": "/security/content-security-policy" + "text": "Email", + "link": "/core-libraries/email" }, - { "text": "CSRF", "link": "/security/csrf" }, { - "text": "HTTPS Enforcer", - "link": "/security/https-enforcer" + "text": "HTTP Client", + "link": "/core-libraries/httpclient" }, { - "text": "Security Headers", - "link": "/security/security-headers" + "text": "Data Utilities", + "collapsed": true, + "items": [ + { + "text": "Collections", + "link": "/core-libraries/collections" + }, + { + "text": "Filesystem", + "link": "/core-libraries/filesystem" + }, + { + "text": "Hash", + "link": "/core-libraries/hash" + }, + { + "text": "XML", + "link": "/core-libraries/xml" + } + ] + }, + { + "text": "Text & Formatting", + "collapsed": true, + "items": [ + { + "text": "Text", + "link": "/core-libraries/text" + }, + { + "text": "Inflector", + "link": "/core-libraries/inflector" + }, + { + "text": "Number", + "link": "/core-libraries/number" + }, + { + "text": "Time", + "link": "/core-libraries/time" + }, + { + "text": "Internationalization and Localization", + "link": "/core-libraries/internationalization-and-localization" + } + ] + }, + { + "text": "Validation Library", + "link": "/core-libraries/validation" + }, + { + "text": "Framework Utilities", + "collapsed": true, + "items": [ + { + "text": "App", + "link": "/core-libraries/app" + }, + { + "text": "Attribute Resolver", + "link": "/core-libraries/attribute-resolver" + }, + { + "text": "Registry Objects", + "link": "/core-libraries/registry-objects" + }, + { + "text": "Global Constants and Functions", + "link": "/core-libraries/global-constants-and-functions" + } + ] + }, + { + "text": "Related Plugins", + "collapsed": true, + "items": [ + { + "text": "Chronos ↗", + "link": "https://book.cakephp.org/chronos/" + }, + { + "text": "Elasticsearch ↗", + "link": "https://book.cakephp.org/elasticsearch/" + }, + { + "text": "Phinx ↗", + "link": "https://book.cakephp.org/phinx/" + } + ] + }, + { + "text": "Standalone Packages", + "link": "/standalone-packages" } ] }, { - "text": "Additional Topics", + "text": "Upgrades & Help", "collapsed": true, "items": [ - { "text": "Deployment", "link": "/deployment" }, - { "text": "Release Policy", "link": "/release-policy" }, { - "text": "Standalone Packages", - "link": "/standalone-packages" + "text": "Upgrade Overview", + "link": "/appendices/migration-guides" + }, + { + "text": "6.0 Upgrade Guide", + "link": "/appendices/6-0-upgrade-guide" + }, + { + "text": "6.0 Migration Guide", + "link": "/appendices/6-0-migration-guide" + }, + { + "text": "Supported Versions", + "link": "/intro/supported-versions" + }, + { + "text": "Release Policy", + "link": "/release-policy" + }, + { + "text": "Where to Get Help", + "link": "/intro/where-to-get-help" }, - { "text": "Topics", "link": "/topics" }, { "text": "Contributing", + "collapsed": true, "items": [ - { "text": "Contributing", "link": "/contributing" }, + { + "text": "Overview", + "link": "/contributing" + }, { "text": "Backwards Compatibility", "link": "/contributing/backwards-compatibility" @@ -401,24 +612,31 @@ "text": "CakePHP Coding Conventions", "link": "/contributing/cakephp-coding-conventions" }, - { "text": "Code", "link": "/contributing/code" }, + { + "text": "Code", + "link": "/contributing/code" + }, { "text": "Documentation", "link": "/contributing/documentation" }, - { "text": "Tickets", "link": "/contributing/tickets" } + { + "text": "Tickets", + "link": "/contributing/tickets" + } ] }, { - "text": "Appendices", - "items": [ - { "text": "Appendices", "link": "/appendices" }, - { - "text": "CakePHP Development Process", - "link": "/appendices/cakephp-development-process" - }, - { "text": "Glossary", "link": "/appendices/glossary" } - ] + "text": "Glossary", + "link": "/appendices/glossary" + }, + { + "text": "CakePHP Development Process", + "link": "/appendices/cakephp-development-process" + }, + { + "text": "Appendices Overview", + "link": "/appendices" } ] } diff --git a/.vitepress/toc_ja.json b/.vitepress/toc_ja.json index ad614b8e84..e306f2002e 100644 --- a/.vitepress/toc_ja.json +++ b/.vitepress/toc_ja.json @@ -4,23 +4,38 @@ "text": "はじめに", "collapsed": false, "items": [ - { "text": "インストール", "link": "/ja/installation" }, - { "text": "クイックスタート", "link": "/ja/quickstart" }, - { "text": "イントロダクション", "link": "/ja/intro" }, - { "text": "規約", "link": "/ja/intro/conventions" }, + { + "text": "イントロダクション", + "link": "/ja/intro" + }, + { + "text": "クイックスタート", + "link": "/ja/quickstart" + }, + { + "text": "インストール", + "link": "/ja/installation" + }, + { + "text": "規約", + "link": "/ja/intro/conventions" + }, { "text": "CakePHP フォルダ構造", "link": "/ja/intro/cakephp-folder-structure" }, { - "text": "ヘルプの取得", - "link": "/ja/intro/where-to-get-help" + "text": "設定", + "link": "/ja/development/configuration" + }, + { + "text": "ガイドの概要", + "link": "/ja/topics" }, { "text": "チュートリアル & 例", - "collapsed": true, - "items": [ - { "text": "概要", "link": "/ja/tutorials-and-examples" }, + "link": "/ja/tutorials-and-examples" + }, { "text": "ブログチュートリアル", "collapsed": true, @@ -94,14 +109,41 @@ ] } ] + }, + { + "text": "アプリケーション", + "collapsed": true, + "items": [ + { + "text": "アプリケーションのライフサイクル", + "link": "/ja/development/application" + }, + { + "text": "依存性注入", + "link": "/ja/development/dependency-injection" + }, + { + "text": "イベント", + "link": "/ja/core-libraries/events" + }, + { + "text": "プラグインの読み込み", + "link": "/ja/core-libraries/plugin" + }, + { + "text": "プラグインの作成", + "link": "/ja/plugins" } ] }, { - "text": "コントローラー", + "text": "HTTP", "collapsed": true, "items": [ - { "text": "コントローラー", "link": "/ja/controllers" }, + { + "text": "ルーティング", + "link": "/ja/development/routing" + }, { "text": "リクエスト & レスポンス", "link": "/ja/controllers/request-response" @@ -111,19 +153,31 @@ "link": "/ja/controllers/middleware" }, { - "text": "ページコントローラー", - "link": "/ja/controllers/pages-controller" + "text": "コントローラー", + "link": "/ja/controllers" + }, + { + "text": "セッション", + "link": "/ja/development/sessions" }, { "text": "ページネーション", "link": "/ja/controllers/pagination" }, + { + "text": "REST API", + "link": "/ja/development/rest" + }, + { + "text": "ページコントローラー", + "link": "/ja/controllers/pages-controller" + }, { "text": "コンポーネント", "collapsed": true, "items": [ { - "text": "コンポーネント", + "text": "概要", "link": "/ja/controllers/components" }, { @@ -133,12 +187,88 @@ { "text": "フラッシュ", "link": "/ja/controllers/components/flash" + } + ] + } + ] + }, + { + "text": "データベース", + "collapsed": true, + "items": [ + { + "text": "概要", + "link": "/ja/orm" + }, + { + "text": "データベース基礎", + "link": "/ja/orm/database-basics" + }, + { + "text": "テーブルオブジェクト", + "link": "/ja/orm/table-objects" + }, + { + "text": "エンティティ", + "link": "/ja/orm/entities" + }, + { + "text": "アソシエーション", + "link": "/ja/orm/associations" + }, + { + "text": "クエリビルダー", + "link": "/ja/orm/query-builder" + }, + { + "text": "データの取得と結果セット", + "link": "/ja/orm/retrieving-data-and-resultsets" + }, + { + "text": "データの保存", + "link": "/ja/orm/saving-data" + }, + { + "text": "データの削除", + "link": "/ja/orm/deleting-data" + }, + { + "text": "バリデーションとアプリケーションルール", + "link": "/ja/orm/validation" + }, + { + "text": "ビヘイビア", + "collapsed": true, + "items": [ + { + "text": "概要", + "link": "/ja/orm/behaviors" + }, + { + "text": "カウンターキャッシュ", + "link": "/ja/orm/behaviors/counter-cache" + }, + { + "text": "タイムスタンプ", + "link": "/ja/orm/behaviors/timestamp" }, { - "text": "フォーム保護", - "link": "/ja/controllers/components/form-protection" + "text": "翻訳", + "link": "/ja/orm/behaviors/translate" + }, + { + "text": "ツリー", + "link": "/ja/orm/behaviors/tree" } ] + }, + { + "text": "スキーマシステム", + "link": "/ja/orm/schema-system" + }, + { + "text": "Migrations ↗", + "link": "https://book.cakephp.org/migrations/" } ] }, @@ -146,18 +276,26 @@ "text": "ビュー", "collapsed": true, "items": [ - { "text": "ビュー", "link": "/ja/views" }, - { "text": "セル", "link": "/ja/views/cells" }, { - "text": "JSON と XML ビュー", - "link": "/ja/views/json-and-xml-views" + "text": "テンプレートとレイアウト", + "link": "/ja/views" + }, + { + "text": "フォームヘルパー", + "link": "/ja/views/helpers/form" + }, + { + "text": "モデルなしのフォーム", + "link": "/ja/core-libraries/form" }, - { "text": "テーマ", "link": "/ja/views/themes" }, { "text": "ヘルパー", "collapsed": true, "items": [ - { "text": "ヘルパー", "link": "/ja/views/helpers" }, + { + "text": "概要", + "link": "/ja/views/helpers" + }, { "text": "パンくずリスト", "link": "/ja/views/helpers/breadcrumbs" @@ -166,10 +304,6 @@ "text": "フラッシュ", "link": "/ja/views/helpers/flash" }, - { - "text": "フォーム", - "link": "/ja/views/helpers/form" - }, { "text": "HTML", "link": "/ja/views/helpers/html" @@ -190,121 +324,220 @@ "text": "時間", "link": "/ja/views/helpers/time" }, - { "text": "URL", "link": "/ja/views/helpers/url" } + { + "text": "URL", + "link": "/ja/views/helpers/url" + } ] + }, + { + "text": "ビューセル", + "link": "/ja/views/cells" + }, + { + "text": "JSON と XML ビュー", + "link": "/ja/views/json-and-xml-views" + }, + { + "text": "テーマ", + "link": "/ja/views/themes" } ] }, { - "text": "ORM", + "text": "セキュリティ", "collapsed": true, "items": [ - { "text": "ORM", "link": "/ja/orm" }, { - "text": "データベース基礎", - "link": "/ja/orm/database-basics" + "text": "セキュリティの概要", + "link": "/ja/security" }, { - "text": "クエリビルダー", - "link": "/ja/orm/query-builder" + "text": "Authentication ↗", + "link": "https://book.cakephp.org/authentication/" }, { - "text": "テーブルオブジェクト", - "link": "/ja/orm/table-objects" + "text": "Authorization ↗", + "link": "https://book.cakephp.org/authorization/" }, - { "text": "エンティティ", "link": "/ja/orm/entities" }, { - "text": "アソシエーション", - "link": "/ja/orm/associations" + "text": "CSRF 保護", + "link": "/ja/security/csrf" }, { - "text": "データの取得と結果セット", - "link": "/ja/orm/retrieving-data-and-resultsets" + "text": "フォーム保護", + "link": "/ja/controllers/components/form-protection" }, - { "text": "データの保存", "link": "/ja/orm/saving-data" }, - { "text": "データの削除", "link": "/ja/orm/deleting-data" }, - { "text": "バリデーション", "link": "/ja/orm/validation" }, { - "text": "スキーマシステム", - "link": "/ja/orm/schema-system" + "text": "コンテンツセキュリティポリシー", + "link": "/ja/security/content-security-policy" }, { - "text": "ビヘイビア", + "text": "HTTPS エンフォーサー", + "link": "/ja/security/https-enforcer" + }, + { + "text": "セキュリティヘッダー", + "link": "/ja/security/security-headers" + }, + { + "text": "暗号化とハッシュ", + "link": "/ja/core-libraries/security" + } + ] + }, + { + "text": "テストとデプロイ", + "collapsed": true, + "items": [ + { + "text": "テスト", + "link": "/ja/development/testing" + }, + { + "text": "デバッグ", + "link": "/ja/development/debugging" + }, + { + "text": "エラーと例外処理", + "link": "/ja/development/errors" + }, + { + "text": "ログ", + "link": "/ja/core-libraries/logging" + }, + { + "text": "キャッシュ", + "link": "/ja/core-libraries/caching" + }, + { + "text": "デプロイメント", + "link": "/ja/deployment" + }, + { + "text": "クロンジョブ", + "link": "/ja/console-commands/cron-jobs" + }, + { + "text": "Debug Kit ↗", + "link": "https://book.cakephp.org/debugkit/" + } + ] + }, + { + "text": "コンソール", + "collapsed": true, + "items": [ + { + "text": "コンソールの概要", + "link": "/ja/console-commands" + }, + { + "text": "コマンドの作成", + "link": "/ja/console-commands/commands" + }, + { + "text": "コンソールの入出力", + "link": "/ja/console-commands/input-output" + }, + { + "text": "オプションパーサー", + "link": "/ja/console-commands/option-parsers" + }, + { + "text": "組み込みコマンド", "collapsed": true, "items": [ { - "text": "ビヘイビア", - "link": "/ja/orm/behaviors" + "text": "キャッシュ", + "link": "/ja/console-commands/cache" }, { - "text": "カウンターキャッシュ", - "link": "/ja/orm/behaviors/counter-cache" + "text": "補完", + "link": "/ja/console-commands/completion" }, { - "text": "タイムスタンプ", - "link": "/ja/orm/behaviors/timestamp" + "text": "i18n", + "link": "/ja/console-commands/i18n" }, { - "text": "翻訳", - "link": "/ja/orm/behaviors/translate" + "text": "プラグイン", + "link": "/ja/console-commands/plugin" }, { - "text": "ツリー", - "link": "/ja/orm/behaviors/tree" + "text": "ルート", + "link": "/ja/console-commands/routes" + }, + { + "text": "スキーマキャッシュ", + "link": "/ja/console-commands/schema-cache" + }, + { + "text": "サーバー", + "link": "/ja/console-commands/server" } ] + }, + { + "text": "Bake ↗", + "link": "https://book.cakephp.org/bake/" + }, + { + "text": "REPL", + "link": "/ja/console-commands/repl" } ] }, { - "text": "コアライブラリ", + "text": "ユーティリティ", "collapsed": true, "items": [ - { "text": "イベント", "link": "/ja/core-libraries/events" }, - { "text": "キャッシュ", "link": "/ja/core-libraries/caching" }, - { "text": "メール", "link": "/ja/core-libraries/email" }, - { "text": "ログ", "link": "/ja/core-libraries/logging" }, - { "text": "セキュリティ", "link": "/ja/core-libraries/security" }, { - "text": "アプリケーションコア", + "text": "メール", + "link": "/ja/core-libraries/email" + }, + { + "text": "HTTP クライアント", + "link": "/ja/core-libraries/httpclient" + }, + { + "text": "データユーティリティ", + "collapsed": true, "items": [ - { "text": "アプリ", "link": "/ja/core-libraries/app" }, - { "text": "プラグイン", "link": "/ja/core-libraries/plugin" }, { - "text": "レジストリオブジェクト", - "link": "/ja/core-libraries/registry-objects" + "text": "コレクション", + "link": "/ja/core-libraries/collections" }, { - "text": "グローバル定数と関数", - "link": "/ja/core-libraries/global-constants-and-functions" + "text": "ハッシュ", + "link": "/ja/core-libraries/hash" }, { - "text": "HTTP クライアント", - "link": "/ja/core-libraries/httpclient" + "text": "XML", + "link": "/ja/core-libraries/xml" } ] }, { - "text": "データ処理", + "text": "テキストと書式設定", + "collapsed": true, "items": [ { - "text": "コレクション", - "link": "/ja/core-libraries/collections" + "text": "テキスト", + "link": "/ja/core-libraries/text" }, - { "text": "ハッシュ", "link": "/ja/core-libraries/hash" }, - { "text": "XML", "link": "/ja/core-libraries/xml" } - ] - }, - { - "text": "テキストと書式設定", - "items": [ { "text": "インフレクター", "link": "/ja/core-libraries/inflector" }, - { "text": "数値", "link": "/ja/core-libraries/number" }, - { "text": "テキスト", "link": "/ja/core-libraries/text" }, - { "text": "時間", "link": "/ja/core-libraries/time" }, + { + "text": "数値", + "link": "/ja/core-libraries/number" + }, + { + "text": "時間", + "link": "/ja/core-libraries/time" + }, { "text": "国際化とローカライゼーション", "link": "/ja/core-libraries/internationalization-and-localization" @@ -312,132 +545,95 @@ ] }, { - "text": "フォームとバリデーション", + "text": "バリデーションライブラリ", + "link": "/ja/core-libraries/validation" + }, + { + "text": "フレームワークユーティリティ", + "collapsed": true, "items": [ - { "text": "フォーム", "link": "/ja/core-libraries/form" }, { - "text": "バリデーション", - "link": "/ja/core-libraries/validation" + "text": "アプリ", + "link": "/ja/core-libraries/app" + }, + { + "text": "レジストリオブジェクト", + "link": "/ja/core-libraries/registry-objects" + }, + { + "text": "グローバル定数と関数", + "link": "/ja/core-libraries/global-constants-and-functions" } ] - } - ] - }, - { - "text": "コンソールコマンド", - "collapsed": true, - "items": [ - { - "text": "コンソールコマンド", - "link": "/ja/console-commands" }, { - "text": "コマンド", - "link": "/ja/console-commands/commands" - }, - { - "text": "入力出力", - "link": "/ja/console-commands/input-output" - }, - { - "text": "オプションパーサー", - "link": "/ja/console-commands/option-parsers" - }, - { - "text": "キャッシュ", - "link": "/ja/console-commands/cache" - }, - { - "text": "補完", - "link": "/ja/console-commands/completion" - }, - { - "text": "クロンジョブ", - "link": "/ja/console-commands/cron-jobs" - }, - { "text": "i18n", "link": "/ja/console-commands/i18n" }, - { - "text": "プラグイン", - "link": "/ja/console-commands/plugin" - }, - { "text": "REPL", "link": "/ja/console-commands/repl" }, - { "text": "ルート", "link": "/ja/console-commands/routes" }, - { - "text": "スキーマキャッシュ", - "link": "/ja/console-commands/schema-cache" + "text": "関連プラグイン", + "collapsed": true, + "items": [ + { + "text": "Chronos ↗", + "link": "https://book.cakephp.org/chronos/" + }, + { + "text": "Elasticsearch ↗", + "link": "https://book.cakephp.org/elasticsearch/" + }, + { + "text": "Phinx ↗", + "link": "https://book.cakephp.org/phinx/" + } + ] }, { - "text": "サーバー", - "link": "/ja/console-commands/server" + "text": "スタンドアロンパッケージ", + "link": "/ja/standalone-packages" } ] }, { - "text": "開発", + "text": "アップグレードとヘルプ", "collapsed": true, "items": [ { - "text": "アプリケーション", - "link": "/ja/development/application" + "text": "アップグレードの概要", + "link": "/ja/appendices/migration-guides" }, - { "text": "設定", "link": "/ja/development/configuration" }, { - "text": "ルーティング", - "link": "/ja/development/routing" + "text": "5.0 アップグレードガイド", + "link": "/ja/appendices/5-0-upgrade-guide" }, { - "text": "セッション", - "link": "/ja/development/sessions" + "text": "5.0 移行ガイド", + "link": "/ja/appendices/5-0-migration-guide" }, - { "text": "デバッグ", "link": "/ja/development/debugging" }, { - "text": "依存性注入", - "link": "/ja/development/dependency-injection" + "text": "5.1 移行ガイド", + "link": "/ja/appendices/5-1-migration-guide" }, - { "text": "プラグイン", "link": "/ja/plugins" }, - { "text": "エラー", "link": "/ja/development/errors" }, - { "text": "REST", "link": "/ja/development/rest" }, - { "text": "テスト", "link": "/ja/development/testing" } - ] - }, - { - "text": "セキュリティ", - "collapsed": true, - "items": [ - { "text": "セキュリティ", "link": "/ja/security" }, { - "text": "コンテンツセキュリティポリシー", - "link": "/ja/security/content-security-policy" + "text": "5.2 移行ガイド", + "link": "/ja/appendices/5-2-migration-guide" }, - { "text": "CSRF", "link": "/ja/security/csrf" }, { - "text": "HTTPS エンフォーサー", - "link": "/ja/security/https-enforcer" + "text": "PHPUnit アップグレード", + "link": "/ja/appendices/phpunit-upgrade" }, - { - "text": "セキュリティヘッダー", - "link": "/ja/security/security-headers" - } - ] - }, - { - "text": "追加トピック", - "collapsed": true, - "items": [ - { "text": "デプロイメント", "link": "/ja/deployment" }, { "text": "リリースポリシー", "link": "/ja/release-policy" }, { - "text": "スタンドアロンパッケージ", - "link": "/ja/standalone-packages" + "text": "ヘルプの取得", + "link": "/ja/intro/where-to-get-help" }, - { "text": "トピック", "link": "/ja/topics" }, { "text": "貢献", + "collapsed": true, "items": [ - { "text": "貢献", "link": "/ja/contributing" }, + { + "text": "概要", + "link": "/ja/contributing" + }, { "text": "後方互換性", "link": "/ja/contributing/backwards-compatibility" @@ -446,45 +642,31 @@ "text": "CakePHP コーディング規約", "link": "/ja/contributing/cakephp-coding-conventions" }, - { "text": "コード", "link": "/ja/contributing/code" }, + { + "text": "コード", + "link": "/ja/contributing/code" + }, { "text": "ドキュメント", "link": "/ja/contributing/documentation" }, - { "text": "チケット", "link": "/ja/contributing/tickets" } + { + "text": "チケット", + "link": "/ja/contributing/tickets" + } ] }, { - "text": "付録", - "items": [ - { "text": "付録", "link": "/ja/appendices" }, - { - "text": "移行ガイド", - "link": "/ja/appendices/migration-guides" - }, - { - "text": "5.0 アップグレードガイド", - "link": "/ja/appendices/5-0-upgrade-guide" - }, - { - "text": "5.0 移行ガイド", - "link": "/ja/appendices/5-0-migration-guide" - }, - { - "text": "5.1 移行ガイド", - "link": "/ja/appendices/5-1-migration-guide" - }, - { - "text": "5.2 移行ガイド", - "link": "/ja/appendices/5-2-migration-guide" - }, - { - "text": "CakePHP 開発プロセス", - "link": "/ja/appendices/cakephp-development-process" - }, - { "text": "用語集", "link": "/ja/appendices/glossary" }, - { "text": "PHPUnit アップグレード", "link": "/ja/appendices/phpunit-upgrade" } - ] + "text": "用語集", + "link": "/ja/appendices/glossary" + }, + { + "text": "CakePHP 開発プロセス", + "link": "/ja/appendices/cakephp-development-process" + }, + { + "text": "付録の概要", + "link": "/ja/appendices" } ] } diff --git a/docs/en/index.md b/docs/en/index.md index 355bce9cd4..b0d6d77498 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -1,664 +1,161 @@ --- -title: "|cakefullversion| Documentation - Build Better Web Applications Faster" -description: Official |cakefullversion| documentation. Learn how to build modern PHP web applications with convention over configuration, powerful ORM, built-in security, and rapid development tools. -outline: 2 +title: "|cakefullversion| Cookbook" +description: "Find your way around the CakePHP Cookbook: learn the fundamentals, build your first application, explore the guides, or upgrade an existing app." +pageClass: docs-home +aside: false +outline: false +prev: false +next: false --- -# Build Better Web Applications, Faster -**|cakefullversion|** (currently |cakeversion|) is a modern PHP framework running on PHP |phpversion| (min. PHP |minphpversion|) that helps you write clean, maintainable code without the complexity. Whether you're building a simple blog or a complex enterprise application, CakePHP gives you the tools to get it done right. + -::: tip Perfect for -✅ Developers who value **convention over configuration**
-✅ Teams building **secure, scalable applications**
-✅ Projects that need to **ship quickly** without sacrificing quality
-✅ Applications requiring **modern PHP standards** (PSR-7, PSR-15, PSR-17) -::: + -## Why CakePHP? +

|cakefullversion| Documentation

-
+# Welcome to the CakePHP 6 Cookbook -🚀 **Rapid Development**
-Scaffold applications in minutes with powerful code generation tools. +Learn the fundamentals, build your first application, or find the guide you need. -🔒 **Security First**
-Built-in protection against SQL injection, XSS, CSRF, and more. + -📦 **Batteries Included**
-ORM, validation, caching, authentication — everything you need out of the box. +## Find your starting point -🎯 **Convention over Configuration**
-Sensible defaults mean less setup, more coding. +A little guidance for wherever you are in your CakePHP journey. -
- -## Quick Start - -Get a CakePHP application running in under 5 minutes: - -::: code-group - -```bash [Composer] -# Create new project -composer create-project --prefer-dist cakephp/app:~|cakeversion| my_app - -# Start development server -cd my_app -bin/cake server - -# Open http://localhost:8765 -``` - -```bash [DDEV] -# Setup with DDEV -mkdir my-cakephp-app && cd my-cakephp-app -ddev config --project-type=cakephp --docroot=webroot -ddev composer create --prefer-dist cakephp/app:~|cakeversion| -ddev launch -``` - -```bash [Docker] -# Using official PHP image -docker run -it --rm -v $(pwd):/app composer create-project \ - --prefer-dist cakephp/app:~|cakeversion| my_app - -cd my_app -docker run -it --rm -p 8765:8765 -v $(pwd):/app \ - -w /app php:8.2-cli php bin/cake server -H 0.0.0.0 -``` - -::: - -> [!TIP] -> You should see a welcome page with green checkmarks at **** - -::: details System Requirements -Make sure your system meets these requirements before getting started: - -| Component | Version | -| ---------- | ------- | -| PHP | 8.2 - 8.5 | -| Database | MySQL 5.7+, PostgreSQL 9.6+, SQLite 3, SQL Server 2012+ | -| Extensions | `mbstring`, `intl`, `pdo`, `simplexml` | -| Composer | Latest | - -::: - -## Your First Application - -Let's build a simple blog in 10 minutes! Follow along with this hands-on tutorial. - -> [!NOTE] -> This tutorial assumes you already have a database created. Use your database management tool to create a database named `blog` before proceeding. - -### Step 1: Configure Database Connection +
-Update your database credentials in **config/app_local.php**: + -```php{7-11} [config/app_local.php] -New to CakePHP? -return [ - 'Datasources' => [ - 'default' => [ - 'host' => 'localhost', - 'username' => 'my_user', - 'password' => 'secret', - 'database' => 'blog', - 'encoding' => 'utf8mb4', - ], - ], -]; -``` - -::: tip Configuration Files - -- **config/app.php** - Default configuration (committed to git) -- **config/app_local.php** - Local overrides (gitignored) -::: - -### Step 2: Create Database Tables - -Choose your preferred approach for creating the database schema: - -> [!NOTE] -> **Migrations** are recommended for team projects and production - they're version-controlled and database-agnostic. -> **Raw SQL** is fine for quick prototyping or if you prefer direct database control. - -#### Option A: Using Migrations - -::: code-group - -```bash [Commands] -# Step 1: Generate a migration file -bin/cake bake migration CreateArticles -# This creates: config/Migrations/YYYYMMDDHHMMSS_CreateArticles.php - -# Step 2: Edit the generated file to define your table structure -# See the "Migration File" tab for the complete example -# Open: config/Migrations/YYYYMMDDHHMMSS_CreateArticles.php - -# Step 3: Run the migration to create the table -bin/cake migrations migrate - -# Step 4: (Optional) Generate and run seed data -bin/cake bake seed Articles -bin/cake seeds run Articles -``` +Get to know the framework, its conventions, and how the pieces fit together. -```php [Migration File] -table('articles'); - $table->addColumn('title', 'string', ['limit' => 255]) - ->addColumn('slug', 'string', ['limit' => 191]) - ->addColumn('body', 'text', ['null' => true]) - ->addColumn('published', 'boolean', ['default' => false]) - ->addColumn('created', 'datetime') - ->addColumn('modified', 'datetime') - ->addIndex(['slug'], ['unique' => true]) - ->create(); - } -} -``` - -```php [Seed File] - 'First Post', - 'slug' => 'first-post', - 'body' => 'This is my first blog post!', - 'published' => true, - 'created' => date('Y-m-d H:i:s'), - 'modified' => date('Y-m-d H:i:s'), - ], - [ - 'title' => 'Second Post', - 'slug' => 'second-post', - 'body' => 'Another great article.', - 'published' => true, - 'created' => date('Y-m-d H:i:s'), - 'modified' => date('Y-m-d H:i:s'), - ], - ]; - - $table = $this->table('articles'); - $table->insert($data)->save(); - } -} -``` + -::: + -#### Option B: Using Raw SQL +

Build an application

-::: code-group +Learn by doing with a step-by-step content management system tutorial. -```sql [MySQL] -USE blog; +
-CREATE TABLE articles ( - id INT AUTO_INCREMENT PRIMARY KEY, - title VARCHAR(255) NOT NULL, - slug VARCHAR(191) UNIQUE, - body TEXT, - published BOOLEAN DEFAULT FALSE, - created DATETIME, - modified DATETIME -) ENGINE=InnoDB; + -INSERT INTO articles (title, slug, body, published, created, modified) -VALUES ('First Post', 'first-post', 'This is my first blog post!', TRUE, NOW(), NOW()); -``` +

Upgrade your application

-```sql [PostgreSQL] -\c blog - -CREATE TABLE articles ( - id SERIAL PRIMARY KEY, - title VARCHAR(255) NOT NULL, - slug VARCHAR(191) UNIQUE, - body TEXT, - published BOOLEAN DEFAULT FALSE, - created TIMESTAMP, - modified TIMESTAMP -); - -INSERT INTO articles (title, slug, body, published, created, modified) -VALUES ('First Post', 'first-post', 'This is my first blog post!', TRUE, NOW(), NOW()); -``` - -```sql [SQLite] -CREATE TABLE articles ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - title VARCHAR(255) NOT NULL, - slug VARCHAR(191) UNIQUE, - body TEXT, - published BOOLEAN DEFAULT 0, - created DATETIME, - modified DATETIME -); - -INSERT INTO articles (title, slug, body, published, created, modified) -VALUES ('First Post', 'first-post', 'This is my first blog post!', 1, datetime('now'), datetime('now')); -``` - -::: - -### Step 3: Generate Your First Model - -Use CakePHP's code generation tool: - -```bash -# Generate model classes -bin/cake bake model Articles - -# Output: -# ✓ Created: src/Model/Table/ArticlesTable.php -# ✓ Created: src/Model/Entity/Article.php -# ✓ Created: tests/TestCase/Model/Table/ArticlesTableTest.php -``` +Prepare your existing application for CakePHP 6. -This creates: +
-::: code-group - -```php [ArticlesTable.php] -setTable('articles'); - $this->setDisplayField('title'); - $this->setPrimaryKey('id'); - - $this->addBehavior('Timestamp'); - } -} -``` - -```php [Article.php] - true, - 'slug' => true, - 'body' => true, - 'published' => true, - 'created' => true, - 'modified' => true, - ]; -} -``` +
-::: +
+
-### Step 4: Create Your Controller +## Quick start -Generate a controller with views: +Have PHP |minphpversion|+ and Composer installed? Create an application and start the development server. -```bash -bin/cake bake controller Articles -``` +[Installation guide →](installation) -```php [src/Controller/ArticlesController.php] -Articles->find('all') - ->where(['published' => true]) - ->orderBy(['created' => 'DESC']); - - $this->set(compact('articles')); - } - - public function view(?string $slug = null): void - { - $article = $this->Articles - ->findBySlug($slug) - ->firstOrFail(); - - $this->set(compact('article')); - } - - public function add(): void - { - $article = $this->Articles->newEmptyEntity(); - - if ($this->request->is('post')) { - $article = $this->Articles->patchEntity( - $article, - $this->request->getData() - ); - - if ($this->Articles->save($article)) { - $this->Flash->success('Article saved!'); - return $this->redirect(['action' => 'index']); - } - - $this->Flash->error('Unable to save article.'); - } - - $this->set(compact('article')); - } -} -``` +
+
-### Step 5: Create Your Views - -Create a simple list view in **templates/Articles/index.php**: - -```php [templates/Articles/index.php] -

Blog Articles

- - -
-

- Html->link( - h($article->title), - ['action' => 'view', $article->slug] - ) ?> -

-

- Published: created->format('F d, Y') ?> -

-

body) ?>

-
- - -Html->link('New Article', ['action' => 'add'], ['class' => 'button']) ?> +```bash:no-line-numbers +composer create-project --prefer-dist cakephp/app:~|cakeversion| my_app +cd my_app +bin/cake server ``` -> [!TIP] -> Visit **** to see your blog in action! - -## Next Steps - -Now that you've built your first CakePHP application, here are some great places to continue your journey: - -**Learn the Fundamentals:** - -- [CakePHP Conventions](intro/conventions) - Understanding the naming conventions that power CakePHP -- [MVC Pattern](intro) - How CakePHP structures applications -- [Configuration](development/configuration) - Customizing your application - -**Build Real Applications:** - -- [Tutorials & Examples](tutorials-and-examples) - Step-by-step guides -- [CMS Tutorial](tutorials-and-examples/cms/installation) - Build a complete content management system - -**Master Core Features:** - -- [Database & ORM](orm) - Advanced queries, associations, and data modeling -- [Controllers](controllers) - Request handling, components, and middleware -- [Views](views) - Templates, helpers, and rendering -- [Security](security) - Best practices for secure applications - -## Get Help +Then open [localhost:8765](http://localhost:8765). -Join our community and get the support you need: - - - -**Additional Resources:** - -- [API Documentation](https://api.cakephp.org/5.0/) - Complete API reference -- [Stack Overflow](https://stackoverflow.com/questions/tagged/cakephp) - Find answers to common questions - -## How CakePHP Works - -Understanding the request flow helps you build better applications. Here's what happens when a user visits your CakePHP application: - -
-CakePHP request flow diagram
-**A typical request follows these steps:** +## Explore the guides -1. 🌐 **Request arrives** → Webserver routes to `webroot/index.php` -2. ⚙️ **Application boots** → Your app is loaded and middleware initializes -3. 🛣️ **Routing** → Request is matched to a controller and action -4. 🎮 **Controller** → Action is called, interacts with Models -5. 📊 **Model Layer** → Fetches and processes data from the database -6. 🎨 **View Layer** → Renders the response (HTML, JSON, XML, etc.) -7. 📤 **Response sent** → Back through middleware to the client +Jump straight to the part of your application you're working on. -::: tip Understanding MVC -The **Model** handles your data and business logic, the **Controller** coordinates the request, and the **View** presents the data. This separation keeps your code organized and testable. +
-[Learn more about MVC in CakePHP →](intro) -::: + -## Everything You Need, Out of the Box +

HTTP

-CakePHP comes with powerful features that save you time and help you build better applications: +Handle requests and responses with controllers and components. -::: details 🚀 Code Generation (Bake) -Generate complete CRUD applications in seconds: +
-```bash -bin/cake bake all Articles -# Creates: Model, Controller, Views, Tests -``` + -Bake can scaffold entire features, saving hours of repetitive coding. Perfect for prototyping or generating boilerplate. +

Database

-[Learn more about Bake →](https://book.cakephp.org/bake/2/en/) -::: +Work with tables, queries, associations, and application data. -::: details 💾 Caching Framework -Integrated caching with multiple backends: +
-```php -// Cache expensive operations -$results = Cache::remember('expensive_query', function () { - return $this->Articles->find('complex')->toArray(); -}); -``` + -**Supported backends:** Redis, Memcached, APCu, File, Database +

Views

-[Learn more about Caching →](core-libraries/caching) -::: +Create templates, layouts, and reusable helpers. -::: details 🧪 Built-in Testing -Write tests with confidence using the integrated testing framework: +
-```php -public function testAddArticle(): void -{ - $this->post('/articles/add', ['title' => 'Test']); - $this->assertResponseOk(); - $this->assertFlashMessage('Article saved!'); -} -``` - -Supports unit tests, integration tests, and browser tests out of the box. - -[Learn more about Testing →](development/testing) -::: + -::: details 🔐 Authentication & Authorization -Drop-in user management with flexible policies: +

Security

-```bash -composer require cakephp/authentication cakephp/authorization -``` +Explore the tools for protecting your application. -Handle login, permissions, and access control with minimal configuration. +
-[Authentication Guide →](https://book.cakephp.org/authentication/) • [Authorization Guide →](https://book.cakephp.org/authorization/) -::: + -::: details 🌐 REST API Support -Build APIs with automatic content type negotiation: +

Testing

-```php -// Automatically serves JSON/XML based on Accept header -public function index() -{ - $articles = $this->Articles->find('all'); - $this->set('articles', $articles); - $this->viewBuilder()->setOption('serialize', ['articles']); -} -``` +Build confidence with unit tests and integration tests. -Supports JSON, XML, and custom formats with minimal code. +
-[Learn more about REST →](development/rest) -::: + -::: details 📦 Database Migrations -Version control your database schema: +

Deployment

-```bash -bin/cake bake migration CreateArticles -bin/cake migrations migrate -``` +Get your application ready for production. -Keep your database changes in sync across development, staging, and production. +
-[Learn more about Migrations →](https://book.cakephp.org/migrations/) -::: - -## What Makes CakePHP Special? - -::: code-group +
-```php [Convention Over Configuration] - -// No configuration needed! CakePHP automatically knows: -// - ArticlesController uses ArticlesTable -// - ArticlesTable uses 'articles' database table -// - Primary key is 'id' -// - Foreign keys end in '_id' -// - Templates are in templates/Articles/ +[All topics →](topics) -class ArticlesController extends AppController -{ - // That's it! Table is auto-loaded - public function index(): void - { - $articles = $this->Articles->find('all'); - $this->set(compact('articles')); - } -} -``` +[API reference ↗](https://api.cakephp.org/) -```php [Powerful ORM] -Articles->find() - ->contain(['Users', 'Comments']) - ->matching('Tags', function ($q) { - return $q->where(['Tags.name IN' => ['PHP', 'CakePHP']]); - }) - ->where(['Articles.published' => true]) - ->orderBy(['Articles.view_count' => 'DESC']) - ->limit(10); -``` +
-```php [Built-in Security] - -// Automatic protection against common vulnerabilities: -// ✓ SQL Injection (parameterized queries) -// ✓ CSRF attacks (token validation) -// ✓ XSS (auto-escaping in templates) -// ✓ Mass assignment (protected fields) +## Get Help -$article = $this->Articles->newEntity($data); -// Only patchable fields can be set -``` +You don't have to figure it all out on your own. Find support or help improve the Cookbook. -```bash [Code Generation] -# Generate complete CRUD in seconds -bin/cake bake all Articles +
-# Creates: -# ✓ Model (Table + Entity) -# ✓ Controller (with all actions) -# ✓ Templates (index, view, add, edit) -# ✓ Tests (full coverage) -``` +[Find help →](intro/where-to-get-help) -::: +[Community forum ↗](https://discourse.cakephp.org/) -
+[Contribute →](contributing) -
- Ready to Build Something Amazing
-

Ready to Build Something Amazing?

- -**Start your CakePHP journey today and join thousands of developers building modern web applications.** - -

- Get Started → - • - Join Community - • - View Examples -

-
diff --git a/docs/en/quickstart.md b/docs/en/quickstart.md index 56b9d02e2a..b76e56e370 100644 --- a/docs/en/quickstart.md +++ b/docs/en/quickstart.md @@ -84,4 +84,6 @@ Dive deeper into CakePHP's powerful features: ### Get Help & Connect - +- [Find help](intro/where-to-get-help) - Places to ask questions and get support +- [Community forum](https://discourse.cakephp.org/) - Connect with other CakePHP developers +- [Contribute to the Cookbook](contributing) - Help improve the documentation From 0e3b7684dc5173ca37fc0fe2fdbb5034e6a3b6c8 Mon Sep 17 00:00:00 2001 From: Jasper Smet Date: Sat, 3 Oct 2026 10:34:54 +0200 Subject: [PATCH 2/2] Allow homepage Vue components in Markdown lint --- .github/.markdownlint-cli2.jsonc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/.markdownlint-cli2.jsonc b/.github/.markdownlint-cli2.jsonc index 823ca5e162..9d4024bbcf 100644 --- a/.github/.markdownlint-cli2.jsonc +++ b/.github/.markdownlint-cli2.jsonc @@ -18,6 +18,10 @@ "no-inline-html": { "allowed_elements": [ "Badge", + "HomeWelcome", + "HomeCard", + "script", + "h3", "div", "span", "br",