diff --git a/.vitepress/config.ts b/.vitepress/config.ts
index 60841558..8c233938 100644
--- a/.vitepress/config.ts
+++ b/.vitepress/config.ts
@@ -168,8 +168,9 @@ const mainSidebar = [
{ text: 'Introduction', link: '/docs/introduction/' },
{ text: 'Why Leaf?', link: '/docs/introduction/why' },
{ text: 'Installation', link: '/docs/introduction/installation' },
+ { text: 'Leaf + MVC', link: '/docs/mvc/' },
{ text: 'Using Docker', link: '/docs/introduction/docker' },
- { text: 'Migration Guide', link: '/docs/migration/introduction' }
+ { text: 'Migration Guide', link: '/docs/migration/other' },
]
},
{
@@ -177,13 +178,12 @@ const mainSidebar = [
collapsible: true,
collapsed: true,
items: [
- { text: 'Leaf + MVC', link: '/docs/mvc/' },
- { text: 'Leaf Devtools', link: '/modules/devtools/' },
+ { text: 'Leaf CLI', link: '/docs/cli/' },
{ text: 'Modules', link: '/modules/' },
{ text: 'Functional Mode', link: '/docs/tooling/functions' },
{ text: 'Leaf tutorial', link: '/tutorial/' },
- { text: 'Leaf CLI', link: '/docs/cli/' },
{ text: 'Your first app', link: '/docs/introduction/first-app' },
+ { text: 'Leaf Devtools', link: '/modules/devtools/' },
{ text: 'Testing', link: '/docs/tooling/testing' },
{ text: 'Deployment', link: '/docs/tooling/deployment' }
]
@@ -194,9 +194,10 @@ const mainSidebar = [
collapsed: true,
items: [
{ text: 'Overview', link: '/docs/config/' },
- { text: 'Instance and Mode', link: '/docs/config/nsm' },
{ text: 'App settings', link: '/docs/config/settings' },
- { text: 'Dependency Injection', link: '/docs/tooling/container' }
+ { text: 'Application Env', link: '/docs/config/nsm' },
+ { text: 'URL Rewriting', link: '/docs/introduction/url-rewriting' },
+ { text: 'Dependency Injection', link: '/docs/tooling/container' },
]
},
{
@@ -204,7 +205,6 @@ const mainSidebar = [
collapsible: true,
collapsed: true,
items: [
- { text: 'URL Rewriting', link: '/docs/introduction/url-rewriting' },
{ text: 'Request', link: '/modules/http/v/2/request' },
{ text: 'Response', link: '/modules/http/v/2/response' },
{ text: 'Headers', link: '/modules/http/v/2/headers' },
@@ -223,6 +223,7 @@ const mainSidebar = [
collapsed: true,
items: [
{ text: 'Basic Routing', link: '/docs/routing/' },
+ { text: 'MVC Support', link: '/docs/routing/mvc' },
{ text: 'Route Groups', link: '/docs/routing/sub-routing' },
{ text: 'Dynamic routing', link: '/docs/routing/dynamic' },
{
@@ -239,6 +240,7 @@ const mainSidebar = [
collapsed: true,
items: [
{ text: 'Introduction', link: '/modules/db/' },
+ { text: 'MVC Support', link: '/modules/db/mvc' },
{ text: 'Query Builder', link: '/modules/db/v/2/builder' },
{ text: 'Leaf Redis', link: '/modules/redis/' }
]
@@ -249,15 +251,16 @@ const mainSidebar = [
collapsed: true,
items: [
{ text: 'Introduction', link: '/modules/auth/' },
+ { text: 'MVC Support', link: '/modules/auth/mvc' },
{ text: 'Auth Config', link: '/modules/auth/config' },
{ text: 'User Login', link: '/modules/auth/login' },
{ text: 'User Sign Up', link: '/modules/auth/signup' },
+ { text: 'Auth Session', link: '/modules/auth/session' },
{
text: 'Protecting your Routes',
link: '/modules/auth/protecting-your-routes'
},
{ text: 'Updating logged-in user', link: '/modules/auth/update' },
- { text: 'Session Support', link: '/modules/auth/session' },
{ text: 'Helper methods', link: '/modules/auth/helpers' }
]
},
@@ -266,11 +269,11 @@ const mainSidebar = [
collapsible: true,
collapsed: true,
items: [
- { text: 'Leaf Forms', link: '/modules/forms/v/1.2/' },
+ { text: 'Validation', link: '/modules/forms/v/2/' },
{ text: 'Leaf Password', link: '/modules/password/' },
{ text: 'Leaf Anchor', link: '/modules/anchor/' },
- { text: 'Leaf Date', link: '/modules/date/' },
- { text: 'Leaf Fetch', link: '/modules/fetch/' },
+ { text: 'Date/Time', link: '/modules/date/' },
+ { text: 'Data Fetching', link: '/modules/fetch/' },
{ text: 'Logging', link: '/docs/tooling/logging' }
]
},
@@ -296,8 +299,11 @@ const mainSidebar = [
{ text: 'Bare UI', link: '/modules/views/bareui/' },
{ text: 'Leaf Blade', link: '/modules/views/blade/' },
{ text: 'Leaf Veins', link: '/modules/views/veins/' },
+ { text: 'Other Engines', link: '/modules/views/third-party/' },
+ { text: 'Vite JS', link: '/modules/views/vite/' },
+ { text: 'Inertia JS', link: '/modules/views/inertia/' },
{ text: 'Viewi PHP', link: '/modules/views/viewi/' },
- { text: 'Leaf UI', link: '/modules/views/leaf-ui/' }
+ { text: 'Leaf UI', link: '/modules/views/leaf-ui/' },
]
},
{
@@ -309,7 +315,6 @@ const mainSidebar = [
{ text: 'Leaf API', link: '/docs/leafapi/' },
{ text: 'Skeleton', link: '/docs/skeleton/' },
{ text: 'MVC Config', link: '/docs/mvc/config' },
- { text: 'MVC Routing', link: '/docs/mvc/routing' },
{ text: 'Controllers', link: '/docs/mvc/controllers' },
{ text: 'Views', link: '/docs/mvc/views' },
{ text: 'Models', link: '/docs/mvc/models' },
@@ -317,9 +322,10 @@ const mainSidebar = [
{ text: 'Schema', link: '/docs/mvc/schema' },
{ text: 'Seeders', link: '/docs/mvc/seeds' },
{ text: 'Factories', link: '/modules/mvc-core/factories' },
- // { text: 'MVC Console Tool', link: '/docs/mvc/console' },
- { text: 'Aloe CLI', link: '/aloe-cli/' },
- { text: 'MVC Core', link: '/modules/mvc-core/' }
+ { text: 'Writing Commands', link: '/docs/mvc/commands' },
+ { text: 'Mailing', link: '/docs/mvc/mail' },
+ { text: 'MVC Helpers', link: '/docs/mvc/globals' },
+ { text: 'MVC Console Tool', link: '/docs/mvc/console' },
]
},
{
diff --git a/.vitepress/theme/components/PreferenceSwitch.vue b/.vitepress/theme/components/PreferenceSwitch.vue
index 0c9d0134..dfd0ab7d 100644
--- a/.vitepress/theme/components/PreferenceSwitch.vue
+++ b/.vitepress/theme/components/PreferenceSwitch.vue
@@ -22,7 +22,7 @@ onMounted(() => {
const route = useRoute()
const show = $computed(() =>
- /^\/(guide|docs|tutorial|examples|modules)\//.test(route.path) && !/^\/(docs\/tooling\/functions|docs\/config|modules\/db\/v\/1|modules\/http\/v\/2\/headers|modules\/date|modules\/fs|docs\/tooling\/testing)\//.test(route.path.replace('.html', '/'))
+ /^\/(guide|docs|tutorial|examples|modules)\//.test(route.path) && !/^\/(docs\/tooling\/functions|docs\/config\/settings|modules\/db\/v\/1|modules\/http\/v\/2\/headers|modules\/date|modules\/fs|docs\/tooling\/testing)\//.test(route.path.replace('.html', '/'))
)
const showFullText = $computed(() =>
/^\/(tutorial|examples)\//.test(route.path)
diff --git a/.vitepress/theme/styles/pages.css b/.vitepress/theme/styles/pages.css
index d859a439..2d807ec7 100644
--- a/.vitepress/theme/styles/pages.css
+++ b/.vitepress/theme/styles/pages.css
@@ -19,3 +19,16 @@
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 1rem;
}
+
+.dark .custom-block [class*='language-'] pre {
+ background-color: var(--vt-c-theme-plain);
+}
+
+.dark .custom-block .custom-block {
+ background-color: var(--vt-c-theme-plain) !important;
+ border-left: none !important;
+}
+
+.details.custom-block::before {
+ content: none !important;
+}
diff --git a/LICENSE b/LICENSE
index 8944fd0b..55b818a7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2019 vuejs
+Copyright (c) 2023 Michael Darko-Duodu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -19,3 +19,11 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+
+--------------------------------------------------------------------------------
+Third party licenses are below
+--------------------------------------------------------------------------------
+
+Parts of this project's code was based on code from the below repositories:
+
+- LICENSE.VUEJS https://github.com/vuejs/docs
diff --git a/LICENSE.VUEJS b/LICENSE.VUEJS
new file mode 100644
index 00000000..8944fd0b
--- /dev/null
+++ b/LICENSE.VUEJS
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 vuejs
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/netlify.toml b/netlify.toml
index 238ab5df..8690fdfe 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -1,3 +1,7 @@
+[[redirects]]
+ from = "/aloe-cli/"
+ to = "/docs/mvc/console"
+
[build.environment]
NODE_VERSION = "16"
NPM_FLAGS = "--version" # prevent Netlify npm install
diff --git a/package.json b/package.json
index 7fca0248..7b38243b 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"dependencies": {
"449.css": "^1.3.0",
"@codemirror/lang-php": "^6.0.0",
- "@leafphp/docs-theme": "^0.1.2",
+ "@leafphp/docs-theme": "0.1.2",
"@vue/repl": "^1.2.4",
"axios": "^0.27.2",
"dynamics.js": "^1.1.5",
@@ -29,7 +29,8 @@
"@algolia/client-search",
"react",
"react-dom",
- "@types/react"
+ "@types/react",
+ "search-insights"
]
}
}
diff --git a/src/aloe-cli/index.md b/src/aloe-cli/index.md
index 590e4505..d9eb856a 100755
--- a/src/aloe-cli/index.md
+++ b/src/aloe-cli/index.md
@@ -30,8 +30,8 @@ Available commands:
aloe
aloe:config Install aloe config
app
- app:down Place app in maintainance mode
- app:up Remove app from maintainance mode
+ app:down Place app in maintenance mode
+ app:up Remove app from maintenance mode
d
d:command Delete a console command
d:controller Delete a controller
diff --git a/src/aloe-cli/v/1.2.3/index.md b/src/aloe-cli/v/1.2.3/index.md
index fbf1faab..b62439b0 100644
--- a/src/aloe-cli/v/1.2.3/index.md
+++ b/src/aloe-cli/v/1.2.3/index.md
@@ -83,8 +83,8 @@ Available commands:
aloe
aloe:config Install aloe config
app
- app:down Place app in maintainance mode
- app:up Remove app from maintainance mode
+ app:down Place app in maintenance mode
+ app:up Remove app from maintenance mode
d
d:command Delete a console command
d:controller Delete a controller
diff --git a/src/community/team/Member.ts b/src/community/team/Member.ts
index f124977e..9ad76d87 100644
--- a/src/community/team/Member.ts
+++ b/src/community/team/Member.ts
@@ -22,4 +22,6 @@ export interface Socials {
github: string
twitter?: string
codepen?: string
+ instagram?: string
+ linkedin?: string
}
diff --git a/src/community/team/TeamMember.vue b/src/community/team/TeamMember.vue
index a326324d..70e11d8d 100644
--- a/src/community/team/TeamMember.vue
+++ b/src/community/team/TeamMember.vue
@@ -6,6 +6,7 @@ import {
VTIconGitHub,
VTIconGlobe,
VTIconHeart,
+ VTIconInstagram,
VTIconLink,
VTIconLinkedIn,
VTIconMapPin,
@@ -158,6 +159,15 @@ const avatarUrl = computed(() => {
+
+
+
+
+
{
padding: 20px 32px 32px;
}
-@media (min-width: 512px) {
- .data {
- padding: 40px 32px 32px 32px;
- }
-}
-
.name {
font-size: 20px;
font-weight: 500;
diff --git a/src/community/team/members-core.json b/src/community/team/members-core.json
index 468bb2b3..4d3bc5a7 100644
--- a/src/community/team/members-core.json
+++ b/src/community/team/members-core.json
@@ -17,6 +17,24 @@
},
"sponsor": false
},
+ {
+ "name": "André Rosa",
+ "title": "Developer",
+ "company": "Leaf PHP",
+ "projects": [
+ {
+ "label": "leafsphp/*",
+ "url": "https://www.github.com/leafsphp"
+ }
+ ],
+ "location": "Portugal",
+ "languages": ["Portuguese", "English"],
+ "socials": {
+ "github": "crosa7",
+ "twitter": "andre_crosa"
+ },
+ "sponsor": false
+ },
{
"name": "Ashley Nyanteh",
"title": "Community Manager",
diff --git a/src/docs/cli/index.md b/src/docs/cli/index.md
index 04424ccb..2a6911fc 100644
--- a/src/docs/cli/index.md
+++ b/src/docs/cli/index.md
@@ -1,15 +1,17 @@
# Leaf CLI
+
+
-
+
-
+
-Leaf CLI is a simple command line tool for creating and interacting with your leaf projects. You can do stuff like installing packages, interacting with your app, previewing your app...
+Leaf CLI is a simple command line tool for creating and interacting with your Leaf applications. It gives you the options to create projects, install dependencies, run scripts, scaffold items and much more.
## Installation
@@ -19,7 +21,13 @@ Leaf CLI is a simple command line tool for creating and interacting with your le
link="https://www.youtube.com/embed/yb3LUYHtopQ"
/>
-You can get this tool up and running on your system using composer:
+You can install the leaf cli using composer. Composer is a dependency manager for PHP. You can follow the instructions on [getcomposer.org](https://getcomposer.org) to install composer on your system. From there, you should have access to the `composer` command from anywhere on your system.
+
+```bash
+composer --version
+```
+
+You should then be able to get the Leaf CLI up and and running on your system using composer:
```bash
composer global require leafs/cli
@@ -27,9 +35,13 @@ composer global require leafs/cli
After that, you should have access to the `leaf` command from anywhere on your system.
+```bash
+leaf --version
+```
+
## command not found: leaf
-If you get a `command not found: leaf` error, it means your composer bin is not in your path.
+If you get a `command not found: leaf` error, it means your composer bin is not in your system path.
You need to make sure that Composer's system-wide vendor bin directory is in your system `$PATH` so the leaf executable can be located by your system. This directory exists in different locations based on your operating system; however, some common locations include:
@@ -83,93 +95,129 @@ source ~/.bashrc
link="https://www.youtube.com/embed/PuOk5xqTIsA"
/>
-To start a new project, simply open up your console or terminal and move into the directory you want to generate your project. From there, you can use the `create` command:
+To start a new project, open up your terminal and move into a directory you want to generate your projects in. From there, you can use the `leaf create` command to set up a new Leaf app in that directory:
```bash
leaf create
```
-with leaf 3:
+This will prompt you to select a preset. Presets are quick ways to get your project up and running as quickly as possible. You can select a preset from the list of presets displayed to you:
```bash
-leaf create --v3
+? What kind of app do you want to create? [leaf]
+ [0] leaf
+ [1] leaf mvc
+ [2] leaf api
+ >
```
-or with leaf 2:
+*You can select a number or type in the preset you prefer.*
+
+A leaf app will be generated based on the associated preset. As you can see, there are 3 presets:
+
+- **Leaf**: a bare Leaf project
+- **Leaf MVC**: a Leaf project with leaf mvc
+- **Leaf API**: a Leaf project with leaf api
+
+The Leaf CLI will automatically install the dependencies for the preset you selected and set up your project using Leaf 3. From there, you can `cd` into your project and start building.
```bash
-leaf create --v2
+cd
+leaf serve
```
-This will now prompt you to select a preset
+### Custom installation New
+
+The Leaf CLI also comes with a custom installation option. This allows you to customize your project to your liking. You can select the features you want to add to your project and the Leaf CLI will set it up for you.
```bash
-Creating a new Leaf app "" in ./projects-directory.
+leaf create --custom
+```
-* Please pick a preset
- [0] leaf
- [1] leaf mvc
- [2] leaf api
- [3] skeleton
+This will prompt you to select the features you want to add to your project. You can select the features you want to add to your project from the list of features displayed to you:
+
+```bash
+? What modules would you like to add? [none] eg: 1,2,7
+ [0] None
+ [1] Database
+ [2] Authentication
+ [3] Session support
+ [4] Cookie support
+ [5] CSRF protection
+ [6] CORS support
+ [7] Leaf Date
+ [8] Leaf Fetch
>
```
-::: tip
-Note that you are to select a number, not type the name of the preset.
-:::
+For Leaf MVC, you can also select things like the View engine you prefer to use:
+
+```bash
+? What view engine would you like to use? [Blade]
+ [0] Blade
+ [1] Bare UI
+ [2] React/Vue
+ >
+```
-Selecting a number will generate a leaf app based on the associated preset. As you can see, there are 4 presets:
+Whether to add a bundler for your frontend assets:
-- **Leaf**: a bare leaf project
-- **Leaf MVC**: a leaf MVC project with leaf 2
-- **Leaf API**: a leaf API project with leaf 2
-- **Skeleton**: a leaf skeleton project
+```bash
+? Do you want to add Vite to bundle your assets? [Yes]
+```
-After picking a preset, if no version was specified, leaf will display an interactive version picker like the one above:
+And whether to add a testing framework:
```bash
-* Select a version to use
- [0] v3
- [1] v2
+? What testing framework would you like to use? [none]
+ [0] none
+ [1] pest
+ [2] phpunit
>
```
-your project will be automatically generated and initialized. All you need to do is open it up and start coding 🚀
+### Quick presets
-### Adding Tests
+Leaf CLI also provides a quicker way to initialize your project without having to go through the interactive installer. You can use the `--mvc`, `--api`, and `--basic` options to generate your project based on a specific presets. These generate the following:
-From Leaf CLI v2.3, you will be asked if you want to add tests to your project. You can add tests by replying `y`.
+- `--basic`: a bare Leaf project
+- `--mvc`: a Leaf project with leaf mvc
+- `--api`: a Leaf project with leaf api
```bash
-* Add testing with Leaf Alchemy? [y, n] y
-
- - Adding alchemy for tests
+leaf create --mvc
```
-For a quicker method, you can use the `--phpunit` or `--pest` option to add tests to your project using PHPUnit or Pest respectively. You can also use the `--no-tests` option to completely skip adding tests.
+### Adding Tests
+
+The Leaf CLI by default will generate your project without any testing framework. However, you will be prompted to add a testing framework if you select the `--custom` option.
```bash
-leaf create --no-tests
+leaf create --custom
```
-### Quick presets
-
-Leaf CLI also provides a quicker way to initialize your project without having to go through the interactive installer. You can use the `--mvc`, `--api`, `--basic` and `--skeleton` options to generate your project based on a specific presets. `--basic` generates a raw leaf project.
+You can still add a testing framework without using the `--custom` option by using either the `--pest` for Pest PHP tests:
-eg: `leaf create backend-api --api`
+```bash
+leaf create --pest
+```
-This will create a leaf api project named `backend-api`.
+Or the `--phpunit` option for PHPUnit tests:
-### Versioning
+```bash
+leaf create --phpunit
+```
-If no version is specified, leaf displays the interactive installer to you, however, to quickly install a particular version, you can use the `--v2` or `--v3` options. These can be coupled with presets as well.
+### Using docker
-Leaf API 3 example:
+Leaf CLI also provides a way to generate your project with docker. You can use the `--docker` option to add all the necessary files to your project to run it with docker.
```bash
-leaf create backend-api --api --v3
+leaf create --docker
```
+If you are using the `--custom` option, you will be asked if you want to add docker to your project. For the full docker guide, you can check out the [docker guide](/docs/introduction/docker).
+
## Running your leaf apps
After generating your leaf app, you can `cd` into the directory and spin up a local dev server using leaf cli's `serve` command.
@@ -195,7 +243,7 @@ leaf serve --port 8000 --watch
### Dependency Management
-The serve command also now installs dependencies when there is no `vendor` folder present in the current working directory.
+The serve command will also try to install dependencies for your project if it doesn't detect a `vendor` folder present in the current working directory.
New
+
+Leaf CLI also allows you to create and interact with frontend setups using the `view` commands. You can scaffold frontend setups like React, Vue, templating engines, build tools, and more.
+
+### Scaffolding views
+
+Leaf CLI ships with a `view:install` command that allows you to setup React, Vue, and templating engines like Blade and BareUI. You can use the `--react`, `--vue`, `--blade`, and `--bareui` options to scaffold your frontend setup.
+
+```bash
+leaf view:install --react
+```
+
+You can also use the `--vite` and `--tailwind` options to scaffold Vite and Tailwind respectively.
+
+### Running frontend setups
+
+Since Leaf CLI is a backend tool, it doesn't come with a frontend server. However, you can use the `view:dev` command to run your frontend setup which may include in a dev server for your frontend.
+
+```bash
+leaf view:dev
+```
+
+### Building frontend setups
+
+You can also use the `view:build` command to build your frontend setup for production.
+
+```bash
+leaf view:build
+```
+
## Running Scripts
Leaf CLI also now allows you run scripts defined in your `composer.json` file. For example, if you have this in your composer.json:
@@ -309,7 +380,7 @@ leaf run test
```bash
_ __ ___ _ ___
-| | ___ __ _ / _| / __| | |_ v2.7.0
+| | ___ __ _ / _| / __| | |_ v2.8.3
| |__/ -_) _` | _| | (__| |__ | |
|____\___\__,_|_| \___|____|___|
@@ -326,20 +397,24 @@ Options:
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands:
- completion Dump the shell completion script
- create [init] Create a new Leaf PHP project
- deploy [publish] Deploy your leaf project
- help Display help for a command
- install Add a new package to your leaf app
- interact Interact with your application
- list List commands
- run Run a script in your composer.json
- serve Run your Leaf app
- test Test your leaf application through leaf alchemy
- uninstall Uninstall a package
- update Update leaf cli to the latest version
+ completion Dump the shell completion script
+ create [init|new] Create a new Leaf PHP project
+ deploy [publish] Deploy your leaf project
+ help Display help for a command
+ install Add a new package to your leaf app
+ interact Interact with your application
+ list List commands
+ run Run a script in your composer.json
+ serve Run your Leaf app
+ test Test your leaf application through leaf alchemy
+ uninstall Uninstall a package
+ update Update leaf cli to the latest version
test
- test:setup Add tests to your application
+ test:setup Add tests to your application
+ view
+ view:build Run your frontend dev server
+ view:dev Run your frontend dev server
+ view:install Run a script in your composer.json
```
This is the full list of commands available with Leaf CLI 2. A new update command has been added to allow you seamlessly update leaf CLI without having to run a bunch of commands. You don't even need to run this manually since leaf cli will automatically check for updates and upgrade to the latest stable release.
diff --git a/src/docs/config/index.md b/src/docs/config/index.md
index de50fefa..396dd8d6 100755
--- a/src/docs/config/index.md
+++ b/src/docs/config/index.md
@@ -1,120 +1,148 @@
-
# Overview
+
+
-::: tip
-Leaf aims for zero configurations out of the box, as such, none of these configurations are required. But for those who want other options with Leaf, this is the place for you.
-:::
+Unlike other frameworks, Leaf requires no configuration out of the box. However, Leaf provides options for those who want to customize the framework to their needs.
## Applying Config
-There are three ways to apply settings to the Leaf application. First during Leaf application instantiation, second with the leaf config class and finally, after instantiation. All settings can be applied at instantiation time by passing Leaf’s constructor an associative array. All settings can be retrieved and modified after instantiation, however some of them can not be done simply by using the config application instance method but will be demonstrated as necessary below. Before I list the available settings, I want to quickly explain how you may define and inspect settings with your Leaf application.
+There are 32 main ways to apply config to your Leaf application. Although they achieve the same result, each method has its own advantages and disadvantages. Let's take a look:
-
+
-### During Instantiation
+- **Passing config during instantiation**
-To define settings upon instantiation, pass an associative array into the Leaf constructor.
+ To define settings upon instantiation, pass an associative array into the Leaf constructor. The array keys are the setting names and the array values are the setting values. This is the most performant way to define settings for Leaf, and we'll recommend this if you're using class mode.
-```php
-$app = new Leaf\App([
+ ```php
+ $app = new Leaf\App([
'debug' => true
-]);
-```
+ ]);
+ ```
-### Leaf Config
+- **Using the `config()` method**
-Leaf config allows you to quickly configure your leaf application from anywhere in your app.
+ This method is the most common way to apply config to your Leaf application. It's also the most flexible way to apply config. You can apply config at any point in your application, and you can apply multiple config at once. *Note that the config will only be applied to code that comes after the config method.*
-```php
-Leaf\Config::set([
- "views.path" => "views",
- "views.cachePath" => "views/cache"
-]);
-```
+ ```php
+ $app = new Leaf\App;
+ $app->config([
+ 'debug' => true,
+ 'views.path' => '../views'
+ ]);
+ ```
-The best part of this is that you don't need to pass these configurations to any file or methods. Leaf automatically picks up all the configurations made in this file whether the configuration is done before of after initializing leaf.
+
+
-You can also get configuration values using `get`
+- **Using the `config()` method**
-```php
-$appConfig = Leaf\Config::get("views.path");
-```
+ The `config()` method is the recommended way to apply config to your Leaf application. It allows you to set and get config values at any point in your application, and you can apply multiple config at once. *Note that the config will only be applied to code that comes after the config method.*
-You can also get all the settings your app is using by leaving the parameter on Leaf Config empty
+ ```php
+ app()->config([
+ 'debug' => true,
+ 'views.path' => '../views'
+ ]);
+ ```
-```php
-$appConfig = Leaf\Config::get();
-```
+
-### After Instantiation
+- **Using the `Leaf\Config` class**
-To define settings after instantiation, the majority can use the config application instance method; the first argument is the setting name and the second argument is the setting value.
+ The Config class is the central point for all of Leaf's config. It allows you to set and get config from anywhere in your app. However, it is best to set config before initializing Leaf.
-```php
-$app = new Leaf\App;
-$app->config('debug', false);
-```
+ ```php
+ Leaf\Config::set([
+ 'views.path' => 'views',
+ 'views.cachePath' => 'views/cache'
+ ]);
-You may also define multiple settings at once using an associative array:
+ // your leaf app after this
+ ```
+
+## Nested Config
+
+Leaf allows you to nest config into groups. This means that you can group config into arrays. This is especially useful when you're scoping features based on some configuration.
+
+For example, you can group all your server config into a `server` array:
+
+
```php
-$app->config([
- 'debug' => true,
- 'views.path' => '../views'
+$app = new Leaf\App([
+ 'server' => [
+ 'host' => 'localhost',
+ 'port' => 8080
+ ]
]);
```
-To retrieve the value of a setting, you also use the config application instance method; however, you only pass one argument - the name of the setting you wish to inspect. If the setting you request does not exist, null is returned.
+
+
```php
-$settingValue = $app->config('views.path'); // returns "../views"
+app()->config([
+ 'server' => [
+ 'host' => 'localhost',
+ 'port' => 8080
+ ]
+]);
```
-## Nested Config
+
-From v3 of leaf, config works a little bit differently under the hood. Leaf now allows you to set and get config under groups in an array form. Before, all config was saved in one flat array, and you namespacing commands eg: `app.down` would add a new entry in the flat array just as defined.
+You can then access the config using the `config()` method:
-Leaf Config in v3 now creates a sub array which allows you to group all the config related to an item in an array.
+
-::: tip Note
-This in no way affects the way Leaf config works, it simply creates new possibilities for use, especially externally with modules and functional mode.
-:::
+```php
+$app->config('server.host'); // localhost
+```
-Instead of your config looking like this:
+
+
```php
-['app.down' => false, ..., 'log.enabled' => false, 'log.file' => '1.txt', ...]
+app()->config('server.host'); // localhost
```
-You'll have this:
+
+
+
+You can also retrieve the entire config group by passing the group name:
+
+
```php
-['app' => ['down' => false, ...], 'log' => ['enabled' => false, ...], ...]
+$app->config('server'); // ['host' => 'localhost', 'port' => 8080]
```
-This means that you can simply grab a single group if you want to:
+
+
```php
-$appConfig = app()->config('app');
-$loggerConfig = app()->config('log');
+app()->config('server'); // ['host' => 'localhost', 'port' => 8080]
```
-You can also create your own group and config:
+
-```php
-app()->config(['home.key' => '2']);
+This isn't limited to only retrieving config. You can also set config using the same method:
-$homeConfig = app()->config('home');
-$homeKey = $homeConfig['key'];
+
-// or
+```php
+$app->config('server.host', '127.0.0.1');
+```
+
+
+
-$homeKey = app()->config('home.key');
+```php
+app()->config('server.host', '127.0.0.1');
```
+
+
diff --git a/src/docs/config/nsm.md b/src/docs/config/nsm.md
index a7402189..baa1e91f 100755
--- a/src/docs/config/nsm.md
+++ b/src/docs/config/nsm.md
@@ -1,90 +1,99 @@
-
-
-# Instance and Mode
-
-## Config app instance
+# Application Environment
-Once leaf is initialized, a config named app is populated with the app instance and container. You can use these from anywhere in your app.
+
-```php
-
+import VideoDocs from '/@theme/components/VideoDocs.vue'
+
-// ...
-$app = Leaf\Config::get("app")["instance"];
+When building an application, it is helpful to distinguish between what is "running locally" versus what is "running in production". For example, you may have a different database running locally than you do on your production server.
-$app->set404(Custom404::build());
-```
+To make this a breeze, Leaf provides robust support for environment based configuration, allowing you to conveniently handle configuration values for different environments.
-## Modes
+## Environment variables
-It is common practice to run web applications in a specific mode depending on the current state of the project. If you are developing the application, you will run the application in “development” mode; if you are testing the application, you will run the application in “test” mode; if you launch the application, you will run the application in “production” mode.
+In a sense of your applications, environment variables are dynamic values that affect the way your applications behave. They are part of the environment in which a process runs. For example, your app can use the value of the TEMP environment variable to discover a suitable location to store temporary files. Environment variables are easy to change between environments, such as development, staging, and production.
-Leaf supports the concept of modes in that you may define your own modes and prompt Leaf to prepare itself appropriately for the current mode. For example, you may want to enable debugging in “development” mode but not in “production” mode. The examples below demonstrate how to configure Leaf differently for a given mode.
+
-### What is a mode?
+## Loading env variables
-Technically, an application mode is merely a string of text - like `development` or `production` - that has an associated callback function used to prepare the Leaf application appropriately. The application mode may be anything you like: `testing`, `production`, `development`, or even `foo`.
+Leaf doesn't come with an env loader out of the box, but you can add one yourself. Env loaders allow you to load environment variables from a `.env` file into PHP's `$_ENV` and `$_SERVER` globals. You can then access these variables using the `_env()` helper function that Leaf provides. Here's a list of some of the most popular env loaders:
-### How do I set the app mode?
+- [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv)
+- [symfony/dotenv](https://github.com/symfony/dotenv)
-#### Use leaf config
+## Using env variables
-You can directly set the mode using Leaf Config.
+After loading your env variables, you can access them using the `_env()` helper function. The `_env()` function takes in a key and a default value. If the key is found, the value is returned, otherwise the default value is returned.
```php
-Leaf\Config::set("mode", "production");
+$serverEnvironment = _env('APP_ENV', 'development');
```
-#### Use application setting
+## Application Modes
-If an environment variable is not found, Leaf will next look for the mode in the application settings.
+Using the concept of environments like `development`, `testing`, and `production` is a common way to prepare an application to behave correctly in each environment. Leaf takes this concept one step further and introduces the concept of application modes. Application modes allow you to configure your application for a specific purpose.
-```php
-$app = new \Leaf\App([
- 'mode' => 'production'
-]);
-```
+For example, you may want to enable debugging in “development” mode but not in “production” mode. The examples below demonstrate how to configure Leaf differently for a given mode.
-#### Use .env
+### Setting your application mode
-You can also use the `APP_ENV` environment variable to set the application mode. Leaf will automatically search for this environment variable and set the application mode from it.
+Leaf will automatically set the application mode based on the value of the `APP_ENV` environment variable. If the `APP_ENV` environment variable is not set, Leaf will set the application mode to `development`. This is because Leaf assumes you are developing your application locally when no environment is set.
-::: warning NOTE
-If you want to go down this route, leaf expects you to load your environment variables correctly and will not be responsible for doing so. If however, you use Leaf API, Leaf MVC or Skeleton, this is already taken care of for you.
-:::
+You can also set the application mode manually using the `mode` setting in your application settings.
-#### Default mode
+
-If no mode setting is found, Leaf will set the application mode to `development`.
-
-### How do I use an app mode?
-
-After you instantiate a Leaf application, you may configure the Leaf application for a specific mode with the Leaf application’s `script` method. This method accepts two arguments: the name of the target mode and a callable function to be immediately invoked if the first argument matches the current application mode.
+```php
+$app->config([
+ 'mode' => 'production'
+]);
+```
-Assume the current application mode is `production`. Only the callable associated with the `production` mode will be invoked. The callable associated with the `development` mode will be ignored until the application mode is changed to `development`.
+
+
```php
-config([
- 'mode' => 'production'
+ 'mode' => 'production'
]);
```
+
+
+### Using your application mode
+
+The Leaf instance provides a `script()` method that allows you to register a callable that will be invoked when the application mode matches the given mode. The `script()` method accepts two arguments: the mode and a callable.
+
+
+
```php
-// Only invoked if mode is "production"
-app()->script('production', function () use ($app) {
- app()->config([
- 'log.enable' => true,
- 'debug' => false
- ]);
+$app->script('production', function () use ($app) {
+ $app->config([
+ 'log.enable' => true,
+ 'debug' => false
+ ]);
});
+```
+
+
+
-// Only invoked if mode is "development"
-app()->script('development', function () use ($app) {
- app()->config([
- 'log.enable' => false,
- 'debug' => true
- ]);
+```php
+app()->script('production', function () {
+ app()->config([
+ 'log.enable' => true,
+ 'debug' => false
+ ]);
});
```
+
+
+
+The above example will enable logging and disable debugging when the application mode is set to `production`.
diff --git a/src/docs/config/settings.md b/src/docs/config/settings.md
index 406aaa7a..37bba912 100755
--- a/src/docs/config/settings.md
+++ b/src/docs/config/settings.md
@@ -1,128 +1,84 @@
# App Settings
-
-These are configurations leaf uses to seamlessly configure your applications.
+
-## app
+Leaf has lots of configurations which can be used to determine the way Leaf behaves in your application. You can check the [config page](/docs/config/) for more information on how to set and get configs. This page will show you all the configs available in Leaf. Note that we will only cover the user-facing configs, configs that are used internally by Leaf will not be covered here.
-This is a new configuration that allows you to get information about your Leaf app and it's instance. It is recommended to **set** anything on this config key as Leaf automatically sets up everything you might need.
+## app.down
-After initializing Leaf with `new Leaf\App`, Leaf saves that instance with an `instance` key and the instance container as `container` inside the app config.
+This configuration tells Leaf whether to place your app in a maintenance like state. By default, this is set to `false`, but you can set it to `true` to place your app in a maintenance like state.
```php
-$app = new Leaf\App;
-
-// somewhere else...
-
-$application = Leaf\Config::get("app");
-
-// get the $app instance defined above
-$leafApp = $application["instance"];
-
-// get $app container
-$container = $application["container"];
-
-// use container data
-$container->response->json("hello");
-
-// use the $app instance
-$leafApp->get("/", function () {
- echo "something";
-});
-
-// you can also get information about that instance
-echo $leafApp->routes();
+'app.down' => true
```
-::: tip Note ⚡️
-Although you can do all of these, there is actually no need to. This is because Leaf 3 comes with functional mode which allows you to use the app instance from anywhere in your app.
+When your app is in a maintenance like state, Leaf will automatically load the `down` screen. You can customize this screen using Leaf's `setDown` method.
```php
-$app = new Leaf\App;
-
-// somewhere else...
-
-app()->response()->json("hello");
+$app->setDown(function () {
+ echo 'Custom Down Handler!';
+});
```
-:::
+**You can read more about the down screen [here](/docs/routing/errors#application-down).**
-## app.down
+## debug
-A new `app.down` config was added to replace the `mode=down` which caused problems in earlier releases. You can set this to true to place your app in a maintainance like state.
+By default, Leaf will display all errors and warnings you encounter while developing your app. However, when you're ready to deploy your app, you should turn off debugging to prevent users from seeing errors. You can do this by setting the `debug` config to `false`.
```php
-$app = new \Leaf\App([
- 'app.down' => true
-]);
+'debug' => false
```
-To top it all, you no longer need `setDown` unless you want to define a custom maintainance screen as Leaf's default app down screen is now automatically loaded.
+Note that when you set `debug` to `false`, Leaf will automatically turn off error reporting and display a custom error page to users. You can customize this page using Leaf's `setError` method.
```php
-$app->setDown(function () {
- echo "Custom Down Handler!";
+$app->setError(function () {
+ echo "Custom Error Handler!";
});
```
-## debug
+## Logging
-If debugging is enabled, Leaf will use its built-in error handler to display diagnostic information for uncaught Exceptions. If debugging is disabled, Leaf will instead invoke your custom error handler, passing it the otherwise uncaught Exception as its first and only argument.
+Leaf has a built-in logger that can be used to log errors and other messages. You can check the [logging page](/docs/tooling/logging) for more information on how to use Leaf's logger. This page will show you all the configs available for Leaf's logger.
-```php
-$app = new \Leaf\App([
- 'debug' => true
-]);
-```
-
-## http.version
-
-By default, Leaf returns an HTTP/1.1 response to the client. Use this setting if you need to return an HTTP/1.0 response. This is useful if you use PHPFog or an nginx server configuration where you communicate with backend proxies rather than directly with the HTTP client.
+To get started, make sure you have the [logger module](/docs/tooling/logging) installed. Once installed, you should have access to a `logger()` method on the Leaf instance. You can use this method to access Leaf's logger if you want to manually log messages.
```php
-$app = new \Leaf\App([
- 'http.version' => '1.1'
-));
-
-// After instantiation
-$app->config('http.version', '1.1');
+$app->logger()->info('Hello World!');
```
-## log.dir
+Below are all the configs available for Leaf's logger:
-This tells leaf which directory to save and look for logs.
+### log.enabled
+
+This enables or disables Leaf’s logger. You need to set this to `true` to enable logging.
```php
-Leaf\Config::set("log.dir", __DIR__ . "/logs/");
+'log.enabled' => true
```
-## log.enabled
+Note that if `log.enabled` is set to `false`. Leaf will skip initializing anything related to logs, as such, you won't have access to `$app->logger()`, `$app->log` or `$app->logWriter`.
-This enables or disables Leaf’s logger. To change this setting after instantiation you need to access Leaf’s logger directly and use its `setEnabled()` method.
+### log.dir
-```php
-// During instantiation
-$app = new \Leaf\App([
- 'log.enabled' => true
-]);
+This tells leaf which directory to save and look for logs.
-// After instantiation
-$app->logger()->enabled(true);
+```php
+'log.dir' => __DIR__ . '/logs/'
```
-::: warning log.enabled
-Note that if `log.enabled` is set to `false`. Leaf will skip initializing anything related to logs, as such, you won't have access to `$app->logger()`, `$app->log` or `$app->logWriter`.
-:::
-
-## log.file
+### log.file
This setting tells leaf which file to write logs to.
```php
-Leaf\Config::set("log.file", "crashes.log");
+'log.file' => 'crashes.log'
```
-## log.level
+*By default, Leaf will write logs to a file named `log.txt`.*
+
+### log.level
Leaf has these log levels:
@@ -137,24 +93,11 @@ Leaf has these log levels:
The `log.level` application setting determines which logged messages will be honored and which will be ignored. For example, if the `log.level` setting is `\Leaf\Log::INFO`, debug messages will be ignored while info, warn, error, and fatal messages will be logged.
-To change this setting after instantiation you must access Leaf’s logger directly and use its `setLevel()` method.
-
-```php
-// During instantiation
-$app = new \Leaf\App([
- 'log.level' => \Leaf\Log::DEBUG
-]);
-
-// After instantiation
-$log = $app->getLog();
-$log->setLevel(\Leaf\Log::WARN);
-```
-
-## log.open
+### log.open
This option takes in a boolean and determines whether Leaf should create the specified log file if it doesn't exist.
-## log.writer
+### log.writer
Use a custom log writer to direct logged messages to the appropriate output destination. By default, Leaf’s logger will write logged messages to `STDERR`. If you use a custom log writer, it must implement this interface:
@@ -162,40 +105,10 @@ Use a custom log writer to direct logged messages to the appropriate output dest
public write(mixed $message, int $level);
```
-The `write()` method is responsible for sending the logged message (not necessarily a string) to the appropriate output destination (e.g. a text file, a database, or a remote web service).
-
-To specify a custom log writer after instantiation you must access Leaf’s logger directly and use its `setWriter()` method:
-
-```php
-// During instantiation
-$app = new \Leaf\App([
- 'log.writer' => new \My\LogWriter()
-]);
-
-// After instantiation
-$app->logger()->setWriter(new \My\LogWriter());
-```
-
-## mode
-
-This is an identifier for the application’s current mode of operation. The mode does not affect a Leaf application’s internal functionality. Instead, the mode is only for you to optionally invoke your own code for a given mode with the `script()` application method.
-
-The application mode is declared during instantiation, either as an environment variable or as an argument to the Leaf application constructor. It cannot be changed afterward. The mode may be anything you want — “development”, “test”, and “production” are typical, but you are free to use anything you want (e.g. “foo”).
+The `write()` method is responsible for sending the logged message (not necessarily a string) to the appropriate output destination (e.g. a text file, a database, or a remote web service). The `$level` argument is one of the log levels listed above.
```php
-$app = new \Leaf\App([
- 'mode' => 'development'
-]);
-```
-
-```php
-// Only invoked if mode is "development"
-app()->script('development', function () use ($app) {
- app()->config([
- 'log.enable' => false,
- 'debug' => true
- ]);
-});
+'log.writer' => new \My\LogWriter()
```
## views.path
@@ -203,11 +116,13 @@ app()->script('development', function () use ($app) {
The relative or absolute path to the filesystem directory that contains your Leaf application’s view files.
```php
-$app = new \Leaf\App([
- 'views.path' => './views'
-]);
+'views.path' => './views'
```
## views.cachePath
-This config tells leaf where to save cached and compiled views.
+When using a view engine, this config tells Leaf where to store cached views.
+
+```php
+'views.cachePath' => './views/cache'
+```
diff --git a/src/docs/introduction/docker.md b/src/docs/introduction/docker.md
index 859a257e..5440efc2 100644
--- a/src/docs/introduction/docker.md
+++ b/src/docs/introduction/docker.md
@@ -17,28 +17,23 @@ This guide will walk you through how to set up your Leaf application using Docke
## Using the Leaf CLI
-The Leaf CLI provides a simple way to create a new Leaf application using Docker. To create a new Leaf application using the Leaf CLI, run the following command:
+The Leaf CLI provides a simple way to get started with Docker in your Leaf applications. To create a new Dockerized Leaf app using the Leaf CLI, you need to add the `--docker` option to the `leaf create` command:
```bash
-leaf create my-app --v3 --docker
+leaf create my-app --docker
```
-This will setup a new Leaf application with Docker support. You can then run the following command to start your application:
+This will setup a new Leaf application with Docker support. Although your app is dockerized, Leaf CLI still allows you to use the `serve` command to start your application. This command will automatically start your application using Docker instead of the built-in server.
```bash
leaf serve
```
-As you can see, following this process is not any different from creating a new Leaf application without Docker. The only difference is that the Leaf CLI will create a Dockerfile and docker-compose.yml file for you. You can always customize these files to suit your specific needs. Also, running the `leaf serve` command will smartly start your application using Docker instead of the built-in server.
+### Docker Files
-::: warning Known Issues
-In some cases stopping the dev server doesn't stop your Docker containers. If this happens, you can stop the containers from the Docker Desktop application.
-:::
-
-Using this method will scaffold your application with the following files:
+You will notice a bunch of docker related files in your project. These are added by the Leaf CLI since you used the `--docker` option. You can always customize these files to suit your specific needs.
```bash
-.
├── docker
│ ├── 000-default.conf
│ ├── Dockerfile
@@ -51,17 +46,9 @@ Using this method will scaffold your application with the following files:
- `php.ini` is the PHP configuration file that will be used by the Docker container.
- `docker-compose.yml` is the Docker Compose file that will be used to start the Docker container.
-Leaf CLI only scaffolds them for you. You can always customize them to suit your specific needs.
-
-## Creating your Leaf application
-
-First, create a new Leaf application using the Leaf CLI or any of the methods on the [installation](/docs/introduction/installation) page.
-
-```bash
-leaf create my-app --v3 --basic --no-tests
-```
+## Adding to existing projects
-From there, we can manually add our Docker files into the project. For this, you can choose any method that you prefer. We have provided a sample Dockerfile and docker-compose.yml file below that you can use as a starting point.
+If you already have an existing Leaf application and you want to add Docker support to it, you will need to do so manually. We have provided a sample below that you can use as a reference.
**Dockerfile:**
@@ -129,3 +116,15 @@ services:
```
+
+After adding these files, you can start your application using Docker by running the following command:
+
+```bash
+leaf serve
+```
+
+Or with the docker compose command:
+
+```bash
+docker compose up
+```
diff --git a/src/docs/introduction/first-app.md b/src/docs/introduction/first-app.md
index 708b9f6d..6c48606f 100644
--- a/src/docs/introduction/first-app.md
+++ b/src/docs/introduction/first-app.md
@@ -17,7 +17,7 @@ We recommend using the [Leaf CLI](/docs/cli/) for creating and managing your Lea
To get started, we will need to generate a leaf application. We can do this simply with Leaf CLI:
```bash
-leaf create --basic --v3 --no-tests
+leaf create --basic
```
# Introduction
+
+
Leaf is a slim and lightweight PHP framework focused on developer experience, usability, and high-performance code. It is a modern PHP framework built to be simple and elegant, yet extremely powerful.
-[→ Checkout Leaf 3's features](/docs/introduction/why)
+Here's an example:
+
+```php
+get('/', function () {
+ response()->json(['message' => 'Hello World!']);
+});
+
+app()->run();
+```
+
+## Features
+
+Leaf has a ton of features that make it a great choice for building your next project. Here are some of the features that make Leaf stand out:
+
+- Lightweight
+- Super performant
+- Easy to learn
+- Easy to use
+
+For an in-depth look at Leaf's features, check out the [features page](/docs/introduction/why.html).
## Getting Started
@@ -51,94 +75,16 @@ If you are not familiar with the concept of PHP frameworks, you can check out th
To quickly get started with Leaf, check out our [installation guide](/docs/introduction/installation.html). This gives you an in-depth explanation of how to set up leaf using various methods.
-::: tip Migrating
-Already know Leaf 2 and just want to learn about what's new in Leaf 3? Check out the [Migration Guide](/docs/migration/introduction.html)!
-:::
-
-Below is a hello world example which takes you through the core of Leaf. Other parts of the docs cover deeper examples. You can also refer to our [codelab experiments](/codelabs/) for real world examples and use-cases.
-
-## Hello world example
-
-At the core of Leaf PHP is a system that enables us to declaratively define applications using a friendly and straight-forward syntax:
-
-**index.php:**
-
-
-
-```php
-get('/', function () {
- echo 'Hello world';
-});
-
-$app->run();
-```
-
-
-
-
-
-```php
-get('/', function () {
- echo 'Hello world';
-});
-
-app()->run();
-```
+## Classes vs Functions
-
-
-We have already created our very first Leaf app! This is as simple as it gets.
-
-In addition, we can output data with Leaf response. This is a module that allows us to output data of various types without any hassle.
-
-
-
-```php
-get('/', function () use($app) {
- $app->response()->markup('Hello world');
-});
-
-$app->run();
-```
-
-Now you might be wondering why we need to go through all of this just to return some HTML when we can just use echo. The reason for this is simple. `Response` takes care of a lot of issues for us under the hood and renders exactly what we expect. Let's look at an example below.
-
-
-
-
-```php
-get('/', function () {
- response()->markup('Hello world');
-});
-
-app()->run();
-```
+Leaf supports two different ways of writing your code:
-We use `response` here instead of `echo` because it takes care of a lot of issues for us under the hood and renders exactly what we expect. Let's look at an example below.
+- Using functional mode which you saw above
+- Using class mode which is building your app using Leaf's classes
-
+### Class Mode
-
+If you are familiar with PHP frameworks, you've probably spent a lot of time writing code using classes. Leaf comes with a ton of powerful classes that you can use to build your app. Let's take a look at the code above in class mode.
```php
get('/', function () {
- // set content-type to json
- Leaf\Http\Headers::contentJSON();
-
- echo 'Hello world';
+$app->get('/', function () use ($app) {
+ $app->response()->json(['message' => 'Hello World!']);
});
$app->run();
```
-
-
-
-
-```php
-get('/', function () {
- // set content-type to json
- Leaf\Http\Headers::contentJSON();
-
- echo 'Hello world';
-});
-
-app()->run();
-```
-
-
-
-When we run this, we get "\Hello world\" instead of **Hello World**
-
-Unlike the confusion above between the content type and echo, Leaf response makes sure that whatever content we're trying to render is reflected in the content type. This is just one of the many things that response takes care of automatically.
-
-## Functional Mode
-
-We have mostly talked about general features that are the same even in Leaf 2, so let's talk about some spice in Leaf 3.
-
-::: tip
-This is just an introduction to functional mode. Read the [functional mode documentation](/docs/tooling/functions.html) for the full explanation.
-:::
-
-Basically, leaf 3 comes with global helper functions that take away the only pain anyone has ever had in using leaf, i.e., long namespaces and class initializers. Let's rewrite the first example in functional mode.
-
-```php
-get('/', function () {
- response()->markup('Hello world');
-});
-
-app()->run();
-```
-
-You'll notice that we've gotten rid of the lengthy `use Leaf\Http\Response;` and even the leaf initializer. Leaf 3 helps you focus on only what matters: your application. Everything is either done for you under the hood or made available to you in easy-to-use tools.
-
-### Handling User Input
-
-One very important part of building web apps/APIs is user input. Users may pass data into your leaf app through forms, http request bodies, URLs, ...
+### Functional Mode
-You must read this data and make sure it can't harm your system before performing any operations on it. This can be very clumsy when done raw with PHP, especially when the data comes in through multiple channels. Leaf has, however, prepared a simple handler for this: `Leaf\Http\Request`. Since we are using functional mode, we will use the `request` method instead of this lengthy class.
+Classes can become annoying and very repetitive, especially because of namespaces. You also sometimes need to worry about variable scoping and re-initializing classes.
-The user navigates to /?greeting=hello%20world
+For these and many more reasons, Leaf allows you to build your apps entirely using functions. Let's take a look at the code above in functional mode.
```php
get('/', function () {
- // we can get the GET request data from the URL like this
- $greeting = request()->get('greeting'); // hello world
-
- // output json encoded data
- response()->json([
- 'greeting' => $greeting
- ]);
+ response()->json(['message' => 'Hello World!']);
});
app()->run();
```
-The most beautiful thing about the request object is that all data passed into your app is automatically sanitized to prevent attacks like XSS. You have simple and safe code working for you.
-
-## Class mode vs Functional mode
-
-Leaf supports two different ways of writing your code:
-
-- Using functional mode which you saw above
-- Using class mode which is what has been used since Leaf v1
-
-### Class Mode
-
-This method is the default for most frameworks. Since leaf comes with classes, you can entirely build your aplication using those classes. like the `Leaf\Http\Response` class.
-
-```php
-get("/", function () {
- echo "Hello world";
-});
-
-$app->run();
-```
-
-### Functional Mode
-
-Classes become annoying to use and repeat, especially because of namespaces. You also sometimes need to put the instance of a class into a function's scope with `use`. Getting the particular instance of a class can be difficult which sometimes leads to reinitializing the class. For these reasons (and more), we created scopeless functions which allow you to quickly build your applications. These functions return instances of Leaf's classes so you don't need to use the classes yourself.
-
-```php
-get("/", function () {
- echo "Hello world";
-});
-
-app()->run();
-```
+Besides the benefits functional mode gives you on a surface level, it also does a lot of work behind the scenes to make your code more efficient and faster.
## Modes in the docs
-Just as leaf allows you to write your code in 2 ways, with functional mode or class mode, our docs come with examples prepared for both.
-
-You can click on this switch in the sidebar to toggle the mode of the examples on our documentation.
+The docs are written in both functional and class mode. You can switch between the two modes using the switcher at the top of the page.
![Switcher](https://user-images.githubusercontent.com/26604242/178108346-c9c22a19-6a82-4786-ac3e-00cbfe69cba8.png)
-## Installing modules
-
-Modules are pieces of functionality that have been packaged and shipped separately from the Leaf core. Modules are used to extend Leaf's reach by performing operations not available on the core. Modules were introduced with Leaf 3, but some of them can be used with earlier versions of Leaf. Modules can also be used in external libraries and frameworks as well. To install a module, simply run its install script with composer or use the leaf CLI.
-
-To demonstrate this, we will expand the app above to output a template instead of the JSON data from earlier. For this, we will need a template module. Leaf has 3 template modules
+## Leaf modules
-- BareUI: Super lightweight, blazing fast templating engine with zero compilation
-- Blade: A port of the laravel blade templating engine
-- Leaf Veins: Lightweight but powerful templating
-
-For this demo, we will use BareUI. We can install BareUI with leaf CLI.
-
-```bash
-leaf install bareui
-```
-
-Or with composer:
-
-```bash
-composer require leafs/bareui
-```
-
-After this, Leaf **automatically** links the BareUI class for you and makes it available on the leaf object as `template`. So from there, we can create our template. I'll name this `index.view.php` (BareUI templates end in `.view.php`)
-
-```php
-
-
-
-
-
-
- Document
-
-
-
-
-
-```
-
-The next thing to do is to tell BareUI where to look for templates and finally render `index.view.php`.
-
-
-
-```php
-template->config("path", "./");
-
-$app->get("/", function () use($app) {
- // we can get the GET request data from the URL like this
- $greeting = $app->request()->get("greeting"); // hello world
-
- // render our template
- echo $app->template->render("index", [
- "greeting" => $greeting,
- ]);
-});
-
-$app->run();
-```
-
-
-
-
-```php
-template->config("path", "./");
-
-app()->get("/", function () {
- // we can get the GET request data from the URL like this
- $greeting = request()->get("greeting"); // hello world
-
- // render our template
- echo app()->template->render("index", [
- "greeting" => $greeting,
- ]);
-});
-
-app()->run();
-```
-
-
+Modules are pieces of Leaf's functionality that are available as separate packages. These packages can be installed and used with Leaf to extend its functionality. Most modules are framework agnostic and can be used with other frameworks and libraries, but they are built to work best with Leaf.
-Just as you saw above, most Leaf modules require absolutely no configuration in order to work with the Leaf core. They just fit right in.
+You can check out the [modules page](/modules/) to see a list of all the modules available for Leaf.
## Ready for More?
@@ -383,7 +138,7 @@ We've briefly introduced the most basic features of Leaf 3 - the rest of this gu
## Next Steps
-If you skipped the [Introduction](/docs/introduction/), we strongly recommend reading it before moving on to the rest of the documentation.
+If you are new to Leaf, we strongly recommend reading this page before moving on to the rest of the documentation. It will provide you with a solid foundation on which to build your Leaf knowledge. If you are already familiar with Leaf, feel free to check out the rest of the documentation.
diff --git a/src/docs/introduction/installation.md b/src/docs/introduction/installation.md
index e01c802e..efb95098 100644
--- a/src/docs/introduction/installation.md
+++ b/src/docs/introduction/installation.md
@@ -1,7 +1,7 @@
-
-
# Installation
+
+
@@ -10,29 +10,26 @@ Leaf 3 is built by design to be incrementally adoptable. This means that it can
There are four primary ways of adding Leaf PHP to a project:
-1. Use the [Leaf CLI](/docs/cli/) to scaffold a project [RECOMMENDED].
-2. Download leaf through composer
-3. Use [Leaf skeleton](https://leafphp.netlify.app/#/skeleton/v/2.0/) to quickstart your project
-4. Download the leaf repo
-
-::: tip Migrating
-If you want to migrate an existing Leaf 2 project, skip this and follow the [Migration Guide](/docs/migration/introduction.html)
-:::
+1. [Use the Leaf CLI to scaffold a project [RECOMMENDED]](#leaf-cli).
+2. [Download leaf through composer](#composer)
+3. [Scaffold a Leaf MVC or Leaf API project](#mvc-setup)
## Technical Requirements
Before creating your first Leaf application you must:
-- Install PHP 7.2 or higher and these PHP extensions (which are installed and enabled by default in most PHP installations): json, zip;
- ::: warning Note that
- Note that some specific modules require PHP 7.4, so to be safe, we recommend PHP 7.4 as your minimum PHP version.
- :::
+- Install PHP 7.4 or higher and these PHP extensions (which are installed and enabled by default in most PHP installations): json, zip;
- [Install Composer](https://getcomposer.org/download/), which is used to install PHP packages.
-- Optionally, you can also install [Leaf CLI](/docs/cli/). This provides all the tools you need to create and manage your Leaf application locally.
+- Optionally, you can also install [Leaf CLI](/docs/cli/). This provides all the tools you need to create and manage your Leaf application locally. This is optional but highly recommended.
+
+
+Not sure where to start?
+
+- Laravel released an amazing tool called [Laravel Herd](https://herd.laravel.com/) that provides a quick and easy way to set up a local PHP development environment for Mac. It's a great way to get started with PHP and Leaf.
-Leaf 3 works as far back as PHP 7.2, however, some modules require PHP 7.4, so we advice using a minimum of PHP 7.4. There's also full support for PHP 8.
+- On Windows and Mac, you can use [Xampp](https://www.apachefriends.org/), which is a free and open-source cross-platform web server solution stack package developed by Apache Friends, consisting mainly of the Apache HTTP Server, MariaDB database, and interpreters for scripts written in the PHP and Perl programming languages.
-You'll also need some PHP extensions like json extension and the zip extension
+
## Leaf CLI
@@ -44,17 +41,25 @@ You'll also need some PHP extensions like json extension and the zip extension
Leaf provides an [official CLI](https://github.com/leafsphp/cli) for quickly creating and managing your Leaf applications. It takes just a few seconds to get up and running with your leaf app. See [the Leaf CLI docs](/docs/cli/) for more details.
+Using the CLI, you can quickly scaffold a new Leaf 3 project with:
+
```bash
-leaf create --v3
+leaf create
```
-You can also install modules using the following syntax:
+Besides the core of the framework, Leaf also ships with a ton of installable functionality. We call these independent libraries modules. You can install modules using the `install` command:
```bash
-leaf install cors
+leaf install
```
-You can then run your app using:
+The CLI also allows you to completely customize the installation you wish to create. You can choose different features like database, authentication, etc. This is done using the `--custom` flag:
+
+```bash
+leaf create --custom
+```
+
+You can then run your app using the `serve` command:
```bash
leaf serve
@@ -68,14 +73,10 @@ leaf serve
link="https://www.youtube.com/watch?v=t-pNURSTOKw"
/> -->
-You can also set up a new leaf 3 project from scratch using composer:
+Leaf also allows a more traditional approach to installation. You can install leaf through composer. You can use this method if you don't want to use the leaf cli or if you want to use leaf as a dependency in your project. The disadvantage of this method is that you don't get a quick-start setup like you do with the leaf cli.
```bash
-# latest stable (v3)
-$ composer require leafs/leaf
-
-# version 3 dev
-$ composer require leafs/leaf v3.x-dev
+composer require leafs/leaf
```
After insalling Leaf, you need to create your index.php file which will be the entry point to your application.
@@ -85,12 +86,12 @@ After insalling Leaf, you need to create your index.php file which will be the e
```php
get("/", function () use($app) {
- $app->response()->json(["message" => "Hello World!"]);
+$app->get('/', function () use($app) {
+ $app->response()->json(['message' => 'Hello World!']);
});
$app->run();
@@ -103,10 +104,10 @@ $app->run();
```php
get("/", function () {
- response()->json(["message" => "Hello World!"]);
+app()->get('/', function () {
+ response()->json(['message' => 'Hello World!']);
});
app()->run();
@@ -114,84 +115,85 @@ app()->run();
-You might want to check out [URL rewriting](/docs/introduction/url-rewriting.html).
+When hosting your application on a webserver, all requests coming into your app must be routed through Leaf. It is really simple to do, and all needed instructions can be found @ [URL rewriting](/docs/introduction/url-rewriting.html).
-## GitHub
+## MVC Setup
-
+Although Leaf allows you to select exactly what you want to install, some applications go beyond the basic setup. Leaf MVC is a full but ridiculously light-weight MVC framework that allows you to build complex applications with Leaf. It comes with a lot of features like authentication, database, http related functionality and a powerful CLI. To get started with Leaf's MVC setup, you can check out the [MVC docs](/docs/mvc/).
-You can also clone the leaf 3 branch.
+## Hello world example
-::: tip Setup
-You can directly download v3.x-dev here.
-
-
-:::
+Below is a "hello world" example which takes you through the core of Leaf. Other parts of the docs cover deeper examples. You can also refer to our [codelab experiments](/codelabs/) for real world examples and use-cases.
-After downloading repo, you need to create an autoloader.
+A base Leaf app that outputs hello world in your browser looks like this:
-**Example autoloader: `autoloader.php`**
+
```php
get('/', function () {
+ echo 'Hello world';
});
-```
-The autoloader will allow you use leaf files without having to `require` or `include` them first. So straight up using `Leaf\App` will load `leaf\src\App.php`.
+$app->run();
+```
-**This is only required if you downloaded the repo.**
+
-Now, all you have to do is create your index.php file, install leaf's dependencies (core modules), and include your autoloader like this:
+
```php
get('/', function () {
+ echo 'Hello world';
+});
+
+app()->run();
```
-::: warning NOTE THAT
-functional mode is not automatically available if you go down this route, you will have to manually add the leaf functions file in your app or in the autoloader.
-:::
+
-```php{5}
-
-## Leaf skeleton
+```php
+ --skeleton --v3
+$app->get('/', function () use($app) {
+ $app->response()->markup('Hello world');
+});
+
+$app->run();
```
-:::
+
+
-The main installtion for skeleton is through composer.
+```php
+
+require __DIR__ . '/vendor/autoload.php';
+
+app()->get('/', function () {
+ response()->markup('Hello world');
+});
+
+app()->run();
```
+
+
diff --git a/src/docs/leafapi/index.md b/src/docs/leafapi/index.md
index 9801e456..28158c87 100644
--- a/src/docs/leafapi/index.md
+++ b/src/docs/leafapi/index.md
@@ -6,16 +6,12 @@ Leaf API is a minimal but powerful PHP MVC framework. It's designed to be simple
Leaf API is a setup that gives you a good starting point for building APIs using the MVC pattern. It's built on top of Leaf, and comes with additional tooling that make building with Leaf even faster.
-::: tip Leaf MVC vs Leaf API vs Skeleton
-Leaf offers three setups for you to choose from. You can find more information about these setups in the [MVC](/docs/mvc/#mvc-in-leaf) section.
-:::
-
## Installation
The easiest way to setup Leaf MVC is to use the [Leaf CLI](/docs/cli/):
```bash
-leaf create --api --v3
+leaf create --api
```
You can also setup a Leaf API app by using [Composer](https://getcomposer.org/):
@@ -114,7 +110,7 @@ Follow along with the next steps to learn more about Leaf API.
Leaf API Configuration
Learn how to configure Leaf and your app to work in different ways.
-
+
Routing
Learn how routing works in your Leaf applications.
diff --git a/src/docs/leafmvc/index.md b/src/docs/leafmvc/index.md
index d1a3cd47..4cbaf7cd 100644
--- a/src/docs/leafmvc/index.md
+++ b/src/docs/leafmvc/index.md
@@ -6,18 +6,12 @@ Leaf MVC is a minimal but powerful PHP MVC framework. It's designed to be simple
Leaf MVC is a setup that gives you a good starting point for building applications using the MVC pattern. It's built on top of Leaf, and comes with additional tooling that make building with Leaf even faster.
-::: tip Leaf MVC vs Leaf API vs Skeleton
-
-Leaf offers three setups for you to choose from. You can find more information about these setups in the [MVC](/docs/mvc/#mvc-in-leaf) section.
-
-:::
-
## Installation
The easiest way to setup Leaf MVC is to use the [Leaf CLI](/docs/cli/):
```bash
-leaf create --mvc --v3
+leaf create --mvc
```
You can also setup a Leaf MVC app by using [Composer](https://getcomposer.org/):
@@ -122,7 +116,7 @@ Follow along with the next steps to learn more about Leaf MVC.
Leaf MVC Configuration
Learn how to configure Leaf and your app to work in different ways.
-
+
Routing
Learn how routing works in your Leaf applications.
diff --git a/src/docs/migration/introduction.md b/src/docs/migration/introduction.md
index 004b7acb..86fa8a26 100644
--- a/src/docs/migration/introduction.md
+++ b/src/docs/migration/introduction.md
@@ -84,7 +84,7 @@ php -S localhost:5500
Alternatively, you can use the Leaf CLI:
```bash
-leaf create --v3
+leaf create
```
And run the sample app with:
diff --git a/src/docs/migration/other.md b/src/docs/migration/other.md
index cc8ab54b..8fed725f 100644
--- a/src/docs/migration/other.md
+++ b/src/docs/migration/other.md
@@ -8,10 +8,6 @@ aside: none
import VideoDocs from '/@theme/components/VideoDocs.vue'
-::: tip
-New to Leaf PHP? Check out our [Essentials Guide](/docs/introduction/) to get started.
-:::
-.
This page is for developers who have a working application in another framework and want to port over to Leaf. As far-fetched as this sounds, Leaf 3 makes it super easy to sprinkle pieces of Leaf into any existing application, gradually rewriting it without breaking any code. Leaf has always allowed users to integrate other libraries seamlessly into their leaf apps with no conflicts or complexities, now Leaf 3 allows you to go the other way: **integrating Leaf seamlessly into any application no matter which libraries or frameworks it was built with.**
-Leaf MVC, Leaf API and Skeleton all try to maintain a working out-of-the-box configuration as much as possible, so, for the most part, you don't have to configure anything. However, there are some things you may want to configure, and this page will show you how.
+Both Leaf MVC and Leaf API try to maintain a working out-of-the-box configuration as much as possible, so, for the most part, you don't have to configure anything. However, there are some things you may want to customize to match your application's style, and this page will show you how.
## Overview
-You can find your application in the `config` directory. This directory contains the configuration files for Leaf MVC, Leaf API and Skeleton. You only need to configure the files that you need to configure. If you don't need to configure a file, you can just leave it as is. Each option is documented, so feel free to look through the files and get familiar with the options available to you.
+You can find your application in the `config` directory. This directory contains all the configuration files for you need for different features. You only need to configure the files that you need to configure. If you don't need to configure a file, you can just leave it as is. Each option is documented, so feel free to look through the files and get familiar with the options available to you.
These configuration files allow you to configure things like your database connection information, your mail server information, as well as various other core configuration values such as your application timezone and encryption key.
@@ -26,11 +26,15 @@ If you add new environment variables to a team project, be sure to add the keys
:::
+*If you want more info on how Leaf handles your application's environment, you can check out the [environment docs](/docs/config/nsm).*
+
## Application Config
This configuration basically controls how Leaf works with your application. This file contains the following options by default:
```php
+ _env('APP_DOWN', false),
-
- /*
- |--------------------------------------------------------------------------
- | App debugging
- |--------------------------------------------------------------------------
- |
- | If debugging is enabled, Leaf will use its built-in error handler to
- | display diagnostic information for uncaught Exceptions, else it will
- | display a bare error page usable in production. You can set a
- | custom error page to display using `$app->setError`.
- |
- | You might want to turn this off in production.
- |
- */
- 'debug' => _env('APP_DEBUG', true),
-
- /*
- |--------------------------------------------------------------------------
- | HTTP Version
- |--------------------------------------------------------------------------
- |
- | By default, Leaf returns an HTTP/1.1 response to the client.
- | Use this setting if you need to return an HTTP/1.0 response.
- |
- */
- 'http.version' => '1.1',
-
- /*
- |--------------------------------------------------------------------------
- | Log directory
- |--------------------------------------------------------------------------
- |
- | This tells leaf which directory to save and look for logs.
- |
- */
- 'log.dir' => 'storage/logs/',
-
- /*
- |--------------------------------------------------------------------------
- | Log Enabled
- |--------------------------------------------------------------------------
- |
- | This enables or disables Leaf’s logger. Note that if log.enabled is
- | set to false. Leaf will skip initializing anything related to logs,
- | as such, you won't have access to $app->logger(),
- | $app->log or $app->logWriter.
- |
- */
- 'log.enabled' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Log file
- |--------------------------------------------------------------------------
- |
- | This setting tells leaf which file to write logs to.
- |
- */
- 'log.file' => 'app.log',
-
- /*
- |--------------------------------------------------------------------------
- | Log level
- |--------------------------------------------------------------------------
- |
- | Leaf has these log levels:
- |
- | - \Leaf\Log::EMERGENCY
- | - \Leaf\Log::ALERT
- | - \Leaf\Log::CRITICAL
- | - \Leaf\Log::ERROR
- | - \Leaf\Log::WARN
- | - \Leaf\Log::NOTICE
- | - \Leaf\Log::INFO
- | - \Leaf\Log::DEBUG
- |
- */
- 'log.level' => \Leaf\Log::DEBUG,
-
- /*
- |--------------------------------------------------------------------------
- | Log open
- |--------------------------------------------------------------------------
- |
- | Takes in a boolean and determines whether Leaf should create
- | the specified log file if it doesn't exist.
- |
- */
- 'log.open' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Log writer
- |--------------------------------------------------------------------------
- |
- | Use a custom log writer to direct logged messages
- | to the appropriate output destination.
- |
- */
- 'log.writer' => null,
-
- /*
- |--------------------------------------------------------------------------
- | Mode
- |--------------------------------------------------------------------------
- |
- | This is an identifier for the application’s current mode of operation.
- | The mode does not affect a Leaf application’s internal functionality.
- |
- */
- 'mode' => 'development',
-
- /*
- |--------------------------------------------------------------------------
- | Views path
- |--------------------------------------------------------------------------
- |
- | The relative or absolute path to the filesystem directory that
- | contains your Leaf application’s view files.
- |
- */
- 'views.path' => ViewsPath(null, false),
-
- /*
- |--------------------------------------------------------------------------
- | views cache path
- |--------------------------------------------------------------------------
- |
- | This config tells leaf where to save cached and compiled views.
- |
- */
- 'views.cachePath' => StoragePath('framework/views')
+ /*
+ |--------------------------------------------------------------------------
+ | Place app in maintenance mode
+ |--------------------------------------------------------------------------
+ |
+ | Replacement for earlier mode=down. You can set this to true to place
+ | your app in a maintenance like state. It will display Leaf's default
+ | app down page if a custom handler is not set.
+ |
+ | See: https://leafphp.dev/docs/config/settings.html#app-down
+ |
+ */
+ 'app.down' => _env('APP_DOWN', false),
+
+ /*
+ |--------------------------------------------------------------------------
+ | App debugging
+ |--------------------------------------------------------------------------
+ |
+ | If debugging is enabled, Leaf will use its built-in error handler to
+ | display diagnostic information for uncaught Exceptions, else it will
+ | display a bare error page usable in production. You can set a
+ | custom error page to display using `$app->setError`.
+ |
+ | You might want to turn this off in production.
+ |
+ */
+ 'debug' => _env('APP_DEBUG', true),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Log directory
+ |--------------------------------------------------------------------------
+ |
+ | This tells leaf which directory to save and look for logs.
+ |
+ */
+ 'log.dir' => 'storage/logs/',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Log Enabled
+ |--------------------------------------------------------------------------
+ |
+ | This enables or disables Leaf’s logger. Note that if log.enabled is
+ | set to false. Leaf will skip initializing anything related to logs,
+ | as such, you won't have access to $app->logger(),
+ | $app->log or $app->logWriter.
+ |
+ */
+ 'log.enabled' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Log file
+ |--------------------------------------------------------------------------
+ |
+ | This setting tells leaf which file to write logs to.
+ |
+ */
+ 'log.file' => 'app.log',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Log level
+ |--------------------------------------------------------------------------
+ |
+ | Leaf has these log levels:
+ |
+ | - \Leaf\Log::EMERGENCY
+ | - \Leaf\Log::ALERT
+ | - \Leaf\Log::CRITICAL
+ | - \Leaf\Log::ERROR
+ | - \Leaf\Log::WARN
+ | - \Leaf\Log::NOTICE
+ | - \Leaf\Log::INFO
+ | - \Leaf\Log::DEBUG
+ |
+ */
+ 'log.level' => \Leaf\Log::DEBUG,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Log open
+ |--------------------------------------------------------------------------
+ |
+ | Takes in a boolean and determines whether Leaf should create
+ | the specified log file if it doesn't exist.
+ |
+ */
+ 'log.open' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Log writer
+ |--------------------------------------------------------------------------
+ |
+ | Use a custom log writer to direct logged messages
+ | to the appropriate output destination.
+ |
+ */
+ 'log.writer' => null,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Mode
+ |--------------------------------------------------------------------------
+ |
+ | This is an identifier for the application’s current mode of operation.
+ | The mode does not affect a Leaf application’s internal functionality.
+ |
+ */
+ 'mode' => 'development',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Views path
+ |--------------------------------------------------------------------------
+ |
+ | The relative or absolute path to the filesystem directory that
+ | contains your Leaf application’s view files.
+ |
+ */
+ 'views.path' => ViewsPath(null, false),
+
+ /*
+ |--------------------------------------------------------------------------
+ | views cache path
+ |--------------------------------------------------------------------------
+ |
+ | This config tells leaf where to save cached and compiled views.
+ |
+ */
+ 'views.cachePath' => StoragePath('framework/views')
];
```
@@ -726,7 +719,7 @@ return [
Follow along with the next steps to learn more about Leaf MVC.
-
+
Routing
Learn how routing works in your Leaf applications.
diff --git a/src/docs/mvc/console.md b/src/docs/mvc/console.md
index a073d579..f4e4a821 100644
--- a/src/docs/mvc/console.md
+++ b/src/docs/mvc/console.md
@@ -2,3 +2,459 @@
+Leaf MVC and Leaf API come with a robust console tool to help you manage your app from the command line. We call this tool Aloe.
+
+Aloe comes with a predefined set of commands which provide project scaffolding, database and app management right from your terminal. To view all available commands, run `php leaf list` from your terminal.
+
+## Aloe CLI vs Leaf CLI
+
+Before we go any further, it's important to note that Aloe is not the same as Leaf CLI.
+
+Leaf CLI is a tool for creating and managing your Leaf applications, it is installed globally and can be used in Leaf and Leaf MVC/Leaf API applications. The Leaf CLI has a more generalized set of commands which can be used in any Leaf application.
+
+Aloe on the other hand is a tool for managing Leaf MVC and Leaf API applications. It is limited to the root directory of your Leaf MVC/Leaf API application and has a more specific set of commands which are only available in Leaf MVC/Leaf API applications.
+
+## Aloe Commands
+
+Aloe provides a large set of commands to ease your development process. Although they may look like a lot, we can group them into 6 categories:
+
+- App commands
+- Scaffold commands
+- Generate commands
+- Delete commands
+- Database commands
+- View commands
+
+## App Commands
+
+App commands are commands which help you manage your Leaf MVC/Leaf API application. These commands are used to manage your app's state, interact with your app and it's dependencies and more.
+
+### Serve
+
+The `serve` command is used to start the Leaf development server. It is the same as running `php -S localhost:[PORT]` from your terminal, but it also runs your app's bootstrapping process.
+
+To start the Leaf development server, run `php leaf serve` from your terminal. You can also specify a port to run the server on by running `php leaf serve --port=[PORT]`.
+
+```bash
+php leaf serve
+```
+
+### Interact
+
+The `interact` command is used to start the Leaf interactive shell. The interactive shell is a REPL (Read-Eval-Print-Loop) which allows you to interact with your app from the command line. It is powered by [PsySH](https://psysh.org/).
+
+```bash
+php leaf interact
+```
+
+### Up and Down
+
+The `app:up` and `app:down` commands are used to put your app in maintenance mode. When your app is in maintenance mode, all requests to your app will return a 503 response. This is useful when you want to take your app down for maintenance.
+
+To put your app in maintenance mode, run `php leaf app:down`. To take your app out of maintenance mode, run `php leaf app:up`.
+
+```bash
+php leaf app:down
+php leaf app:up
+```
+
+## Scaffold Commands
+
+Scaffold commands are commands which help you scaffold your Leaf MVC/Leaf API application. These commands are used to create new files and folders in your app. Some of these commands even scaffold entire flows for you.
+
+### Auth Scaffold
+
+The `auth:scaffold` command is used to scaffold basic authentication for your Leaf MVC/Leaf API application. It creates required models, controllers, views and routes, migrations and everything you need to get started with authentication. Depending on your flow, you may need to make some changes to the files generated by this command.
+
+Note that this command will generate different files depending on whether you're using Leaf MVC or Leaf API.
+
+If you're building a Leaf MVC app, this command will automatically scaffold a login and registration flow for you with views and controllers, however, since Leaf API comes with the View layer disabled, this command will only scaffold the required models, controllers, routes and migrations for you. All controllers in Leaf API will return JSON responses.
+
+You can force the command to generate files for Leaf MVC or Leaf API by passing the `--mvc` or `--api` flag respectively.
+
+```bash
+php leaf auth:scaffold
+php leaf auth:scaffold --mvc # force Leaf MVC
+php leaf auth:scaffold --api # force Leaf API
+```
+
+You can find the Leaf MVC authentication documentation [here](/modules/auth/mvc).
+
+### Mail Setup
+
+The `mail:setup` command is used to setup mailing in your Leaf MVC/Leaf API application. It installs the Leaf Mail package and creates a `mail.php` config file in your `config` folder as well as a demo mailer in your `app/mailers` folder.
+
+```bash
+php leaf mail:setup
+```
+
+Find the MVC Mail documentation [here](/docs/mvc/mail).
+
+### Env Generate
+
+The `env:generate` command is used to generate a `.env` file in your Leaf MVC/Leaf API application. It generates a `.env` file from your `.env.example` file and fills it with the values in your `.env.example` file.
+
+If there is no `.env.example` file in your app, this command will generate a `.env` file from scratch.
+
+```bash
+php leaf env:generate
+```
+
+### Devtools Install
+
+The `devtools:install` command is used to install and setup the Leaf PHP devtools in your Leaf MVC/Leaf API application.
+
+```bash
+php leaf devtools:install
+```
+
+You can find the Leaf PHP devtools documentation [here](/modules/devtools/).
+
+### View Install
+
+The `view:install` command is used to install and setup the frontend of your Leaf MVC/Leaf API application. It can be used to install any frontend framework of your choice, vite, tailwind or a template engine like bare ui. You can use the `--react`, `--vue`, `--blade`, and `--bareui` options to scaffold your frontend setup.
+
+```bash
+leaf view:install --react
+```
+
+You can also use the `--vite` and `--tailwind` options to scaffold Vite and Tailwind respectively.
+
+```bash
+php leaf view:install --vite
+php leaf view:install --tailwind
+```
+
+You can check the [frontend documentation](/modules/views/) for more information.
+
+## Generate Commands
+
+These commands are used to generate files like controllers, models, migrations, views and more directly into your app.
+
+### Generate Command
+
+The `g:command` command is used to generate a new console command in your Leaf MVC/Leaf API application. It creates a new command class in your `app/commands` folder.
+
+```bash
+php leaf g:command [name]
+```
+
+### Generate Controller
+
+The `g:controller` command is used to generate a new controller in your Leaf MVC/Leaf API application. It creates a new controller class in your `app/controllers` folder.
+
+```bash
+php leaf g:controller [name]
+```
+
+This command can also be used to generate a controller with a resource route. To generate a controller with a resource route, pass the `--resource` flag.
+
+```bash
+php leaf g:controller [name] --resource
+```
+
+Resource controllers are controllers which have a route for every CRUD operation. You can find more information about resource controllers [here](/docs/mvc/controllers).
+
+You can also generate a controller and a model at the same time by passing the `--model` flag.
+
+```bash
+php leaf g:controller [name] --model
+```
+
+You can also generate a migration and model at the same time by passing the `--all` flag, or just `-a` for short.
+
+```bash
+php leaf g:controller [name] --all
+php leaf g:controller [name] -a
+```
+
+### Generate Factory
+
+The `g:factory` command is used to generate a new model factory in your Leaf MVC/Leaf API application. It creates a new factory class in your `app/database/factories` folder.
+
+```bash
+php leaf g:factory [name]
+```
+
+### Generate Helper
+
+The `g:helper` command is used to generate a new helper class in your Leaf MVC/Leaf API application. It creates a new helper class in your `app/helpers` folder.
+
+```bash
+php leaf g:helper [name]
+```
+
+### Generate Mailer
+
+The `g:mailer` command is used to generate a new mailer in your Leaf MVC/Leaf API application. It creates a new mailer class in your `app/mailers` folder.
+
+```bash
+php leaf g:mailer [name]
+```
+
+### Generate Migration
+
+The `g:migration` command is used to generate a new migration in your Leaf MVC/Leaf API application. It creates a new migration file in your `app/database/migrations` folder.
+
+```bash
+php leaf g:migration [name]
+```
+
+By default, this command assumes your table name from the migration name. For example, if you run `php leaf g:migration users`, the command will assume your table name is `users`. You can override this by passing the `--table` flag.
+
+```bash
+php leaf g:migration [name] --table=[table_name]
+```
+
+### Generate Model
+
+The `g:model` command is used to generate a new model in your Leaf MVC/Leaf API application. It creates a new model class in your `app/models` folder.
+
+```bash
+php leaf g:model [name]
+```
+
+If you want to generate a model with a migration, you can pass the `--migration` flag.
+
+```bash
+php leaf g:model [name] --migration
+```
+
+### Generate Seed
+
+The `g:seed` command is used to generate a new seed file in your Leaf MVC/Leaf API application. It creates a new seed file in your `app/database/seeds` folder.
+
+```bash
+php leaf g:seed [name]
+```
+
+### Generate Template
+
+The `g:template` command is used to generate a new view file in your Leaf MVC/Leaf API application. It creates a new view file in your `resources/views` folder.
+
+```bash
+php leaf g:template [name]
+```
+
+You can tell this command what kind of view file you want to create using the `--type` flag. The available types are `blade`, `jsx`, `vue` and `html`.
+
+```bash
+php leaf g:template [name] --type=blade
+php leaf g:template [name] --type=jsx
+php leaf g:template [name] --type=vue
+php leaf g:template [name] --type=html
+```
+
+## Delete Commands
+
+These commands are used to delete files like controllers, models, migrations, views and more directly from your app.
+
+### Delete Command
+
+The `d:command` command is used to delete a console command from your Leaf MVC/Leaf API application. It deletes a command class from your `app/commands` folder and automatically unregisters it from Aloe.
+
+```bash
+php leaf d:command [name]
+```
+
+### Delete Controller
+
+The `d:controller` command is used to delete a controller from your Leaf MVC/Leaf API application. It deletes a controller class from your `app/controllers` folder.
+
+```bash
+php leaf d:controller [name]
+```
+
+### Delete Factory
+
+The `d:factory` command is used to delete a model factory from your Leaf MVC/Leaf API application. It deletes a factory class from your `app/database/factories` folder.
+
+```bash
+php leaf d:factory [name]
+```
+
+### Delete Migration
+
+The `d:migration` command is used to delete a migration from your Leaf MVC/Leaf API application. It deletes a migration file from your `app/database/migrations` folder.
+
+```bash
+php leaf d:migration [name]
+```
+
+### Delete Model
+
+The `d:model` command is used to delete a model from your Leaf MVC/Leaf API application. It deletes a model class from your `app/models` folder.
+
+```bash
+php leaf d:model [name]
+```
+
+### Delete Seed
+
+The `d:seed` command is used to delete a seed file from your Leaf MVC/Leaf API application. It deletes a seed file from your `app/database/seeds` folder.
+
+```bash
+php leaf d:seed [name]
+```
+
+## Database Commands
+
+These commands are used to manage your database. They are used to create, migrate, seed and rollback your database.
+
+### Install Database
+
+The `db:install` command is used to create a new database from your `.env` file. It creates a new database using the credentials in your `.env` file.
+
+```bash
+php leaf db:install
+```
+
+### Migrate Database
+
+The `db:migrate` command is used to run your database migrations. It runs all migrations in your `app/database/migrations` folder.
+
+```bash
+php leaf db:migrate
+```
+
+You can also run a specific migration by passing the migration name to the `--file` flag.
+
+```bash
+php leaf db:migrate --file=[migration_name]
+php leaf db:migrate --file=users # runs the ..._create_users_table migration
+```
+
+You can also seed your database after running your migrations by passing the `--seed` flag.
+
+```bash
+php leaf db:migrate --seed
+```
+
+### Reset Database
+
+The `db:reset` command is used to rollback, migrate and seed your database. It runs the `db:rollback`, `db:migrate` and `db:seed` commands in that order.
+
+```bash
+php leaf db:reset
+```
+
+If you want to prevent seeding your database, you can pass the `--noSeed` flag.
+
+```bash
+php leaf db:reset --noSeed
+```
+
+### Rollback Database
+
+The `db:rollback` command is used to rollback your database migrations. It rolls back all migrations in your `app/database/migrations` folder.
+
+```bash
+php leaf db:rollback
+```
+
+You can also rollback a specific migration by passing the migration name to the `--file` flag.
+
+```bash
+php leaf db:rollback --file=[migration_name]
+php leaf db:rollback --file=users # rolls back the ..._create_users_table migration
+```
+
+You may also rollback a specific number of migrations by passing the number to the `--step` flag.
+
+```bash
+php leaf db:rollback --step=[number]
+php leaf db:rollback --step=2 # rolls back the last 2 migrations
+```
+
+### Seed Database
+
+The `db:seed` command is used to seed your database. It runs all seed files loading in the `app/database/seeds/DatabaseSeeder.php` file. In this file, you can specify which seed files to run.
+
+```bash
+php leaf db:seed
+```
+
+## View Commands
+
+These commands are used to manage your frontend. They are used to build, serve and install your frontend. We already covered the `view:install` command in the Scaffold Commands section above.
+
+### Build Frontend
+
+The `view:build` command is used to build your frontend. It builds your frontend using the build command specified in your `package.json` file.
+
+```bash
+php leaf view:build
+```
+
+### Serve Frontend
+
+The `view:serve` command is used to serve your frontend. It serves your frontend using the `dev` command specified in your `package.json` file.
+
+```bash
+php leaf view:serve
+```
+
+## Command List
+
+This is a list of every command available in Aloe. To view this list from your terminal, run `php leaf list`.
+
+```bash
+Leaf MVC v3.5.0
+
+Usage:
+ command [options] [arguments]
+
+Options:
+ -h, --help Display help for the given command. When no command is given display help for the list command
+ -q, --quiet Do not output any message
+ -V, --version Display this application version
+ --ansi|--no-ansi Force (or disable --no-ansi) ANSI output
+ -n, --no-interaction Do not ask any interactive question
+ -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+
+Available commands:
+ completion Dump the shell completion script
+ example example command's description
+ help Display help for a command
+ interact Interact with your application
+ list List commands
+ serve Start the leaf development server
+ app
+ app:down Place app in maintainance mode
+ app:up Remove app from maintainance mode
+ auth
+ auth:scaffold Scaffold basic app authentication
+ d
+ d:command Delete a console command
+ d:controller Delete a controller
+ d:factory Delete a model factory
+ d:migration Delete a migration
+ d:model Delete a model
+ d:seed Delete a model seeder
+ db
+ db:install Create new database from .env variables
+ db:migrate Run the database migrations
+ db:reset Rollback, migrate and seed database
+ db:rollback Rollback all database migrations
+ db:seed Seed the database with records
+ devtools
+ devtools:install Install the Leaf PHP devtools
+ env
+ env:generate Generate .env file
+ g
+ g:command Create a new console command
+ g:controller Create a new controller class
+ g:factory Create a new model factory
+ g:helper Create a new helper class
+ g:mailer Create a new mailer
+ g:migration Create a new migration file
+ g:model Create a new model class
+ g:seed Create a new seed file
+ g:template Create a new view file
+ mail
+ mail:setup Install leaf mail and setup mail config
+ view
+ view:build Run your frontend dev server
+ view:dev [view:serve] Run your frontend dev server
+ view:install Run a script in your composer.json
+```
diff --git a/src/docs/mvc/controllers.md b/src/docs/mvc/controllers.md
index 4945674c..557fbbc8 100644
--- a/src/docs/mvc/controllers.md
+++ b/src/docs/mvc/controllers.md
@@ -2,17 +2,12 @@
-Instead of using Closures in route files to define all your request handling logic, you can use controllers to organize this behavior. Controllers can group related request handling logic into a single class. For instance,
-you may want to group all logic that handles user account details into an `AccountsController` class: actions such as displaying, creating, updating, and deleting users.
+Instead of using Closures in route files to define all your request handling logic, you can use controllers to organize this behavior. Controllers can group related request handling logic into a single class. For instance, you may want to group all logic that handles user account details into an `AccountsController` class: actions such as displaying, creating, updating, and deleting users.
-Controllers can also be shared among different route files, giving you a single location to define a controller that can be used in different contexts throughout your application. Leaf MVC and Leaf API controllers are stored in the `app/controllers` directory while Skeleton controllers are stored in the `controllers` directory.
+Controllers can also be shared among different route files, giving you a single location to define a controller that can be used in different contexts throughout your application. Leaf MVC and Leaf API controllers are stored in the `app/controllers`. Any new controller you create will be saved in this location.
## Generating Controllers
-::: warning Leaf Console
-This section only applies to Leaf MVC and Leaf API. If you're using Skeleton, you can skip this section.
-:::
-
Leaf MVC and Leaf API come with a console helper that can generate a new controller for you. To create a new controller, use the `g:controller` command:
```bash
@@ -37,11 +32,11 @@ class UsersController extends Controller
}
```
-You can see that the controller extends the `App\Controllers\Controller` class. This is the base controller class provided by Leaf MVC, Leaf API or Skeleton. It contains serves as the parent class for all your application's controllers.
+You can see that the controller extends the `App\Controllers\Controller` class. This is the base controller class provided by Leaf MVC and Leaf API. It is the parent class for all your application's controllers and serves as a place to put shared logic.
## Defining Controllers
-The above section looked at generating a new controller using the console helper in Leaf MVC and Leaf API. If you're using Skeleton, you can create a new controller by creating a new PHP file in the `controllers` directory. The file should contain a class that extends the `Controllers\Controller` class. The class should also contain at least one public method that returns a response.
+The above section looked at generating a new controller using the console helper in Leaf MVC and Leaf API. If you are using Leaf Core, you can manually create a controller in any way you prefer. Controllers are basically classes that have callable actions and return responses. To add some extra functionality to your controllers, you can extend the `Leaf\Controller` class.
For example, let's create a new controller that returns a simple string:
@@ -50,12 +45,14 @@ For example, let's create a new controller that returns a simple string:
namespace Controllers;
+use Leaf\Controller;
+
class HomeController extends Controller
{
- public function index()
- {
- return 'Hello World!';
- }
+ public function index()
+ {
+ response()->json('Hello World!');
+ }
}
```
@@ -78,10 +75,6 @@ app()->get('/', 'HomeController@index');
## Resource Controllers
-::: warning Skeleton
-Skeleton does not come with a console helper to generate resource controllers. If you're using Skeleton, you need to create the controller yourself.
-:::
-
Leaf resource routing assigns the typical create, read, update, and delete ("CRUD") routes to a controller with a single line of code. To get started, we can use the `g:controller` command's `--resource` option to quickly create a controller to handle these actions:
```sh
@@ -91,10 +84,10 @@ php leaf g:controller Photos --resource
This command will generate a controller at `app/controllers/PhotosController.php`. The controller will contain a method for each of the available resource operations. Next, you may register a resource route that points to the controller:
```php
-app()->resource("/user/(\d+)", "UsersController");
+app()->resource('/user/(\d+)', 'UsersController');
```
-The `resource` method accepts a URI and a controller name. The URI may contain route parameters, which will be passed to the controller methods. The controller name should be the fully-qualified class name of the controller. In this example, the `UsersController` class should be defined in the `app/controllers` directory on Leaf MVC and Leaf API or the `controllers` directory on Skeleton.
+The `resource` method accepts a URI and a controller name. The URI may contain route parameters, which will be passed to the controller methods. The controller name should be the fully-qualified class name of the controller. In this example, the `UsersController` class should be defined in the `app/controllers` directory.
This single route declaration creates multiple routes to handle a variety of actions on the resource. The generated controller will already have methods stubbed for each of these actions:
@@ -167,7 +160,7 @@ Also routes are mapped to these methods:
| DELETE | /photos/{photo} | destroy |
::: tip Leaf API Resource Controllers
-Leaf API resource controllers don't have a `create` or `edit` method. This is because Leaf API does not have a view layer like Leaf MVC and Skeleton.
+Leaf API resource controllers don't have a `create` or `edit` method. This is because Leaf API does not have a view layer like Leaf MVC does. Since you will typically be building an API that is consumed by another application, the `create` and `edit` methods will not be needed.
| Verb | URI | Action |
|----------------|-------------------------|---------|
@@ -181,10 +174,6 @@ Leaf API resource controllers don't have a `create` or `edit` method. This is be
## Leaf Console Helper
-::: warning Leaf Console
-This section only applies to Leaf MVC and Leaf API. If you're using Skeleton, you can skip this section.
-:::
-
You can also generate a model together with your controller.
```bash
@@ -234,7 +223,7 @@ Options:
Follow along with the next steps to learn more about Leaf MVC.
-
+
Routing
Learn how routing works in your Leaf applications.
diff --git a/src/docs/mvc/globals.md b/src/docs/mvc/globals.md
new file mode 100644
index 00000000..6408e674
--- /dev/null
+++ b/src/docs/mvc/globals.md
@@ -0,0 +1,287 @@
+# MVC Helpers
+
+Just as Leaf has a couple of built-in helpers, Leaf MVC also ships with a bunch of helpers to make your life easier. These helpers are available throughout your application and help you with common tasks like finding files and loading paths.
+
+## Loading app paths
+
+Since Leaf MVC and Leaf API come with a robust structure out of the box, they also come with quick ways to reference files in these structures. For example, if you want to reference a file in your `public` folder, you can use the `PublicPath()` helper.
+
+### AppPaths()
+
+This returns an array of all the paths in your application.
+
+```php
+$paths = AppPaths();
+
+$controllersPath = AppPaths('controllers'); // you can do this
+$controllersPath = $paths['controllers']; // or this
+```
+
+If the path you are looking for doesn't have a helper function, you can use the `AppPaths()` helper to get the path. Just make sure that the path is defined in your `config/paths.php` file.
+
+```php
+AppPaths('weirdPath');
+```
+
+### assets()
+
+This returns the path to your assets folder. You can pass in a file name to get the path to that file.
+
+```php
+$asset = assets('css/main.css');
+// -> public/assets/css/main.css
+```
+
+You can configure the path to your assets folder in your `config/paths.php` file.
+
+```php
+'assets' => 'public/assets'
+```
+
+### ConfigPath()
+
+This returns the path to your config folder. You can pass in a file name to get the path to that file.
+
+```php
+$dbConfigFile = ConfigPath('db.php');
+// -> config/db.php
+```
+
+### CommandsPath()
+
+This returns the path to your commands folder. You can pass in a file name to get the path to that file.
+
+```php
+$command = CommandsPath('MainCommand.php');
+// -> app/commands/MainCommand.php
+```
+
+### ControllersPath()
+
+This returns the path to your controllers folder. You can pass in a file name to get the path to that file.
+
+```php
+$controller = ControllersPath('MainController.php');
+// -> app/controllers/MainController.php
+```
+
+### DatabasePath()
+
+This returns the path to your database folder. You can pass in a file name to get the path to that file.
+
+```php
+$database = DatabasePath('migrations');
+// -> app/database/migrations
+```
+
+### FactoriesPath()
+
+This returns the path to your factories folder. You can pass in a file name to get the path to that file.
+
+```php
+$factory = FactoriesPath('UserFactory.php');
+// -> app/database/factories/UserFactory.php
+```
+
+### HelpersPath()
+
+This returns the path to your helpers folder. You can pass in a file name to get the path to that file.
+
+```php
+$helper = HelpersPath('MainHelper.php');
+// -> app/helpers/MainHelper.php
+```
+
+### LibPath()
+
+This returns the path to your lib folder. You can pass in a file name to get the path to that file.
+
+```php
+$lib = LibPath('MainLib.php');
+// -> lib/MainLib.php
+```
+
+### MigrationsPath()
+
+This returns the path to your migrations folder. You can pass in a file name to get the path to that file.
+
+```php
+$migration = MigrationsPath('MainMigration.php');
+// -> app/database/migrations/MainMigration.php
+```
+
+### ModelsPath()
+
+This returns the path to your models folder. You can pass in a file name to get the path to that file.
+
+```php
+$model = ModelsPath('User.php');
+// -> app/models/User.php
+```
+
+### PublicPath()
+
+This returns the path to your public folder. You can pass in a file name to get the path to that file.
+
+```php
+$public = PublicPath('index.php');
+// -> public/index.php
+```
+
+### RoutesPath()
+
+This returns the path to your routes folder. You can pass in a file name to get the path to that file.
+
+```php
+$routes = RoutesPath('_auth.php');
+// -> app/routes/_auth.php
+```
+
+### SeedsPath()
+
+This returns the path to your seeds folder. You can pass in a file name to get the path to that file.
+
+```php
+$seed = SeedsPath('MainSeed.php');
+// -> app/database/seeds/MainSeed.php
+```
+
+### StoragePath()
+
+This returns the path to your storage folder. You can pass in a file name to get the path to that file.
+
+```php
+$storage = StoragePath('MainStorage.php');
+// -> storage/MainStorage.php
+```
+
+### ViewsPath()
+
+This returns the path to your views folder. You can pass in a file name to get the path to that file.
+
+```php
+$view = ViewsPath('index.leaf.php');
+// -> app/views/index.leaf.php
+```
+
+## Loading app config
+
+There are some situations that may require you to load up your config files. For such situations, we've prepared a couple of helpers to help you load up your config files.
+
+### MvcConfig()
+
+This returns an array of all the config files in your application.
+
+```php
+$configs = MvcConfig();
+
+$dbConfig = MvcConfig('db'); // you can do this
+$dbConfig = $configs['db']; // or this
+```
+
+It also allows you to load up a specific config from the config file you pass in.
+
+```php
+$config = MvcConfig('db', 'host'); // you can do this
+$config = $configs['db']['host']; // or this
+```
+
+### AppConfig()
+
+This returns an array of all the config in your `config/app.php` file.
+
+```php
+$configs = AppConfig();
+
+$debug = AppConfig('debug'); // you can do this
+$debug = $configs['debug']; // or this
+```
+
+### AuthConfig()
+
+This returns an array of all the config in your `config/auth.php` file.
+
+```php
+$configs = AuthConfig();
+
+$auth = AuthConfig('auth'); // you can do this
+$auth = $configs['auth']; // or this
+```
+
+### CorsConfig()
+
+This returns an array of all the config in your `config/cors.php` file.
+
+```php
+$configs = CorsConfig();
+
+$origin = CorsConfig('origin'); // you can do this
+$origin = $configs['origin']; // or this
+```
+
+### DatabaseConfig()
+
+This returns an array of all the config in your `config/db.php` file.
+
+```php
+$configs = DatabaseConfig();
+
+$host = DatabaseConfig('host'); // you can do this
+$host = $configs['host']; // or this
+```
+
+### MailConfig()
+
+This returns an array of all the config in your `config/mail.php` file.
+
+```php
+$configs = MailConfig();
+
+$host = MailConfig('host'); // you can do this
+$host = $configs['host']; // or this
+```
+
+### ViewConfig()
+
+This returns an array of all the config in your `config/view.php` file.
+
+```php
+$configs = ViewConfig();
+
+$host = ViewConfig('viewEngine'); // you can do this
+$host = $configs['viewEngine']; // or this
+```
+
+## View Helpers
+
+View helpers are in charge of outputting your views.
+
+### view()
+
+This method calls the `render()` method of whatever view engine you are using. It takes in the name of the view you want to render and an optional array of data you want to pass to the view.
+
+```php
+view('index', [
+ 'name' => 'Leaf'
+]);
+```
+
+The only issue here is that not all view engines directly output the view. For example, Blade and Twig return the view as a string. This means that you have to echo the view.
+
+```php
+echo view('index', [
+ 'name' => 'Leaf'
+]);
+```
+
+To make this easier, Leaf MVC ships with a `render()` method that calls the `view()` helper and echoes the view.
+
+### render()
+
+This method calls the `view()` helper and echoes the view. It takes in the name of the view you want to render and an optional array of data you want to pass to the view.
+
+```php
+render('index', [
+ 'name' => 'Leaf'
+]);
+```
diff --git a/src/docs/mvc/index.md b/src/docs/mvc/index.md
index fb19bcc6..42c7e9ed 100644
--- a/src/docs/mvc/index.md
+++ b/src/docs/mvc/index.md
@@ -10,10 +10,10 @@ Leaf is a simple PHP framework/set of libraries that can be used to build any ki
## What is MVC?
-MVC stands for Model-View-Controller. It's a pattern that separates your application into three distinct parts:
+MVC stands for Model-View-Controller. It is a pattern that separates your application into three distinct parts:
- Models: These are the classes that represent your data. They are responsible for interacting with your database, and for validating your data.
-- Views: These are the files that are responsible for displaying your data to the user. They are usually written in HTML, but can also be written in other templating languages like [BareUI](https://leafphp.dev/modules/views/bareui/) or [Blade](https://leafphp.dev/modules/views/blade/).
+- Views: These are the files that are responsible for displaying your data to the user. They are usually written in HTML, but can also be written in other templating languages like [BareUI](https://leafphp.dev/modules/views/bareui/) or [Blade](https://leafphp.dev/modules/views/blade/) or frameworks like [Vue](https://vuejs.org/) or [React](https://reactjs.org/)
- Controllers: These are the classes that are responsible for handling the user's request, and for returning the appropriate response.
+
+Skeleton was designed to be a simple starting point for your application, and came with just the bare minimum to get you started. However, we have decided to deprecate Skeleton in favor of the Leaf CLI. The Leaf CLI is a command-line tool for generating Leaf projects, installing modules, and more.
+
+We recently released an update to the Leaf CLI that allows you to select specific features you want to include and generate a project with everything you need. This functionality is similar to what Skeleton provided but is more flexible and allows you to create projects with only the features that you need, which is why we've decided to deprecate Leaf Skeleton.
+
+Skeleton will still be available for download, but we won't be updating it anymore. We recommend that you generate a project with the CLI or use Leaf MVC or Leaf API instead.
+
+[> Leaf CLI Docs](/docs/cli/)
## MVC Tools
-Besides to the MVC setups, Leaf also provides a few tools that can help you build your own MVC setup if you want to. You can check the "MVC Tools" section in the sidebar to learn more about these tools.
+Besides the MVC setups, Leaf also provides a few tools that can help you build your own MVC setup if you want to. You can check the "MVC Tools" section in the sidebar to learn more about these tools.
diff --git a/src/docs/mvc/mail.md b/src/docs/mvc/mail.md
new file mode 100644
index 00000000..69429188
--- /dev/null
+++ b/src/docs/mvc/mail.md
@@ -0,0 +1,352 @@
+# Mailing
+
+Leaf provides amazing support for handling mailing in your application via Leaf Mail. The documentation for the Leaf Mailer module can be found on the [Leaf Mail page](/modules/mail/). This page will only cover how to use Leaf Mail in your Leaf MVC or Leaf API application.
+
+If you haven't already, we recommend you read the [Leaf Mail documentation](/modules/mail/) before continuing.
+
+## Setting up Leaf Mail
+
+Leaf MVC and Leaf API provide a lean setup out of the box that comes without mailing pre-activated. To activate mailing, you can run the following command in the root of your app:
+
+```bash
+php leaf mail:setup
+```
+
+This will setup everything you need to start using mailing and will also create a `mail.php` file in your `config` folder. This file contains all the configuration options for Leaf Mail. You can read more about the configuration options in the [Leaf Mail documentation](/modules/mail/#mailer-config).
+
+## Mail server connection
+
+After setting up Leaf Mail, the next thing to do is to connect to your mail server. This connection is what Leaf Mail will attempt to use whenever you initiate an email send.
+
+Before you can connect to your mail server, you need to have your mail server credentials. You can get these from your mail server provider.
+
+### Your mail provider
+
+If you are using a mail provider like Mailgun, Sendgrid, etc, you need to head over to your provider's dashboard and get your mail server credentials. From there, you need to update the mail host and port in your `.env` file.
+
+```env
+MAIL_HOST=smtp.mailtrap.io
+MAIL_PORT=2525
+```
+
+There are different kinds of server connections you can use. The most common one is SMTP using a username and password. You can also use OAuth authentication with a provider like Google.
+
+### Connection with username and password
+
+To connect to a server using your username and password, you can head over to your `.env` file and update the following values:
+
+```env
+MAIL_USERNAME=null
+MAIL_PASSWORD=null
+```
+
+These are your mail server username and password respectively. **Note that these values are not set by default**. You need to set them yourself.
+
+### Connection with OAuth
+
+Some mail providers like Google require OAuth authentication. To connect to a server using OAuth, you need to add an OAuth provider like league/oauth2-google to your project. You can install this using the Leaf CLI:
+
+```bash
+leaf install league/oauth2-google
+```
+
+Or with composer:
+
+```bash
+composer require league/oauth2-google
+```
+
+From there, you need to update the `config/mail.php` file to work with OAuth instead of username and password. You can do this by replacing these lines:
+
+```php
+'auth' => [
+ 'username' => _env('MAIL_USERNAME'),
+ 'password' => _env('MAIL_PASSWORD'),
+],
+```
+
+With the OAuth config:
+
+```php
+use League\OAuth2\Client\Provider\Google;
+use PHPMailer\PHPMailer\OAuth;
+
+return [
+ ...
+
+ 'auth' => new OAuth(
+ [
+ 'userName' => _env('MAIL_USERNAME'),
+ 'clientSecret' => _env('MAIL_CLIENT_SECRET'),
+ 'clientId' => _env('MAIL_CLIENT_ID'),
+ 'refreshToken' => _env('MAIL_REFRESH_TOKEN'),
+ 'provider' => new Google(
+ [
+ 'clientId' => _env('MAIL_CLIENT_ID'),
+ 'clientSecret' => _env('MAIL_CLIENT_SECRET'),
+ ]
+ ),
+ ]
+ ),
+
+ ...
+];
+```
+
+Since more environment variables have been added, you need to update your `.env` file to include these variables:
+
+```env
+MAIL_CLIENT_ID=
+MAIL_CLIENT_SECRET=
+MAIL_REFRESH_TOKEN=
+```
+
+::: tip .env.example
+It is a good practice to add these variables to your `.env.example` file so that other developers can easily know what environment variables they need to set.
+:::
+
+## Sending emails
+
+Before you can send emails, you need to create a mailer. You can create a mailer by running the following command in the root of your app:
+
+```bash
+php leaf mail:create
+```
+
+A mailer is a class that allows you to group related emails together. Mailers have methods called "actions" which are responsible for handling a specific type of email. For instance, you can create a mailer called `UserMailer` that has a `welcome` action for sending welcome emails, a `passwordReset` action for sending password reset emails, etc.
+
+Using this example, we can create a `UserMailer` by running the following command:
+
+```bash
+php leaf mail:create user
+```
+
+This will create a `UserMailer` class in your `app/mailers` folder. The `UserMailer` class will look like this:
+
+```php
+ 'UserMailer Test',
+ 'body' => 'This is a test mail from action',
+ 'recipientEmail' => $user->email,
+ 'recipientName' => $user->name,
+
+ // next couple of lines can be skipped if you
+ // set defaults in the config/mail.php file
+ 'senderName' => _env('MAIL_SENDER_NAME'),
+ 'senderEmail' => _env('MAIL_SENDER_EMAIL'),
+ ]);
+ }
+}
+```
+
+You can rename the `action` method to anything you want, in this case we will rename it to `welcome`. The method is responsible for creating and returning a new `Mail` instance. The `Mail` instance is what is used to send the email. You can read more about the `Mail` class in the [Leaf Mail documentation](/modules/mail/#mailer-config).
+
+```php
+ 'Welcome to my app',
+ 'body' => 'This is a test mail from action',
+ 'recipientEmail' => $user->email,
+ 'recipientName' => $user->name,
+ ]);
+ }
+}
+```
+
+To send the welcome email, you can call the `welcome` method on the `UserMailer` class like this:
+
+```php
+UserMailer::welcome($user)->send();
+```
+
+## Setting mail defaults
+
+Some values like the `senderName` and `senderEmail` are repeated in every email you send although they may not change. To avoid repeating these values, we set them as defaults in the `config/mail.php` file. You can configure these in your `.env` file like this:
+
+```env
+MAIL_SENDER_NAME=
+MAIL_SENDER_EMAIL=
+MAIL_REPLY_TO_NAME=
+MAIL_REPLY_TO_EMAIL=
+```
+
+### Removing defaults
+
+If you don't want to set defaults, you can remove them from the `config/mail.php` file. The `.env` values will then be ignored. Your updated `config/mail.php` file will look like this:
+
+```php
+...
+'defaults' => [],
+...
+```
+
+Removing these defaults means that you will have to set these values in every email you send.
+
+## Mail Debugging
+
+Leaf Mail by default reports all errors from your mail server. This is useful for debugging, but can be annoying when you are in production. You can disable this by setting the `MAIL_DEBUG` environment variable to `false` in your `.env` file.
+
+```env
+MAIL_DEBUG=false
+```
+
+## Mail Config
+
+The `config/mail.php` file contains all the configuration options for Leaf Mail. You can read more about the configuration options in the [Leaf Mail documentation](/modules/mail/#mailer-config).
+
+```php
+ _env('MAIL_DRIVER', 'smtp'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Mailer hostname
+ |--------------------------------------------------------------------------
+ |
+ | This is the hostname for your mailer
+ |
+ */
+ 'host' => _env('MAIL_HOST', 'smtp.mailtrap.io'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Mailer port
+ |--------------------------------------------------------------------------
+ |
+ | Port to use for mailer connection
+ |
+ */
+ 'port' => _env('MAIL_PORT', 2525),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Keep Alive
+ |--------------------------------------------------------------------------
+ |
+ | This config is used to keep the connection to your mail server alive.
+ | This is useful if you are sending multiple emails. It takes in a boolean.
+ |
+ */
+ 'keepAlive' => true,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Mailer Debug
+ |--------------------------------------------------------------------------
+ |
+ | Enable or disable debug mode. Supported values are:
+ | 'SERVER', false or any value supported by PHPMailer's
+ | SMTPDebug config
+ |
+ */
+ 'debug' => _env('MAIL_DEBUG', 'SERVER'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Mailer Encryption
+ |--------------------------------------------------------------------------
+ |
+ | This is the encryption used for your mailer. Supported values are:
+ | 'STARTTLS' or any value supported by PHPMailer's SMTPSecure config
+ |
+ */
+ 'security' => _env('MAIL_ENCRYPTION', 'STARTTLS'),
+
+ /*
+ |--------------------------------------------------------------------------
+ | Auth
+ |--------------------------------------------------------------------------
+ |
+ | This config handles the authentication details for your mailer.
+ | It supports authentication with username and password and also
+ | OAuth authentication.
+ |
+ | For OAuth authentication, you will need to add an OAuth
+ | provider like league/oauth2-google to your project.
+ |
+ | An example OAuth config is shown below:
+ |
+ | use League\OAuth2\Client\Provider\Google;
+ | use PHPMailer\PHPMailer\OAuth;
+ |
+ | 'auth' => new OAuth(
+ | [
+ | 'userName' => 'mail@gmail.com',
+ | 'clientSecret' => 'CLIENT_SECRET',
+ | 'clientId' => 'CLIENT_ID',
+ | 'refreshToken' => 'GMAIL_REFRESH_TOKEN',
+ | 'provider' => new Google(
+ | [
+ | 'clientId' => 'CLIENT_ID',
+ | 'clientSecret' => 'CLIENT_SECRET',
+ | ]
+ | ),
+ | ]
+ |)
+ */
+ 'auth' => [
+ 'username' => _env('MAIL_USERNAME'),
+ 'password' => _env('MAIL_PASSWORD'),
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Default addresses
+ |--------------------------------------------------------------------------
+ |
+ | This config is used to set default values for the
+ | `recipientEmail`, `recipientName`,
+ | `senderEmail`, `senderName`,
+ | `replyToName`, and `replyToEmail` of your emails.
+ |
+ */
+ 'defaults' => [
+ 'senderName' => _env('MAIL_SENDER_NAME'),
+ 'senderEmail' => _env('MAIL_SENDER_EMAIL'),
+ 'replyToName' => _env('MAIL_REPLY_TO_NAME'),
+ 'replyToEmail' => _env('MAIL_REPLY_TO_EMAIL'),
+ ],
+];
+```
diff --git a/src/docs/mvc/migrations.md b/src/docs/mvc/migrations.md
index 9c2e85e7..d977f1ac 100644
--- a/src/docs/mvc/migrations.md
+++ b/src/docs/mvc/migrations.md
@@ -2,10 +2,6 @@
-::: warning Note
-Migrations are only available in Leaf MVC and Leaf API.
-:::
-
Database migrations are a technique used in software development to manage changes to a database schema over time. A database schema is the structure of a database that defines the tables, columns, relationships, and constraints that make up the data model.
When changes are made to the database schema, such as adding a new table or column, modifying an existing column's data type, or changing a relationship between tables, database migrations allow developers to update the schema and propagate those changes to all instances of the database.
diff --git a/src/docs/mvc/models.md b/src/docs/mvc/models.md
index e426812a..40949075 100644
--- a/src/docs/mvc/models.md
+++ b/src/docs/mvc/models.md
@@ -12,25 +12,17 @@ Leaf Models are built on top of [Laravel's Eloquent ORM](https://laravel.com/doc
## Defining Models
-Your models can be found in the `app/models` directory in Leaf MVC and Leaf API, and in the `models` directory in Skeleton. Leaf MVC and Leaf API models can be created using the `php leaf g:model` command, while Skeleton models need to be added manually.
+Your models can be found in the `app/models` directory in Leaf MVC and Leaf API. Your models can be created using the `php leaf g:model` command from the root of your project.
-- ### Leaf MVC and Leaf API
-
- To create a model, run the following command:
-
- ```bash
- php leaf g:model User
- ```
-
- This will create a `User.php` file in the `app/models` directory.
-
-- ### Skeleton
+```bash
+php leaf g:model User
+```
- To create a model, create a new file in the `models` directory. The name of the file should be the name of the model, with the first letter capitalized. For example, if you want to create a `User` model, create a `User.php` file in the `models` directory.
+This will create a `User.php` file in the `app/models` directory.
## Model Structure
-Leaf MVC, Leaf API and Skeleton come with a base model class. This is to give you a place to configure all your models seamlessly without having access to the `Leaf\Model` file.
+Leaf MVC and Leaf API come with a base model class. This is to give you a place to configure all your models seamlessly without having access to the `Leaf\Model` file. It also allows you to add logic that you want to be available to all your models.
```php
class Flight extends Model
diff --git a/src/docs/mvc/schema.md b/src/docs/mvc/schema.md
index 2cd31abb..52e91494 100644
--- a/src/docs/mvc/schema.md
+++ b/src/docs/mvc/schema.md
@@ -4,8 +4,6 @@
Schema is a simple, yet powerful tool for generating database migrations from JSON data. Instead of dealing with the stress of writing your database migrations from scratch and thinking about all the types of your data, you can simply create a JSON file with sample data and let Leaf do the rest.
-**DB Schema is only available in Leaf MVC and Leaf API.**
-
## Writing your schema
Schema can be found in the `app/database/schema` folder. To get started, create a new JSON file in the the schemas directory. You can name it anything you want, but it's best to name it after the table you're creating as that is what Leaf will expect unless you specify otherwise.
diff --git a/src/docs/mvc/seeds.md b/src/docs/mvc/seeds.md
index c760338a..d19292ee 100644
--- a/src/docs/mvc/seeds.md
+++ b/src/docs/mvc/seeds.md
@@ -2,10 +2,6 @@
-::: warning Note
-Seeds are only available in Leaf MVC and Leaf API.
-:::
-
Database seeds are a way to populate a database with initial data. This initial data can be used to set up default values or pre-populate a database with test data. Database seeds typically contain small amounts of data, such as default settings, test data, or sample records.
Seeds are often used in conjunction with database migrations. After the database schema has been updated or modified, seeds can be used to populate the new or modified tables with initial data. This can be especially useful for testing and development, as it allows developers to work with a pre-populated database without having to manually enter test data.
diff --git a/src/docs/mvc/views.md b/src/docs/mvc/views.md
index 4a76367a..a3364a04 100644
--- a/src/docs/mvc/views.md
+++ b/src/docs/mvc/views.md
@@ -14,27 +14,19 @@ Leaf comes with support for 3 view engines designed by the team at Leaf:
| [veins](/modules/views/veins/) | Lightweight but powerful templating engine |
| [blade](/modules/views/blade/) | Laravel blade templating engine for leaf |
-Leaf MVC and Leaf API come with Blade already installed and configured, but Skeleton comes with BareUI instead. Of course, you can use any templating engine you prefer with Leaf, but these templating engines are specifically created for Leaf but can be used outside Leaf apps as well.
+Leaf MVC and Leaf API come with Blade already installed and configured, but of course, you can use any templating engine you prefer. These have first party support, and work amazingly well out of the box.
***You can find more information on the [Views Docs Page](/modules/views/)***
## Defining Views
-Views are defined in the `app/views` directory if you're using Leaf API/Leaf MVC or `pages` if you're using Skeleton. You can create subdirectories to organize your views.
+Views are defined in the `app/views` directory in Leaf API and Leaf MVC. You can create subdirectories to organize your views based on your preference. For example, you might create a `layouts` directory to store your layout files. To quickly create a view, you can use the `php leaf g:template` command from the root of your project.
-- ### Leaf MVC and Leaf API
-
- Leaf MVC and Leaf API come with a console tool that allows you to quickly create views. You can use the `php leaf g:template` command to create a view. This command will create a view file in the `app/views` directory.
-
- ```bash
- php leaf g:template home
- ```
-
- This will create a file called `home.blade.php` in the `app/views` directory.
-
-- ### Skeleton
+```bash
+php leaf g:template home
+```
- Skeleton comes with a `pages` directory that contains all of your views. To create a new view, simply create a new file in the `pages` directory. For example, if you wanted to create a view called `home`, you would create a file called `home.view.php` in the `pages` directory.
+This will create a file called `home.blade.php` in the `app/views` directory.
## Rendering Views
@@ -49,6 +41,26 @@ echo view('home', ['name' => 'John Doe']);
Notice that we pass the name of the view without the file extension. This is because Leaf will automatically append the correct file extension based on the view engine you're using.
+### The `render()` method
+
+To make things even easier for you, Leaf also ships with a `render()` method. This method accepts the same parameters as the `view()` method but automatically outputs the views with the correct headers in place.
+
+```php
+render('home', ['name' => 'John Doe']);
+```
+
+## Asset Bundling
+
+[Vite](https://vitejs.dev/) is a modern build tool for frontend applications. It aims to provide a faster and leaner development experience for modern web projects. Leaf allows you to bundle your CSS and JS assets using vite, using the powerful [leaf-vite](/modules/views/vite/) module.
+
+[> Read the docs](/modules/views/vite/)
+
+## Frontend Frameworks
+
+Leaf has support for some of the most popular frontend frameworks using [Inertia.js](https://inertiajs.com/). Inertia.js is a framework that allows you to create fully client-side rendered, single-page apps, without much of the complexity that comes with modern SPAs. It does this by leveraging Leaf's server-side rendering capabilities.
+
+[> Read the docs](/modules/views/inertia/)
+
## Next Steps
You can continue learning about MVC with Leaf from the sidebar or check out the view engines below:
diff --git a/src/docs/routing/errors.md b/src/docs/routing/errors.md
index eea5f3ca..606719d2 100755
--- a/src/docs/routing/errors.md
+++ b/src/docs/routing/errors.md
@@ -26,7 +26,7 @@ The example below displays a custom 404 page.
```php
app()->set404(function () {
- response()->page("./pages/404.html");
+ response()->page('./pages/404.html');
});
```
@@ -35,7 +35,7 @@ app()->set404(function () {
```php
$app->set404(function () use($app) {
- $app->response()->page("./pages/404.html");
+ $app->response()->page('./pages/404.html');
});
```
@@ -57,7 +57,7 @@ app()->config('debug', false);
```php
-$app = new Leaf\App('debug', false);
+$app = new \Leaf\App('debug', false);
```
@@ -70,28 +70,28 @@ Although Leaf handles both debug and production cases, you may want to display y
This method takes in a callable in the form of a function or an array. You can take a look at the exaples below:
-
+
```php
// use an error handler from a package
-app()->setErrorHandler(['\Leaf\Exception\General', 'defaultError']);
+$app->setErrorHandler(['\Leaf\Exception\General', 'defaultError']);
// use a custom function
-app()->setErrorHandler(function () {
- response()->page("./pages/500.html");
+$app->setErrorHandler(function () use($app) {
+ $app->response()->page('./pages/500.html');
});
```
-
+
```php
// use an error handler from a package
-$app->setErrorHandler(['\Leaf\Exception\General', 'defaultError']);
+app()->setErrorHandler(['\Leaf\Exception\General', 'defaultError']);
// use a custom function
-$app->setErrorHandler(function () use($app) {
- $app->response()->page("./pages/500.html");
+app()->setErrorHandler(function () {
+ response()->page('./pages/500.html');
});
```
@@ -99,28 +99,24 @@ $app->setErrorHandler(function () use($app) {
## Application Down
-Leaf is also able to dynamically handle placing your application in maintainance mode using leaf config.
+Leaf is also able to dynamically handle placing your application in maintenance mode using leaf config. We have a `down` config which you can set to `true` to place your application in maintenance mode.
```php
-app()->config("app.down", true);
+app()->config('app.down', true);
```
```php
-$app->config("app.down", true);
+$app->config('app.down', true);
```
-Alternatively, you could also place your application in maintainance mode by setting the `APP_DOWN` environment variable to true. Since `.env` variables are given more priority than router config, the router config will be ignored as long as the env is set.
-
-::: warning Loading your env
-Leaf expects you to manually load your `.env` file and will not be responsible for this. You can use [vlucas/phpdotenv](https://packagist.org/packages/vlucas/phpdotenv) to do this. After loading your `.env` variables into your app, leaf router will automatically pick them up.
-:::
+Alternatively, you could also place your application in maintenance mode by setting the `APP_DOWN` environment variable to true. Since `.env` variables are given more priority than router config, the router config will be ignored as long as the env is set. If you decide to use the env variable, you will have to manually load your `.env` file. Check out the [env docs](/docs/config/nsm) for more info.
::: tip Loading your env
Your environment variables are automatically loaded into your application if you are using Leaf MVC, Leaf API or Skeleton.
@@ -128,13 +124,13 @@ Your environment variables are automatically loaded into your application if you
### Custom Down Handler
-Leaf comes with a beautiful application down handler which you can use in production. However, it might not match your theme, or you might have a maintainance screen designed by someone which needs to match that design. Leaf gives you the flexibility to display a custom maintainance error page using the `setDown` method.
+Leaf comes with a beautiful application down handler which you can use in production. However, it might not match your theme, or you might have a maintenance screen designed by someone which needs to match that design. Leaf gives you the flexibility to display a custom maintenance error page using the `setDown` method.
```php
app()->setDown(function () {
- echo "Down for maintainance";
+ echo "Down for maintenance";
});
```
@@ -143,7 +139,7 @@ app()->setDown(function () {
```php
$app->setDown(function () {
- echo "Down for maintainance";
+ echo "Down for maintenance";
});
```
diff --git a/src/docs/routing/index.md b/src/docs/routing/index.md
index 21bcf8d4..51aaeba8 100755
--- a/src/docs/routing/index.md
+++ b/src/docs/routing/index.md
@@ -32,7 +32,7 @@ The router class is the interface you interact with to perform any routing actio
```php
use Leaf\Router;
-Router::get("/", "PagesController@index");
+Router::get('/', 'PagesController@index');
Router::run();
```
@@ -49,10 +49,10 @@ To make things simpler, we tied leaf router directly to the leaf instance, so on
```php
get("/", function () {
- response()->json(["name" => "Leaf"]);
+app()->get('/', function () {
+ response()->json(['name' => 'Leaf']);
});
app()->run();
@@ -68,8 +68,8 @@ require __DIR__ . "/vendor/autoload.php";
$app = new \Leaf\App();
-$app->get("/", function () use($app) {
- $app->response()->json(["name" => "Leaf"]);
+$app->get('/', function () use($app) {
+ $app->response()->json(['name' => 'Leaf']);
});
$app->run();
@@ -101,9 +101,9 @@ composer require imaginary/router
// initialise imaginary router
$imr = new Imaginary\Router();
-$imr->get("/", function () {
+$imr->get('/', function () {
// you can still use leaf modules
- response()->json(["title" => "hello"]);
+ response()->json(['title' => 'hello']);
});
```
@@ -115,9 +115,9 @@ $imr->get("/", function () {
$imr = new Imaginary\Router();
$response = new Leaf\Http\Response();
-$imr->get("/", function () use($response) {
+$imr->get('/', function () use($response) {
// you can still use leaf modules
- $response->json(["title" => "hello"]);
+ $response->json(['title' => 'hello']);
});
```
@@ -349,7 +349,7 @@ A resource route simply creates all the routes needed to successfully handle a p
```php
-app()->resource("/posts", "PostsController");
+app()->resource('/posts', 'PostsController');
app()->run();
```
@@ -358,7 +358,7 @@ app()->run();
```php
-$app->resource("/posts", "PostsController");
+$app->resource('/posts', 'PostsController');
$app->run();
```
@@ -370,13 +370,13 @@ The code above is equivalent to this:
```php
-app()->match("GET|HEAD", "/posts", "$controller@index");
-app()->post("/posts", "$controller@store");
-app()->match("GET|HEAD", "/posts/create", "$controller@create");
-app()->match("POST|DELETE", "/posts/{id}/delete", "$controller@destroy");
-app()->match("POST|PUT|PATCH", "/posts/{id}/edit", "$controller@update");
-app()->match("GET|HEAD", "/posts/{id}/edit", "$controller@edit");
-app()->match("GET|HEAD", "/posts/{id}", "$controller@show");
+app()->match('GET|HEAD', '/posts', "$controller@index");
+app()->post('/posts', "$controller@store");
+app()->match('GET|HEAD', '/posts/create', "$controller@create");
+app()->match('POST|DELETE', '/posts/{id}/delete', "$controller@destroy");
+app()->match('POST|PUT|PATCH', '/posts/{id}/edit', "$controller@update");
+app()->match('GET|HEAD', '/posts/{id}/edit', "$controller@edit");
+app()->match('GET|HEAD', '/posts/{id}', "$controller@show");
app()->run();
```
@@ -385,13 +385,13 @@ app()->run();
```php
-$app->match("GET|HEAD", "/posts", "$controller@index");
-$app->post("/posts", "$controller@store");
-$app->match("GET|HEAD", "/posts/create", "$controller@create");
-$app->match("POST|DELETE", "/posts/{id}/delete", "$controller@destroy");
-$app->match("POST|PUT|PATCH", "/posts/{id}/edit", "$controller@update");
-$app->match("GET|HEAD", "/posts/{id}/edit", "$controller@edit");
-$app->match("GET|HEAD", "/posts/{id}", "$controller@show");
+$app->match('GET|HEAD', '/posts', "$controller@index");
+$app->post('/posts', "$controller@store");
+$app->match('GET|HEAD', '/posts/create', "$controller@create");
+$app->match('POST|DELETE', '/posts/{id}/delete', "$controller@destroy");
+$app->match('POST|PUT|PATCH', '/posts/{id}/edit', "$controller@update");
+$app->match('GET|HEAD', '/posts/{id}/edit', "$controller@edit");
+$app->match('GET|HEAD', '/posts/{id}', "$controller@show");
$app->run();
```
@@ -404,7 +404,7 @@ Resource routes are handled by a [resource controller](/docs/routing/controller?
You can add a route that handles a couple of HTTP methods with the Leaf router's match() method. It accepts three arguments:
-- The HTTP method(s) seperated by |
+- The HTTP method(s) seperated by `|`
- The route pattern (with optional named placeholders or PCRE based patterns)
- The route callback
@@ -456,7 +456,7 @@ Leaf route handlers are usually callable functions like this:
```php
app()->get("/home", function () {
- echo "User Home";
+ echo 'User Home';
});
```
@@ -465,7 +465,7 @@ app()->get("/home", function () {
```php
$app->get("/home", function () {
- echo "User Home";
+ echo 'User Home';
});
```
@@ -476,14 +476,14 @@ Or sometimes controllers, like this:
```php
-app()->get("/home", "HomeController@index");
+app()->get('/home', 'HomeController@index');
```
```php
-$app->get("/home", "HomeController@index");
+$app->get('/home', 'HomeController@index');
```
@@ -493,8 +493,8 @@ This means there was no space to chain additional items to the route, this is so
```php
-app()->get("/home", ["name" => "home", function () {
- echo "User Home";
+app()->get('/home', ['name' => 'home', function () {
+ echo 'User Home';
}]);
```
@@ -502,8 +502,8 @@ app()->get("/home", ["name" => "home", function () {
```php
-$app->get("/home", ["name" => "home", function () {
- echo "User Home";
+$app->get('/home', ['name' => 'home', function () {
+ echo 'User Home';
}]);
```
@@ -514,14 +514,14 @@ When an array is passed into a leaf route as the handler, leaf will take all `ke
```php
-app()->get("/form", ["name" => "userForm", "FormsController@index"]);
+app()->get('/form', ['name' => 'userForm', 'FormsController@index']);
```
```php
-$app->get("/form", ["name" => "userForm", "FormsController@index"]);
+$app->get('/form', ['name' => 'userForm', 'FormsController@index']);
```
@@ -531,7 +531,7 @@ As mentioned before, this feature is also available on groups:
```php
-app()->group("/user", ["namespace" => "\\", function () {
+app()->group('/user', ['namespace' => '\\', function () {
// ...
}]);
```
@@ -540,7 +540,7 @@ app()->group("/user", ["namespace" => "\\", function () {
```php
-$app->group("/user", ["namespace" => "\\", function () {
+$app->group('/user', ['namespace' => '\\', function () {
// ...
}]);
```
@@ -556,18 +556,93 @@ You can give names to your routes which allows you to use your route names for n
```php
-app()->get("/home", ["name" => "home", function () {
- echo "User Home";
+app()->get('/home', ['name' => 'home', function () {
+ echo 'User Home';
+}]);
+```
+
+
+
+
+```php
+$app->get('/home', ['name' => 'home', function () {
+ echo 'User Home';
}]);
```
+
+
+### Getting a route by its name
+
+You can also get the route path by its name.
+
+
+
+```php
+app()->route('home'); // Would return: /home
+```
+
```php
-$app->get("/home", ["name" => "home", function () {
- echo "User Home";
+$app->route('home'); // Would return: /home
+```
+
+
+
+Also, if you have routes with named parameters, you can do as follows:
+
+Route 1:
+
+
+
+```php
+app()->get('/movies/{movieId}', ['name' => 'movies', function () {
+ echo 'User Movies';
}]);
+
+app()->route('movies', 'my-movie') // Would return: /movies/my-movie
+```
+
+
+
+
+```php
+$app->get('/movies/{movieId}', ['name' => 'movies', function () {
+ echo 'User Movies';
+}]);
+
+$app->route('movies', 'my-movie') // Would return: /movies/my-movie
+```
+
+
+
+Route 2:
+
+
+
+```php
+app()->get('/movies/{movieId}/photos/{photoId}', ['name' => 'moviesAndPhotos', function () {
+ echo 'User Movies and Photos';
+}]);
+
+app()->route('moviesAndPhotos', ['movieId' => 'my-movie', 'photoId' => 'my-photo']);
+
+// Would return: /movies/my-movie/photos/my-photo
+```
+
+
+
+
+```php
+$app->get('/movies/{movieId}/photos/{photoId}', ['name' => 'moviesAndPhotos', function () {
+ echo 'User Movies and Photos';
+}]);
+
+$app->route('moviesAndPhotos', ['movieId' => 'my-movie', 'photoId' => 'my-photo']);
+
+// Would return: /movies/my-movie/photos/my-photo
```
@@ -579,14 +654,14 @@ This is simply redirecting to a route and can be done using `push`. `push` also
```php
-app()->push("/home");
+app()->push('/home');
```
```php
-$app->push("/home");
+$app->push('/home');
```
@@ -597,7 +672,7 @@ When an array is passed into push, Leaf will search for a route name matching th
```php
// home was defined above
-app()->push(["home"]);
+app()->push(['home']);
```
@@ -605,7 +680,7 @@ app()->push(["home"]);
```php
// home was defined above
-$app->push(["home"]);
+$app->push(['home']);
```
@@ -617,7 +692,7 @@ There are times when you need to get information about the current route from wi
```php
-app()->get("/home", ["name" => "home", function () {
+app()->get('/home', ['name' => 'home', function () {
$route = app()->getRoute();
echo $route['name'];
}]);
@@ -627,7 +702,7 @@ app()->get("/home", ["name" => "home", function () {
```php
-$app->get("/home", ["name" => "home", function () use ($app) {
+$app->get('/home', ['name' => 'home', function () use ($app) {
$route = $app->getRoute();
echo $route['name'];
}]);
diff --git a/src/docs/routing/mvc.md b/src/docs/routing/mvc.md
new file mode 100644
index 00000000..d90e327a
--- /dev/null
+++ b/src/docs/routing/mvc.md
@@ -0,0 +1,103 @@
+# Usage with Leaf MVC
+
+Leaf MVC and Leaf API use a routing system based on the [Leaf Core](/docs/routing/) router. This means you can use all of Leaf Core's routing methods on your Leaf MVC and Leaf API apps. You can find the full docs [here](/docs/routing/).
+
+## Adding Routes
+
+Leaf MVC and Leaf API come with an `app/routes` folder. This folder contains all your route files. The `app/routes/index.php` file is the entry point for all your routes and is where you can add all your routes.
+
+## Route Partials
+
+New versions of Leaf MVC and Leaf API come with a new feature called route partials. Route partials allow you to split your routes into multiple files. This is useful if you have a lot of routes and you want to split them into multiple files. To use route partials, you can create a new file in your `app/routes` folder and add your routes to it.
+
+All files in your `app/routes` folder that start with `_` are automatically loaded by Leaf MVC and Leaf API. This means that you can create a file called `app/routes/_auth.php` and add all your auth routes to it. This file will be automatically loaded by Leaf MVC and Leaf API, and all the routes in it will be available in your app.
+
+If you don't want a file to be automatically loaded, create a file that doesn't start with `_`. For example, you can create a file called `app/routes/auth.php` and add all your auth routes to it. This file will **NOT** be automatically loaded by Leaf MVC and Leaf API, and you'll have to load it manually.
+
+## Linking Controllers
+
+Controllers provide a way to organize your application's logic. They are a great way to keep your routes file clean and easy to read. Controllers are just classes that implement the `App\Controllers\Controller` class. You can find more information about controllers in the [Controllers](/docs/mvc/controllers) document. This document will focus on how to link controllers to routes.
+
+Leaf provides a simple interface for interacting with controllers and their methods from inside your routes. The idea is to run a method inside your controller whenever a route is matched. This is done by telling Leaf which controller to use and which method to run. Leaf will then create an instance of the controller and run the method.
+
+### Example
+
+Let's say you have a controller called `App\Controllers\HomeController` and you want to run the `index` method inside it whenever the `/` route is matched. You can do this by passing a string containing your controller name and method to your route. The string should be in the format `controllerName@methodName`.
+
+
+
+```php
+$app->get('/', '\App\Controllers\HomeController@index');
+```
+
+
+
+
+```php
+app()->get('/', '\App\Controllers\HomeController@index');
+```
+
+
+
+## Controller Namespaces
+
+***This has already been setup for you in the root routes file of your MVC application.***
+
+In case you're using an auto loader or using leaf in another framework and you have your controllers in another directory, you can do sommething like this
+
+
+
+```php
+app()->get('/(\d+)', '\App\Controllers\User@showProfile');
+```
+
+
+
+
+```php
+$app->get('/(\d+)', '\App\Controllers\User@showProfile');
+```
+
+
+
+But this gets tedious if you have a lot of routes. So Leaf allows you to set a "general" namespace, you can set the default namespace to use on your router instance via `setNamespace()`
+
+
+
+```php
+app()->setNamespace('\App\Controllers');
+
+app()->get('/users/(\d+)', 'User@showProfile');
+app()->get('/cars/(\d+)', 'Car@showProfile');
+```
+
+
+
+
+```php
+$app->setNamespace('\App\Controllers');
+
+$app->get('/users/(\d+)', 'User@showProfile');
+$app->get('/cars/(\d+)', 'Car@showProfile');
+```
+
+
+
+## Next Steps
+
+Follow along with the next steps to learn more about Leaf MVC.
+
+
diff --git a/src/docs/skeleton/index.md b/src/docs/skeleton/index.md
index 24ae0b3f..dca12226 100644
--- a/src/docs/skeleton/index.md
+++ b/src/docs/skeleton/index.md
@@ -1,46 +1,22 @@
-# Skeleton
-
-Skeleton is a minimal but powerful MVC boilerplate built on top of Leaf. It's designed to be simple, fast and easy to use. It is meant to bring structure to your Leaf workflow without forcing you to stick to any framework. It is a good starting point for building lightweight applications using the MVC pattern.
-
-::: tip Leaf MVC vs Leaf API vs Skeleton
-
-Leaf offers three setups for you to choose from. You can find more information about these setups in the [MVC](/docs/mvc/#mvc-in-leaf) section.
-
-:::
+# Skeleton
-## Installation
+Skeleton was designed to be a simple starting point for your application, and came with just the bare minimum to get you started. However, we have decided to deprecate Skeleton in favor of the Leaf CLI. The Leaf CLI is a command-line tool for generating Leaf projects, installing modules, and more.
-The easiest way to setup Skeleton is to use the [Leaf CLI](/docs/cli/):
+## Discontinuing Skeleton
-```bash
-leaf create
--skeleton --v3
-```
+We recently released an update to the Leaf CLI that allows you to select specific features you want to include and generate a project with everything you need. This functionality is similar to what Skeleton provided but is more flexible and allows you to create projects with only the features that you need, which is why we've decided to deprecate Leaf Skeleton.
-You can also setup a Skeleton app by using [Composer](https://getcomposer.org/):
+Skeleton will still be available for download, but we won't be updating it anymore. We recommend that you generate a project with the CLI or use Leaf MVC or Leaf API instead.
-```bash
-composer create-project leafs/skeleton
-```
+## Updating from Skeleton
-This command will set up a Skeleton app in the `` directory. You can then run the app using the Leaf CLI:
-
-```bash
-cd
-leaf serve
-```
-
-Or the [built-in PHP server](https://www.php.net/manual/en/features.commandline.webserver.php):
-
-```bash
-cd
-php -S localhost:8000
-```
+The beauty of this update is that you don't have to change anything in your existing Skeleton project. This is because Skeleton, unlike Leaf MVC and Leaf API is not a framework. It's just a starting point for your project. So, you can continue to use your Skeleton project and update specific features using the Leaf CLI or Composer.
-You should then see the welcome page in your browser.
+If you are starting a fresh project however, we recommend that you use the Leaf CLI to generate your project. If you want to use Composer, you can install Leaf MVC or Leaf API instead.
-![Skeleton Welcome Page](https://user-images.githubusercontent.com/26604242/224507748-87396f4d-7b1e-4d61-ada1-b37e732c739b.png)
+**The Skeleton docs will still be available here, but we won't be updating it anymore.**
## Directory Structure
@@ -106,7 +82,7 @@ Follow along with the next steps to learn more about Skeleton.
Skeleton Configuration
Learn how to configure Leaf and your app to work in different ways.
-
+
Routing
Learn how routing works in your Leaf applications.
diff --git a/src/docs/tooling/functions.md b/src/docs/tooling/functions.md
index 04273fe5..0bd4b8b6 100644
--- a/src/docs/tooling/functions.md
+++ b/src/docs/tooling/functions.md
@@ -27,52 +27,6 @@ app()->get('/', function () {
app()->run();
```
-## How to configure leaf
-
-Since leaf provides extra options which can be passed into leaf on init, how do you configure the leaf object if you have no direct access to it?
-
-- Use the config method
-
-There is a configuration method on leaf which allows you to set extra configurations if needed. You might never have to use this, but depending on the complexities to tackle, you might want Leaf to behave a certain way. You can call the `config` method on `app()` to set these application config.
-
-```php
-config('app.down', true);
-
-app()->get('/', function () {
- response()->json(['name' => 'Leaf']);
-});
-
-app()->run();
-```
-
-- Use the config class
-
-Besides this, you can use the `Leaf\Config` class to pass in configuration options
-
-```php
-get('/', function () {
- response()->json(['name' => 'Leaf']);
-});
-
-app()->run();
-```
-
-The main difference here is that the second method sets the config before the Leaf app is initialized. This means that during initialization, Leaf will use the config that has been set, however, for the first method, the config is loaded only after Leaf is initialized and thus, not used in the initialization process.
-
-::: tip Note
-This is no longer an issue as Leaf will reactively set the config, and so you won't experience any issues with setting the config later in your app with `app->config()`. Of course, you can still use `Leaf\Config` to skip the reactivity process.
-:::
-
## app
This function returns the current instance of the Leaf application. If none exists, it creates and returns it.
@@ -80,8 +34,8 @@ This function returns the current instance of the Leaf application. If none exis
```php{4}
$app = new Leaf\App;
-$app->get("/", function () {
- app()->response()->json(["name" => "Leaf"]);
+$app->get('/', function () {
+ app()->response()->json(['name' => 'Leaf']);
});
```
@@ -90,19 +44,19 @@ $app->get("/", function () {
```php{5}
get("/", function () {
- response()->json(["name" => "Leaf"]);
+app()->get('/', function () {
+ response()->json(['name' => 'Leaf']);
});
app()->run();
```
-As seen on line 5, no app instance already exists and so one is created and returned. This gives you powerful tooling and lets you get rid of imports, namespaces...
+As seen on line 5, no app instance already exists and so one is created and returned. This gives you powerful tooling and lets you get rid of imports, namespaces and lengthy initializers.
::: warning NOTE
-In other frameworks like laravel which also ship an `app` method, calling `app` will return the laravel instance, not leaf's. In such situations, you can use the [app instance config](/docs/config/nsm#config-app-instance)
+In other frameworks like Laravel which also ship an `app()` method, calling `app()` will return the Laravel instance, not leaf's. In such situations, you can use the [app instance config](/docs/config/nsm#config-app-instance) if you absolutely need to use the leaf app instance.
:::
## _env
@@ -114,15 +68,15 @@ This global function allows you to get environment variables set in your `.env`
```php
// get value
-$mode = _env("APP_MODE");
+$mode = _env('APP_MODE');
// get value with default
-$mode = _env("APP_MODE", "production");
+$mode = _env('APP_MODE', 'production');
```
## Extending
-These are the globals provided by default with Leaf, however, some Leaf modules come in with their own globals, for instance, `leafs/session` has the `session` and `flash` globals. All globals are named carefully to avoid conflicts with other popular PHP packages.
+As mentioned earlier, some leaf modules come with their own globals. For instance, the [leaf http module](/modules/http/v/2/) comes with the `request()` and `response()` globals. All globals are named carefully to avoid conflicts with other popular PHP packages.
::: warning NOTE
Leaf and it's modules **only** set a global if a function with that name doesn't exist. This is to avoid unintentionally overwriting important functions in your code.
@@ -130,45 +84,34 @@ Leaf and it's modules **only** set a global if a function with that name doesn't
If you run into a challenge like this, you can rename your functions if you defined them yourself.
-::: tip Extending
-Modules which extend functional mode will have a section on their documentation with a functional mode tag. You can always look out for that
-:::
+**Throughout the docs, modules that support functional mode will have a section for the globals they provide.**
-## request
+## Http Module
-`request` is a global function which returns the leaf request object. The request global is provided from the [leaf http module](/modules/http/) which comes with leaf 3 out of the box, so there's no need to install it.
+The [leaf http module](/modules/http/v/2/) comes with 2 globals:
+
+### request
+
+`request()` is a global function which returns the leaf request object. This is available out of the box in your Leaf applications, so there's no need to install the http module. Read more about the request object [here](/modules/http/v/2/request).
```php
$username = request()->get('username');
```
-## response
+### response
-This global returns the leaf response object. The response global is provided from the [leaf http module](/modules/http/) so there's no need to install it since it comes with leaf 3 out of the box.
+`response()` is a global function which returns the leaf response object. This is available out of the box in your Leaf applications, so there's no need to install the http module. Read more about the response object [here](/modules/http/v/2/response).
```php
response()->markup("Mychi");
```
-## cookie
+## Leaf Cookie
This global allows you to set/get a cookie or return the leaf cookie object. The cookie global is provided from the [leaf cookie module](/modules/cookies/).
```php
-// set multiple cookies
-cookie(["name" => "Mychi", "code" => "PHP"]);
-
-// set single cookie
-cookie("name", "Mychi");
-
-// get cookie
-cookie("name");
-```
-
-If nothing is passed into `cookie`, it returns the leaf cookie object.
-
-```php
-cookie()->set("name", "Mychi");
+cookie()->set(["name" => "Mychi", "code" => "PHP"]);
```
## Leaf CSRF
@@ -211,3 +154,11 @@ After installing the leaf db module, you'll have access to the `db` global. This
```php
db()->connect(...);
```
+
+## Leaf Auth
+
+The leaf auth module provides an `auth()` global. This method returns an instance of the leaf auth class.
+
+```php
+auth()->login(...);
+```
diff --git a/src/docs/tooling/testing.md b/src/docs/tooling/testing.md
index 03e4d251..a976283f 100644
--- a/src/docs/tooling/testing.md
+++ b/src/docs/tooling/testing.md
@@ -80,53 +80,78 @@ You should see something like this:
![phpunit](https://user-images.githubusercontent.com/26604242/182213801-501067c4-d77c-4769-b18a-d83573047b84.png)
-
+The `testsuites` option is an array of all the testsuites you want to run. You can have multiple testsuites, each with their own config. The default testsuite is `directory` which is the directory where your tests are located. You can change this to suit your needs.
-- PHPUnit
+```php
+'testsuites' => [
+ 'directory' => './tests'
+]
+```
-![pest run](https://user-images.githubusercontent.com/26604242/182264487-6db016be-bee3-40d2-bb75-64d34d893e6a.png)
+The `coverage` option is an array of all the coverage options you want to use. You can change this to suit your needs.
+
+```php
+'coverage' => [
+ 'processUncoveredFiles' => true,
+ 'include' => [
+ './app' => '.php',
+ './src' => '.php'
+ ]
+]
+```
-## Config
+## Exporting your config
-As mentioned before, Alchemy simply runs your tests for you. It allows you to run tests without having to do a ton of config first or even write a `phpunit.xml`. All config is handled by Alchemy itself. However, if you want to have control over the `phpunit.xml` file, you can export Alchemy's default config to create a `phpunit.xml` file. You can do this with:
+We mentioned Alchemy handles all the config for how your tests are run, however, if you want to have full control over the way your tests are run, you simply need to export your config like this:
```bash
./vendor/bin/alchemy config:export
diff --git a/src/docs/tooling/view.md b/src/docs/tooling/view.md
index 21b9db05..c066a881 100644
--- a/src/docs/tooling/view.md
+++ b/src/docs/tooling/view.md
@@ -1,6 +1,7 @@
-
# Leaf View
+
+
@@ -11,15 +12,19 @@ import VideoDocs from '/@theme/components/VideoDocs.vue'
link="https://www.youtube.com/embed/BTcUgeOZLyM"
/> -->
-Leaf view is a view manager for your leaf apps. This simply gives you the platform to register, configure and use as many templating engines as you want within your app. This means you can now ship your app with various engines, or rewrite your UIs with a different engine without having to translate or pull down the whole app first.
+Leaf is very flexible when it comes to views. Leaf allows you to use any templating engine you want, and even use multiple engines at the same time. To keep track of all these engines, Leaf provides a view manager, which allows you to register, configure and use as many templating engines as you want within your app.
+
+This is useful when you want to ship your app with various engines, or rewrite your UIs with a different engine without having to translate or pull down the whole app first.
Leaf view also allows you to run multiple instances of the same engine, with different configurations, values and all that.
## Getting Started
-View comes with only one method, `attach`. This method allows you to link UI engines to your leaf app. If attach is called before initializing your leaf app, leaf will automatically attach these engines to the leaf instance.
+Leaf View is a part of the Leaf core, so you don't need to install anything to use it. It allows you to attach view engines to your leaf app, and use them anywhere in your app.
-`attach` takes in 2 parameters:
+## Attaching View Engines
+
+Leaf View comes with an `attach` method that allows you to link UI engines to your leaf app. It takes in 2 parameters:
- The UI engine class to attach (required)
- The key to save the engine as (optional). If it's not provided, it will use the class name.
@@ -27,95 +32,77 @@ View comes with only one method, `attach`. This method allows you to link UI eng
```php
-Leaf\View::attach(\Leaf\Veins\Template::class, "veins");
+Leaf\View::attach(\Leaf\Veins::class, 'veinsEngine');
Leaf\View::attach(\Leaf\Blade::class);
-
-// when views are attached before leaf is initialized,
-// leaf will automatically pick up attached view engines
-$app = new Leaf\App;
-
-// You can use attached views like this:
-$app->veins->render('page');
-echo $app->blade->render('page');
```
```php
-Leaf\View::attach(\Leaf\Veins\Template::class, "veins");
+Leaf\View::attach(\Leaf\Veins::class, 'veinsEngine');
Leaf\View::attach(\Leaf\Blade::class);
-
-// when views are attached before you call `app`,
-// leaf will automatically pick up attached view engines
-// You can use attached views like this:
-app()->veins->render('page');
-echo app()->blade->render('page');
```
-If the views are attached after leaf is initialized, you need to tell leaf to attach them to the instance if you prefer it. This can be done by calling `loadViewEngines`
+We recommend doing this before initializing your leaf app, but you can attach engines at any time.
-
+## Using Attached Views
-```php
-// leaf is initialized before the view is attached
-$app = new Leaf\App;
+Once you've attached your view engine, it is automatically linked to the Leaf instance and can be used like this:
-View::attach(\Leaf\Veins\Template::class, "veins");
+
-$app->loadViewEngines(); // here
+```php
+Leaf\View::attach(\Leaf\Veins::class, 'veinsEngine');
+Leaf\View::attach(\Leaf\Blade::class);
-// you can use veins now
+$app = new Leaf\App;
-$app->veins->render("app");
+$app->veinsEngine->render('page');
+echo $app->blade->render('page');
```
```php
-// `app` is called here, so leaf is initialized before the
-// view is attached
-app()->get('/', function () {
- // ...
-});
-
-View::attach(\Leaf\Veins\Template::class, "veins");
-
-app()->loadViewEngines(); // here
+Leaf\View::attach(\Leaf\Veins::class, 'veinsEngine');
+Leaf\View::attach(\Leaf\Blade::class);
-// you can use veins now
-app()->veins->render("app");
+app()->veinsEngine->render('page');
+echo app()->blade->render('page');
```
+## Using without the Leaf instance
+
If you don't want to set up your engine to the Leaf instance, you can still use it on the View class:
-
+
```php
-View::attach(\Leaf\Veins\Template::class, "veins");
+View::attach(\Leaf\Veins::class);
-// $veins becomes available after attaching it
+// veins() becomes available after attaching it
View::veins()->configure([
- 'veins_dir' => app()->config("views.path"),
- 'cache_dir' => app()->config("views.cachePath"),
+ 'templateDir' => 'views/',
+ 'cacheDir' => 'views/cache/'
]);
```
-
+
```php
-View::attach(\Leaf\Veins\Template::class, "veins");
+View::attach(\Leaf\Veins::class);
-// $veins becomes available after attaching it
+// veins() becomes available after attaching it
View::veins()->configure([
- 'veins_dir' => $app->config("views.path"),
- 'cache_dir' => $app->config("views.cachePath"),
+ 'templateDir' => 'views/',
+ 'cacheDir' => 'views/cache/'
]);
```
diff --git a/src/events/events.json b/src/events/events.json
index 93eb7530..377136ca 100644
--- a/src/events/events.json
+++ b/src/events/events.json
@@ -3,7 +3,7 @@
"name": "Building Scalable APIs: Exploring the Power of Leaf PHP Framework",
"flyer": "https://pbs.twimg.com/media/F2haAZpWUAI5hb1?format=png&name=900x900",
"intro": "Join us for a Twitter space hosted by @DevCongress \"Building Scalable APIs with LeafPHP's Framework - Unleash Scalability and Efficiency.\" Don't miss this opportunity to accelerate your development journey!",
- "date": "2023-08-09T19:00:00.000Z",
+ "date": "2023-08-14T19:00:00.000Z",
"description": [
"Join us for a Twitter space hosted by @DevCongress \"Building Scalable APIs with LeafPHP's Framework - Unleash Scalability and Efficiency.\" Don't miss this opportunity to accelerate your development journey!"
],
diff --git a/src/modules/anchor/csrf/index.md b/src/modules/anchor/csrf/index.md
index c0ed0cc7..44acedc1 100644
--- a/src/modules/anchor/csrf/index.md
+++ b/src/modules/anchor/csrf/index.md
@@ -1,7 +1,6 @@
-# Leaf CSRF
-
+# Leaf CSRF
Beta
-
+
[![Latest Stable Version](https://poser.pugx.org/leafs/csrf/v/stable)](https://packagist.org/packages/leafs/csrf)
@@ -11,10 +10,6 @@
-::: danger NOTE
-This is an experimental module. Please open an issue if you notice any bugs or malfunctions.
-:::
-
This package is leaf's implementation of CSRF default protection with leaf anchor. It comes separated from leaf anchor because it is not needed in every project you may build.
## Installation
diff --git a/src/modules/auth/config.md b/src/modules/auth/config.md
index 4422e7c0..a68d2978 100755
--- a/src/modules/auth/config.md
+++ b/src/modules/auth/config.md
@@ -1,21 +1,19 @@
# Auth Config
-Auth Config was added to give you more control over how leaf handles authentication in your apps. Auth has been configured perfectly for most apps, but not all use cases are the same, hence, this brilliant addition.
+
-This also includes various configurations for doing things like:
+Auth Config was added to give you more control over how leaf handles authentication in your apps. Leaf Auth has been configured perfectly for most apps, but not all use cases are the same, hence, this brilliant addition.
-- Setting custom token lifetime
+This includes various configurations for doing things like:
+
+- Configuring tokens
- Hiding/Showing user fields
- Adding/removing default timestamps
- Changing the default password key
-- Setting custom password encode methods
-- Turning off password encoding totally
-- Setting custom password verify methods
-- Hiding/Showing password field
+- Password encoding and verification
- Adding custom validation messages
-- Configuring tokens
-## config
+## Setting config values
To set a config variable, you can simply call the `config` method.
@@ -23,7 +21,7 @@ To set a config variable, you can simply call the `config` method.
```php
$auth = new Leaf\Auth;
-$auth->config("item", "value");
+$auth->config('item', 'value');
```
@@ -31,7 +29,7 @@ $auth->config("item", "value");
```php
-auth()->config("item", "value");
+auth()->config('item', 'value');
```
@@ -42,8 +40,8 @@ You can also pass in an array to set multiple configs at once:
```php
$auth->config([
- "item" => "value",
- "item2" => "value"
+ 'item' => 'value',
+ 'item2' => 'value'
]);
```
@@ -53,19 +51,18 @@ $auth->config([
```php
auth()->config([
- "item" => "value",
- "item2" => "value"
+ 'item' => 'value',
+ 'item2' => 'value'
]);
```
-## Settings
+## Database Config
-Below is a list of all available settings.
+Leaf Auth uses a database to store and retrieve users. It has been configured to work with common setups, but you can change the database config to suit your needs.
### DB_TABLE
-
The `DB_TABLE` config allows you to set a particular table which leaf auth will perform operations on. Leaf auth will use this database table for storing and retrieving users. By default, it is set to `users`. This allows you to login, signup, update and fetch users without explicitly adding a table each time.
@@ -76,164 +73,193 @@ This determines whether Leaf should add the default `created_at` and `updated_at
### TIMESTAMP_FORMAT
If you set `USE_TIMESTAMPS` to `true` you can then use this property to specify the format that you want your timestamps to be saved in.
-Be aware that `auth` uses the `leafs/date` module, so the accepted formats are listed here: https://leafphp.dev/modules/date/#display
+Be aware that `auth` uses the `leafs/date` module, so the accepted formats are listed [here](/modules/date/#display)
-### PASSWORD_ENCODE
+### PASSWORD_KEY
-*This setting has gone through a lot of changes since v2.4 beta, and may not work exactly the same way*. This setting is run when leaf wants to encode a password. It now uses `PASSWORD_DEFAULT` by defaullt for encryption.
+This allows you to change the password field name, maybe yours is passcode? This tells leaf to look for a user's password in that field. The example below tells leaf to search for passwords in the `passcode` column. (the default field is password)
-
+```php
+auth()->config('PASSWORD_KEY', 'passcode');
+```
-
-
-
-
```php
-// This turns off password encoding
-auth()->config("PASSWORD_ENCODE", false);
-
-// defult encoding (Leaf\Helpers\Password::hash)
-auth()->config("PASSWORD_ENCODE", null);
-
-// use md5. We're still keeping support for md5 :-)
-auth()->config("PASSWORD_ENCODE", Password::MD5);
-
-// use custom method
-auth()->config("PASSWORD_ENCODE", function ($password) {
- return Password::hash($password);
-});
+auth()->config('PASSWORD_KEY', 'passcode');
```
-### PASSWORD_VERIFY
+
-This setting is called when Leaf tries to verify a password. It works just like `PASSWORD_ENCODE` above.
+### ID_KEY
-
+`ID_KEY` allows you to set your primary key name. For instance, you might have used `_id` instead of `id`. This setting allows you to quickly and effectively switch your key name.
+
+```php
+$auth->config('ID_KEY', '_id');
+```
-
-
+```php
+auth()->config('ID_KEY', '_id');
+```
-```php
-// This turns off password encoding
-auth()->config("PASSWORD_VERIFY", false);
+### USE_UUID
-// defult encoding (Leaf\Helpers\Password::hash)
-auth()->config("PASSWORD_VERIFY", null);
+This simply allows you to set the value for user ids on your own. This is done in order to add support for UUIDs in your registrations and not go with the default SQL increments.
-// use md5. We're still keeping support for md5 :-)
-auth()->config("PASSWORD_VERIFY", Password::MD5);
+
-// use custom method
-auth()->config("PASSWORD_VERIFY", function ($password) {
- return Password::verify($password);
-});
+```php
+$auth->config('USE_UUID', UUID::v4());
```
-### PASSWORD_KEY
-
-This allows you to change the password field name, maybe yours is passcode? This tells leaf to look for a user's password in that field. The example below tells leaf to search for passwords in the `passcode` column. (the default field is password)
-
-
-
+
+
+```php
+auth()->config('USE_UUID', UUID::v4());
+```
-
+## Password Encoding
+These configuration options control how Leaf Auth encodes and verifies passwords. Leaf Auth uses `PASSWORD_DEFAULT` to encode passwords and `PASSWORD_VERIFY` to verify passwords.
+### PASSWORD_ENCODE
-
+This setting is used when leaf wants to encode a password. It uses the `Leaf\Helpers\Password::hash` method by default, but you can change this to suit your needs. It accepts these values:
-```php
-auth()->config("PASSWORD_KEY", "passcode");
-```
+- `false` - This turns off password encoding
+- `null` - This uses the default encoding method (Leaf\Helpers\Password::hash)
+- `Password::MD5` - This uses md5. We're still keeping support for md5 :-) (Leaf\Helpers\Password::MD5)
+- `function` - This uses a custom method. The method should accept a password and return the encoded password.
-### ID_KEY
+
-`ID_KEY` allows you to set your primary key name. For instance, you might have used `_id` instead of `id`. This setting allows you to quickly and effectively switch your key name.
+```php
+$auth->config('PASSWORD_ENCODE', false);
-
+$auth->config('PASSWORD_ENCODE', null);
+$auth->config('PASSWORD_ENCODE', Password::MD5);
+$auth->config('PASSWORD_ENCODE', function ($password) {
+ return Password::hash($password);
+});
+```
+```php
+auth()->config('PASSWORD_ENCODE', false);
+auth()->config('PASSWORD_ENCODE', null);
-
+auth()->config('PASSWORD_ENCODE', Password::MD5);
-```php
-auth()->config("ID_KEY", "_id");
+auth()->config('PASSWORD_ENCODE', function ($password) {
+ return Password::hash($password);
+});
```
-### USE_UUID
+
-This simply allows you to set the value for user ids on your own. This is done in order to add support for UUIDs in your registrations and not go with the default SQL increments.
+### PASSWORD_VERIFY
+
+This setting is used by Leaf Auth to verify whether a password is correct. It uses the `Leaf\Helpers\Password::verify` method by default, but you can change this to suit your needs. It accepts these values:
+
+- `false` - This turns off password verification
+- `null` - This uses the default verification method (Leaf\Helpers\Password::verify)
+- `Password::MD5` - This uses md5. We're still keeping support for md5 :-) (Leaf\Helpers\Password::MD5)
+- `function` - This uses a custom method. The method should accept a password and return the encoded password.
+
+This setting is called when Leaf tries to verify a password. It works just like `PASSWORD_ENCODE` above.
+```php
+$auth->config('PASSWORD_VERIFY', false);
+
+$auth->config('PASSWORD_VERIFY', null);
+$auth->config('PASSWORD_VERIFY', Password::MD5);
+
+$auth->config('PASSWORD_VERIFY', function ($password) {
+ return Password::verify($password);
+});
+```
+```php
+auth()->config('PASSWORD_VERIFY', false);
+auth()->config('PASSWORD_VERIFY', null);
-
+auth()->config('PASSWORD_VERIFY', Password::MD5);
-```php
-auth()->config("USE_UUID", UUID::v4());
+auth()->config('PASSWORD_VERIFY', function ($password) {
+ return Password::verify($password);
+});
```
+
+
+## Special Config
+
+These configuration options control special features of Leaf Auth.
+
### HIDE_ID
This is a boolean which determines whether to hide the id in the user object returned on login/register. Default is `true`.
### AUTH_NO_PASS
-This allows you to *manually* tell leaf auth that no password is required for authentication. When this is set to true, leaf auth will assume there is no password and act accordingly. If there is no password field set in the credentials passed into the `login` or `register` methods, leaf auth will automatically set this to `true`.
+This allows you to _manually_ tell leaf auth that no password is required for authentication. When this is set to true, leaf auth will assume there is no password and act accordingly. If there is no password field set in the credentials passed into the `login` or `register` methods, leaf auth will automatically set this to `true`.
### HIDE_PASSWORD
Just as the name implies, allows you to hide or show the password in the final results returned from auth. Default is `true`.
+## Error Message Config
+
+These configuration options control the error messages returned by Leaf Auth. You can change these to suit your needs.
+
### LOGIN_PARAMS_ERROR
This is the error to show if there's an error with any parameter which isn't the password eg: username:
-
+```php
+$auth->config('LOGIN_PARAMS_ERROR', 'Username is incorrect!');
+```
-
-
-
-
-
```php
-auth()->config("LOGIN_PARAMS_ERROR", "Username is incorrect!");
+auth()->config('LOGIN_PARAMS_ERROR', 'Username is incorrect!');
```
+
+
Default is `Incorrect credentials!`.
### LOGIN_PASSWORD_ERROR
@@ -244,19 +270,23 @@ Default is `Password is incorrect!`.
-
+```php
+$auth->config('LOGIN_PASSWORD_ERROR', 'Password is incorrect!');
+```
-
+```php
+auth()->config('LOGIN_PASSWORD_ERROR', 'Password is incorrect!');
+```
-```php
-auth()->config("LOGIN_PASSWORD_ERROR", "Password is incorrect!");
-```
+## Session Config
+
+These configuration options control how Leaf Auth handles sessions. You can change these to suit your needs.
### USE_SESSION
@@ -264,7 +294,11 @@ Use session based authentication instead of the default JWT based auth. Without
### SESSION_ON_REGISTER
-If true, a session will be created on a successful registration, else you it'll be created on login rather. Default is `false`.
+If set to `true`, a session will be created on a successful registration. If set to `false`, sessions will only be created when a user successfully logs into their account. The default value for this config is `false`.
+
+### SESSION_REDIRECT_ON_LOGIN
+
+This configuration option determins whether to redirect to a page after login. When set to `true`, the options set in `GUARD_LOGIN`, `GUARD_REGISTER` and `GUARD_HOME` will be used to redirect the user to the right page based on their state. Default is `true`.
### GUARD_LOGIN
@@ -282,10 +316,30 @@ Logout route handler. Default is `/auth/logout`.
Home page route. Default is `/home`.
+### SESSION_LIFETIME
+
+This option allows you to set the lifetime of the session. After this time, the session will expire and the user will have to login again. Default is `1 day`. You can also set `SESSION_LIFETIME` to `0` to disable session expiration.
+
+### SESSION_COOKIE_PARAMS
+
+This option allows you to set the cookie params for the session. These are the defaults set for you:
+
+```php
+[
+ 'secure' => true,
+ 'httponly' => true,
+ 'samesite' => 'lax'
+]
+```
+
### SAVE_SESSION_JWT
Add an auth token to the auth session? This allows you save a generated JWT to the session. You might want to use this if you want to extend your app into an API. Default is `false`.
+## Token Config
+
+These configuration options control how Leaf Auth handles tokens. You can change these to suit your needs.
+
### TOKEN_LIFETIME
How long the token can be used before it expires. Default is 1 day.
diff --git a/src/modules/auth/index.md b/src/modules/auth/index.md
index 04daa6de..45479447 100755
--- a/src/modules/auth/index.md
+++ b/src/modules/auth/index.md
@@ -1,13 +1,12 @@
# Authentication
+
Numerous web applications offer their users a means to authenticate and access the application by "logging in." Adding this functionality to web applications can be a challenging and potentially dangerous task. For this reason, Leaf provides a lightweight but very powerful authentication system known as Leaf Auth.
-Leaf Auth gives you clean and simple functions to handle complex authentication flows in a few lines of code. Leaf auth is customizable to the core and allows for a bunch of configuration options that determine how it handles authentication in general.
+Leaf Auth gives you clean and simple functions to handle complex authentication flows in a few lines of code. It is customizable to the core and allows for a bunch of configuration options that determine how it handles authentication in general.
-::: tip Note that
-You can still handle authentication without using Leaf Auth. The idea behind Leaf Auth is to make authentication simpler.
-:::
+You can still handle authentication without using Leaf Auth, however, Leaf Auth is a more secure and reliable way to handle authentication in your apps.
## Installing Leaf Auth
@@ -79,14 +78,14 @@ auth()->config('DB_TABLE', 'admins');
After installing leaf auth, you would need to connect to a database. Leaf auth will search for users and add/update users in this database when a login/register or update operation is called. There are a couple of ways to connect to a database with leaf auth.
-### connect
+### Manual Connection
-The connect method allows you to pass in your database connection parameters directly to leaf auth.
+Leaf Auth provides a `connect()` method that allows you to connect to your database by passing in your database connection parameters. This is the most basic and straightforward way to connect to your database.
```php
-$auth = new Leaf\Auth;
+$auth = new \Leaf\Auth;
// syntax
$auth->connect(
@@ -119,9 +118,9 @@ auth()->connect('127.0.0.1', 'dbname', 'root', '');
-### autoConnect
+### Auto Connect
-This method allows you to connect to your database from parameters in a `.env` file. Most MVC frameworks and other libraries rely on a `.env` for a lot of configurations including the database. With `autoConnect`, you can directly pick up these configs.
+Leaf Auth comes with an `autoConnect()` method that allows you to connect to your database using your environment variables. Most MVC frameworks and other libraries rely on a `.env` file for a lot of configuration including the database. With `autoConnect`, you can directly pick up these configs and create a connection from them.
**example env:**
@@ -134,7 +133,7 @@ DB_USERNAME=root
DB_PASSWORD=
```
-**App:**
+Based on the example above, you can connect to your database using:
@@ -202,10 +201,6 @@ auth()->dbConnection(db()->connection());
If you are using leaf auth in a leaf 3 app, you will have access to the auth global as shown in some of the above connections. Along with this, if you already have a leaf db connection, you no longer need to explicitly connect to your database. Leaf auth searches for a leaf db instance and connects to it automatically.
-::: warning Note
-This only works in a leaf 3 app and only if you already have a leaf db connection.
-:::
-
```php
-
+
Auth Config
Configure leaf auth to meet your needs.
-
+
Auth Methods
Docs on all the methods provided in Leaf Auth
-
+
Auth Sessions
Session support with Leaf Auth.
diff --git a/src/modules/auth/login.md b/src/modules/auth/login.md
index 2fabeaed..45d12604 100644
--- a/src/modules/auth/login.md
+++ b/src/modules/auth/login.md
@@ -14,6 +14,8 @@ Leaf Auth provides two authentication systems:
- Token based authentication
- Session based authentication
+These two systems are very similar, the only difference is that token based authentication uses tokens to authenticate users while session based authentication uses sessions to authenticate users. *Token based auth is used by default, but you can switch to session based authentication using the [Auth Config](/modules/auth/config#use-session).*
+
### Token based authentication
Token based authentication is a system where a user is given a token upon login. This token is then used to authenticate the user on every request. This is the most common authentication system for APIs.
@@ -40,10 +42,6 @@ Session based authentication is a system where a user is given a session upon lo
/>
-::: tip Defaults
-Token based auth is used by default, but you can switch to session based authentication using the [Auth Config](/modules/auth/config#use-session).
-:::
-
## The login method
Leaf auth provides a `login()` method used to authenticate users and create a session or token for them. The `login()` method takes in an array of data you want to use to authenticate the user. This data is usually the user's email and password.
@@ -78,12 +76,12 @@ If the user is authenticated, a session or token is created for them and the use
```php
$auth = new Leaf\Auth;
-$user = $auth->login([
+$data = $auth->login([
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -95,12 +93,12 @@ if ($user) {
```php
-$user = auth()->login([
+$data = auth()->login([
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -115,12 +113,12 @@ To get the reason why the user is not authenticated, you can use the `errors()`
```php{11}
$auth = new Leaf\Auth;
-$user = $auth->login([
+$data = $auth->login([
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -133,12 +131,12 @@ if ($user) {
```php{10}
-$user = auth()->login([
+$data = auth()->login([
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -152,16 +150,17 @@ If the authentication was successful, the user is returned. You can use this to
-```php{9}
+```php{9,10}
$auth = new Leaf\Auth;
-$user = $auth->login([
+$data = $auth->login([
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
- $userToken = $user['token'];
+ $token = $data['token'];
+ $user = $data['user'];
} else {
// user is not authenticated
$errors = $auth->errors();
@@ -172,15 +171,16 @@ if ($user) {
-```php{8}
-$user = auth()->login([
+```php{8,9}
+$data = auth()->login([
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
- $userToken = $user['token'];
+ $token = $data['token'];
+ $user = $data['user'];
} else {
// user is not authenticated
$errors = auth()->errors();
@@ -256,7 +256,7 @@ auth()->useSession();
-Just like with token based authentication, you can use the `login()` method to authenticate users. The only difference is that the `login()` method redirects you to a route defined as `GUARD_HOME` in your auth config.
+Just like with token based authentication, you can use the `login()` method to authenticate users. The only difference is that the `login()` method creates a session for your user instead of just returning the user info and a token. It also automatically redirects you to a route defined as `GUARD_HOME` if you have the `SESSION_REDIRECT_ON_LOGIN` config set to `true`.
@@ -267,16 +267,16 @@ $auth->useSession();
$auth->config('GUARD_HOME', '/home');
// will automatically redirect to /home if successful
-$user = $auth->login([
- 'email' => 'm@example.com',
- 'password' => 'password'
+$data = $auth->login([
+ 'email' => $email,
+ 'password' => $password,
]);
-if (!$user) {
+if (!$data) {
// you can pass the auth errors into a view
return $template->render('pages.auth.login', [
'errors' => auth()->errors(),
- 'username' => $username,
+ 'email' => $email,
'password' => $password,
]);
}
@@ -310,6 +310,74 @@ if (!$user) {
For more information on session based authentication, check out the [session based authentication](/modules/auth/session) page.
+## Session lifetime
+
+Session lifetime is the amount of time a session is valid for. This is usually set to a few minutes or hours. Leaf Auth allows you to set the session lifetime using the `SESSION_LIFETIME` config. This config is set to `1 day` by default.
+
+You can set the session lifetime using seconds or a string that can be parsed by the [PHP `strtotime()`](https://www.php.net/manual/en/function.strtotime.php) function.
+
+
+
+```php
+$auth = new Leaf\Auth;
+
+$auth->config('SESSION_LIFETIME', '1 hour');
+$auth->config('SESSION_LIFETIME', 3600);
+```
+
+
+
+
+
+```php
+auth()->config('SESSION_LIFETIME', '1 hour');
+auth()->config('SESSION_LIFETIME', 3600);
+```
+
+
+
+If you set the session lifetime to `0`, the session will never expire.
+
+
+
+```php
+$auth = new Leaf\Auth;
+
+$auth->config('SESSION_LIFETIME', 0);
+```
+
+
+
+
+
+```php
+auth()->config('SESSION_LIFETIME', 0);
+```
+
+
+
+## Token lifetime
+
+Token lifetime is the amount of time a token is valid for. This is usually set to a few minutes or hours. Leaf Auth allows you to set the token lifetime using the `TOKEN_LIFETIME` config.
+
+
+
+```php
+$auth = new Leaf\Auth;
+
+$auth->config('TOKEN_LIFETIME', 3600);
+```
+
+
+
+
+
+```php
+auth()->config('TOKEN_LIFETIME', 3600);
+```
+
+
+
## Password Encoding
Leaf Auth uses the [Leaf Password Helper](/modules/password/) to encode passwords. It supports the most popular password encoding algorithms including `bcrypt`, `argon2i` and `md5`. You can still use your own password encoder by updating the [`PASSWORD_VERIFY`](/modules/auth/config.html#password-verify) config.
diff --git a/src/modules/auth/mvc.md b/src/modules/auth/mvc.md
new file mode 100644
index 00000000..d58865c5
--- /dev/null
+++ b/src/modules/auth/mvc.md
@@ -0,0 +1,17 @@
+# Usage with Leaf MVC
+
+Leaf MVC and Leaf API both come with built-in support for Leaf Auth. This means you can skip the initial setup and get right into using Leaf Auth. To get started, head over to your `public/index.php` file and uncomment the following line:
+
+```php
+\Leaf\Database::initDb();
+```
+
+This will allow Leaf Auth to use your database connection set up in your `.env` file. If you don't have a database connection set up, you can set one up by following the [Leaf MVC Database docs](/docs/leafmvc/).
+
+## Auth config
+
+Once your database connection is set up, you can pretty much start using Leaf Auth. However, you can also set up your auth config in your `config/auth.php` file. This allows you to control Leaf Auth's behaviour. You can find a list of all available config options [here](/modules/auth/config).
+
+## Usage
+
+From this point on, you can use Leaf Auth as you would normally. You can find the full docs [here](/modules/auth/).
diff --git a/src/modules/auth/session.md b/src/modules/auth/session.md
index 62bdc417..6de48fed 100644
--- a/src/modules/auth/session.md
+++ b/src/modules/auth/session.md
@@ -1,8 +1,10 @@
# Session support
+
+
We've covered session support and it's use in various techniques like login, register, etc. But there are still a bunch of session auth methods that we haven't covered yet. Let's get into them.
-## Enabling session support
+## Enabling sessions
To get started with session support, just set the `USE_SESSION` config to true.
diff --git a/src/modules/auth/signup.md b/src/modules/auth/signup.md
index 537ae48c..7f4f4ee3 100644
--- a/src/modules/auth/signup.md
+++ b/src/modules/auth/signup.md
@@ -14,6 +14,8 @@ Leaf Auth provides two authentication systems:
- Token based authentication
- Session based authentication
+These two systems are very similar, the only difference is that token based authentication uses tokens to authenticate users while session based authentication uses sessions to authenticate users. *Token based auth is used by default, but you can switch to session based authentication using the [Auth Config](/modules/auth/config#use-session).*
+
### Token based authentication
Token based authentication is a system where a user is given a token upon login. This token is then used to authenticate the user on every request. This is the most common authentication system for APIs.
@@ -78,13 +80,13 @@ This example creates a new user with the username `example`, email `m@example.co
```php
$auth = new Leaf\Auth;
-$user = $auth->register([
+$data = $auth->register([
'username' => 'example',
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -96,13 +98,13 @@ if ($user) {
```php
-$user = auth()->register([
+$data = auth()->register([
'username' => 'example',
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -117,13 +119,13 @@ To get the reason why the user is not authenticated, you can use the `errors()`
```php{12}
$auth = new Leaf\Auth;
-$user = $auth->register([
+$data = $auth->register([
'username' => 'example',
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -136,13 +138,13 @@ if ($user) {
```php{11}
-$user = auth()->register([
+$data = auth()->register([
'username' => 'example',
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -156,17 +158,18 @@ If the authentication was successful, the user is returned. You can use this to
-```php{10}
+```php{10,11}
$auth = new Leaf\Auth;
-$user = $auth->register([
+$data = $auth->register([
'username' => 'example',
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
- $userToken = $user['token'];
+ $token = $data['token'];
+ $user = $data['user'];
} else {
// user is not authenticated
$errors = $auth->errors();
@@ -177,16 +180,17 @@ if ($user) {
-```php{9}
-$user = auth()->register([
+```php{9,10}
+$data = auth()->register([
'username' => 'example',
'email' => 'm@example.com',
'password' => 'password'
]);
-if ($user) {
+if ($data) {
// user is authenticated
- $userToken = $user['token'];
+ $token = $data['token'];
+ $user = $data['user'];
} else {
// user is not authenticated
$errors = auth()->errors();
@@ -203,13 +207,13 @@ The `register()` method takes in a list of items that should be unique to users.
```php{12}
$auth = new Leaf\Auth;
-$user = $auth->register([
+$data = $auth->register([
'username' => 'example',
'email' => 'm@example.com',
'password' => 'password'
], ['username', 'email']);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -222,13 +226,13 @@ if ($user) {
```php{11}
-$user = auth()->register([
+$data = auth()->register([
'username' => 'example',
'email' => 'm@example.com',
'password' => 'password'
], ['username', 'email']);
-if ($user) {
+if ($data) {
// user is authenticated
} else {
// user is not authenticated
@@ -315,7 +319,7 @@ auth()->useSession();
-Just like with token based authentication, you can use the `register()` method to authenticate users. The only difference is that the `register()` method redirects you to a route defined as `GUARD_HOME` in your auth config.
+Just like with token based authentication, you can use the `register()` method to authenticate users. The only difference is that the `register()` method redirects you to a route defined as `GUARD_HOME` with a new session or redirects to `GUARD_LOGIN` if you have the `SESSION_ON_REGISTER` config set to `false`.
diff --git a/src/modules/cookies/index.md b/src/modules/cookies/index.md
index f9963288..c0bd2a7d 100755
--- a/src/modules/cookies/index.md
+++ b/src/modules/cookies/index.md
@@ -1,7 +1,14 @@
# Leaf Cookie
+
-This is a module which helps you create, interact with and manage your cookies. You can quickly install leaf cookies with composer or leaf cli.
+Cookies are small pieces of text sent to a client's browser by your application. They help your app remember information about users' visits, which can both make it easier to visit your app and make it more useful to your users.
+
+The cookie module helps you create, interact with and manage your cookies.
+
+## Installation
+
+You can quickly install leaf cookies with composer or leaf cli.
```bash
leaf install cookies
@@ -17,37 +24,38 @@ composer require leafs/cookies
-### Functional mode
-
-
-Leaf cookie also hooks into leaf 3's functional mode. If you are using leaf 3, then this is the fastest way to use the cookie class.
-
-#### cookie
-
-Cookie is a global method that can be used to return the cookie object:
+Right after installing the cookie module, you can start using it on the `cookie()` method like this:
```php
-cookie()->unsetAll();
+cookie()->set('name', 'Fullname');
```
-### Leaf Cookie Class
-
Leaf cookie provides a `Leaf\Http\Cookie` class for quickly using cookie methods:
```php
use Leaf\Http\Cookie;
-// ...
-Cookie::set("name", "Michael");
+
+...
+
+Cookie::set('name', 'Fullname');
```
-## Set
+## Setting Cookies
+
+The cookie module provides 3 methods for setting cookies:
-This method replaces the previous `setCookie` method. It takes in 3 params:
+- `set()`
+- `simpleCookie()`
+- `response()->withCookie`
+
+### Set
+
+This method allows you to set a cookie which should be returned with your next response to the client. It takes in 3 params:
- cookie name (string|array)
- cookie value (optional - string)
@@ -57,10 +65,10 @@ This method replaces the previous `setCookie` method. It takes in 3 params:
```php
// normal method
-cookie()->set("name", "Michael");
+cookie()->set('name', 'Fullname');
// using array
-cookie()->set(["name" => "Michael"]);
+cookie()->set(['name' => 'Fullname']);
```
@@ -68,10 +76,10 @@ cookie()->set(["name" => "Michael"]);
```php
// normal method
-Cookie::set("name", "Michael");
+Cookie::set('name', 'Fullname');
// using array
-Cookie::set(["name" => "Michael"]);
+Cookie::set(['name' => 'Fullname']);
```
@@ -82,8 +90,8 @@ You can also set multiple cookies at a time
```php
cookie()->set([
- "name" => "Michael",
- "age" => "18"
+ 'name' => 'Fullname',
+ 'age' => '18'
]);
```
@@ -92,26 +100,26 @@ cookie()->set([
```php
Cookie::set([
- "name" => "Michael",
- "age" => "18"
+ 'name' => 'Fullname',
+ 'age' => '18'
]);
```
-Adding cookie options
+Cookies can also be set with options. These options allow you to set the cookie's expiry time, path, domain, secure and httponly. They determine how long the cookie should last and who should have access to it.
```php
-cookie()->set("name", "Michael", ["expire" => 0]);
+cookie()->set('name', 'Fullname', ['expire' => 0]);
```
```php
-Cookie::set("name", "Michael", ["expire" => 0]);
+Cookie::set('name', 'Fullname', ['expire' => 0]);
```
@@ -124,7 +132,7 @@ Options for cookies are:
- secure
- httponly
-## simpleCookie
+### simpleCookie
This method allows you to quickly set a cookie and it's expiry time. It takes in 3 params:
@@ -135,79 +143,142 @@ This method allows you to quickly set a cookie and it's expiry time. It takes in
```php
-cookie()->simpleCookie("name", "Michael", "2 days");
+cookie()->simpleCookie('name', 'Fullname', '2 days');
```
```php
-Cookie::simpleCookie("name", "Michael", "2 days");
+Cookie::simpleCookie('name', 'Fullname', '2 days');
```
-## all
+### response()->withCookie
+
+This method allows you to set a cookie directly on the response object. It takes in 3 params:
-`all` returns all set cookies.
+- cookie name (string)
+- cookie value (string)
+- cookie expiresAt (optional - string - default of 7 days)
```php
-$cookies = cookie()->all();
+response()->withCookie('name', 'Fullname', '2 days')->json([
+ 'message' => 'Cookie set'
+]);
```
```php
-$cookies = Cookie::all();
+$app
+ ->response
+ ->withCookie('name', 'Fullname', '2 days')
+ ->json([
+ 'message' => 'Cookie set'
+ ]);
```
-## get
+## Getting Cookies
-`get` returns a particular set cookie
+Just as you can set cookies, you can also get them from the client. The cookie module provides 2 methods for retrieve cookies:
+
+- `get()`
+- `all()`
+
+### get
+
+`get()` returns a particular set cookie
```php
-$name = cookie()->get("name");
+$name = cookie()->get('name');
```
```php
-$name = Cookie::get("name");
+$name = Cookie::get('name');
```
-## unset
+### all
-This method replaces the previous `deleteCookie` method. It takes in the cookie to unset.
+`all()` returns all set cookies.
```php
-// normal method
-cookie()->unset("name");
+$cookies = cookie()->all();
+```
-// using array
-cookie()->unset(["name"]);
+
+
+
+```php
+$cookies = Cookie::all();
+```
+
+
+
+## Deleting Cookies
+
+The cookie module provides 3 methods for deleting cookies:
+
+- `response()->withoutCookie()`
+- `unset()`
+- `unsetAll()`
+
+### response()->withoutCookie
+
+This method allows you to delete a cookie directly on the response object. It takes in 1 param which is the cookie to delete.
+
+
+
+```php
+response()->withoutCookie('name')->json([
+ 'message' => 'Cookie deleted'
+]);
```
```php
-// normal method
-Cookie::unset("name");
+$app
+ ->response
+ ->withoutCookie('name')
+ ->json([
+ 'message' => 'Cookie deleted'
+ ]);
+```
-// using array
-Cookie::unset(["name"]);
+
+
+### unset
+
+This method allows you to delete a cookie that was previously set. It takes in the cookie to unset.
+
+
+
+```php
+cookie()->unset('name');
+```
+
+
+
+
+```php
+Cookie::unset('name');
```
@@ -217,19 +288,19 @@ You can also unset multiple cookies at a time
```php
-cookie()->unset(["name", "age"]);
+cookie()->unset(['name', 'age']);
```
```php
-Cookie::unset(["name", "age"]);
+Cookie::unset(['name', 'age']);
```
-## unsetAll
+### unsetAll
This method removes all set cookies.
diff --git a/src/modules/cors/index.md b/src/modules/cors/index.md
index b91b6bda..4951cd5b 100755
--- a/src/modules/cors/index.md
+++ b/src/modules/cors/index.md
@@ -1,11 +1,26 @@
-
# CORS
-::: tip Note
-In Leaf v3, CORS now has its own module. You no longer have to patch in headers or use `evadeCors` which was pretty much a temporary patch.
-:::
+
+
+
+
+From Wikipedia, Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be accessed from another domain outside the domain from which the first resource was served.
+
+
+New to CORS?
+
+
+
-This is a module used to enable and configure [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) with various options. This module can be used both in and out of Leaf and so can be considered a general module. It is also inspired by the [ExpressJS](https://github.com/expressjs/express) [CORS package](https://github.com/expressjs/cors).
+## The CORS Module
+
+Since CORS is a common pain point for web developers, Leaf provides a simple way to deal with most CORS issues. Of course, you can always handle CORS manually, but this module just offers a more convenient and flexible way to do so. It is heavily inspired by the [ExpressJS](https://github.com/expressjs/express) [CORS package](https://github.com/expressjs/cors).
## Installation
@@ -21,9 +36,9 @@ or with composer
composer require leafs/cors
```
-## Basic Usage
+## Using the CORS Module
-After installing the cors module, Leaf automatically links it to your app, so it can be used directly without referencing it anywhere. To get started, simply call the `cors` method on the leaf instance.
+After installing the cors module, Leaf automatically links it to your app, so it can be used directly on the Leaf instance as the `cors()` method.
@@ -65,7 +80,9 @@ Leaf\Http\Cors::config([
:::
-### Simple Usage (Enable *All* CORS Requests)
+## Basic usage
+
+When you call `cors()` on your app, it enables CORS for all origins, headers and methods. This is the simplest way to enable CORS on your app.
@@ -99,7 +116,7 @@ app()->cors();
app()->get('/products/{id}', function () {
response()->json([
- "message" => "This is CORS-enabled for all origins!"
+ 'message' => 'This is CORS-enabled for all origins!'
]);
});
@@ -108,9 +125,7 @@ app()->run();
-You can alternatively call `Leaf\Http\Cors::config()` instead of `$app->cors()` in the example above.
-
-### Configuring CORS
+However, there are times when you might want to be more restrictive by allowing only some origins to access your app. You can do this by passing in an options array to the `cors()` method. This array allows you to configure specific origins, methods, headers, etc. For example, the following code shows how to allow a single origin (http://example.com) to access your app using the `origin` option:
@@ -126,13 +141,15 @@ $app->cors([
```php
app()->cors([
- "origin" => 'http://example.com',
- "optionsSuccessStatus" => 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
+ 'origin' => 'http://example.com',
+ 'optionsSuccessStatus' => 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
]);
```
+A full list of all the options available can be found below.
+
## Configuration Options
* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
diff --git a/src/modules/db/index.md b/src/modules/db/index.md
index 312630aa..ba5a113e 100755
--- a/src/modules/db/index.md
+++ b/src/modules/db/index.md
@@ -1,4 +1,5 @@
# Getting Started
+
-Modules are a new feature added in Leaf 3 which basically takes parts of Leaf and separates them into installable chunks which can be used both inside and outside of Leaf.
-
-Modules are framework/library agnostic, which means that they'll work just about everywhere with zero config just as with Leaf itself.
+Modules are the pieces of Leaf's functionality that are individually available as packages. They can be used in a wide variety of projects, and are one of the primary ways that Leaf is extended with additional functionality.
-Modules can be quickly installed through composer or the leaf CLI with a single command.
+Most modules are framework/library agnostic, which means that they'll work just about everywhere with zero config just as with Leaf itself. You can easily install them with composer or the leaf cli.
## Why modules?
-The biggest question people ask with Leaf 3 is why we decided to switch to modules, stripping leaf of almost all it's code.
+We have a ton of reasons for switching to modules that we covered in [this blog post](https://blog.leafphp.dev/posts/leaf3.html). However, here are a few of the main reasons:
-[@mychidarko](https://github.com/mychidarko) put an article together on why we decided to switch to modules instead of maintaining the whole code together. We also have a [GitHub discussion](https://github.com/leafsphp/leaf/discussions/70) introducing leaf 3 and everything you need to know about it, we explain modules further here.
+- Modules are easier to update and maintain
+- Modules allow you to use only the parts of Leaf you need
+- Modules allow you to incrementally upgrade your Leaf apps
+- Modules allow you to use Leaf with other frameworks
## Installing modules
@@ -25,15 +27,13 @@ The biggest question people ask with Leaf 3 is why we decided to switch to modul
link="https://www.youtube.com/embed/BTcUgeOZLyM"
/> -->
-Modules are always published on composer and can be installed through composer CLI or the leaf CLI.
-
-**Leaf CLI:**
+You can quickly install any module with the Leaf CLI:
```bash
leaf install
```
-**Composer:**
+Or with composer:
```bash
composer require leafs/
@@ -41,7 +41,7 @@ composer require leafs/
## List of available modules
-*This list is still being updated, you can keep checking for updates.*
+*We update this list whenever we add new modules, you can keep checking for updates.*
| Project | Status | Description |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
@@ -60,11 +60,11 @@ composer require leafs/
| [devtools](/modules/devtools/) | [![Latest Stable Version](https://poser.pugx.org/leafs/devtools/v/stable)](https://packagist.org/packages/leafs/devtools) [![Total Downloads](https://poser.pugx.org/leafs/devtools/downloads)](https://packagist.org/packages/leafs/devtools) | Developer tools for Leaf PHP |
| [eien](/modules/eien/) | [![Latest Stable Version](https://poser.pugx.org/leafs/eien/v/stable)](https://packagist.org/packages/leafs/eien) [![Total Downloads](https://poser.pugx.org/leafs/eien/downloads)](https://packagist.org/packages/leafs/eien) | High-speed, high-performance server for leaf |
| [exception](https://github.com/leafsphp/exceptions) | [![Latest Stable Version](https://poser.pugx.org/leafs/exception/v/stable)](https://packagist.org/packages/leafs/exception) [![Total Downloads](https://poser.pugx.org/leafs/exception/downloads)](https://packagist.org/packages/leafs/exception) | Leaf's exception wrapper (fork of whoops) |
-| [experiments](/modules/experiments/) | [![Latest Stable Version](https://poser.pugx.org/leafs/experimental/v/stable)](https://packagist.org/packages/leafs/experimental) [![Total Downloads](https://poser.pugx.org/leafs/experimental/downloads)](https://packagist.org/packages/leafs/experimental) | collection of experimental modules |
| [fetch](/modules/fetch/) | [![Latest Stable Version](https://poser.pugx.org/leafs/fetch/v/stable)](https://packagist.org/packages/leafs/fetch) [![Total Downloads](https://poser.pugx.org/leafs/fetch/downloads)](https://packagist.org/packages/leafs/fetch) | HTTP requests made simple |
| [form](/modules/forms/) | [![Latest Stable Version](https://poser.pugx.org/leafs/form/v/stable)](https://packagist.org/packages/leafs/form) [![Total Downloads](https://poser.pugx.org/leafs/form/downloads)](https://packagist.org/packages/leafs/form) | Form processes and validation |
| [fs](/modules/fs/) | [![Latest Stable Version](https://poser.pugx.org/leafs/fs/v/stable)](https://packagist.org/packages/leafs/fs) [![Total Downloads](https://poser.pugx.org/leafs/fs/downloads)](https://packagist.org/packages/leafs/fs) | Awesome filesystem operations + file uploads |
| [http](/modules/http/) | [![Latest Stable Version](https://poser.pugx.org/leafs/http/v/stable)](https://packagist.org/packages/leafs/http) [![Total Downloads](https://poser.pugx.org/leafs/http/downloads)](https://packagist.org/packages/leafs/http) | Http operations made simple (request, response, ...) |
+| [inertia](/modules/views/inertia/) | [![Latest Stable Version](https://poser.pugx.org/leafs/inertia/v/stable)](https://packagist.org/packages/leafs/inertia) [![Total Downloads](https://poser.pugx.org/leafs/inertia/downloads)](https://packagist.org/packages/leafs/inertia) | Leaf adapter for inertia JS |
| [logger](/modules/logger/) | [![Latest Stable Version](https://poser.pugx.org/leafs/logger/v/stable)](https://packagist.org/packages/leafs/logger) [![Total Downloads](https://poser.pugx.org/leafs/logger/downloads)](https://packagist.org/packages/leafs/logger) | leaf logger module |
| [mail](/modules/mail/) | [![Latest Stable Version](https://poser.pugx.org/leafs/mail/v/stable)](https://packagist.org/packages/leafs/mail) [![Total Downloads](https://poser.pugx.org/leafs/mail/downloads)](https://packagist.org/packages/leafs/mail) | Mailing made easy with leaf |
| [mvc-core](/modules/mvc-core/) | [![Latest Stable Version](https://poser.pugx.org/leafs/mvc-core/v/stable)](https://packagist.org/packages/leafs/mvc-core) [![Total Downloads](https://poser.pugx.org/leafs/mvc-core/downloads)](https://packagist.org/packages/leafs/mvc-core) | Core MVC tools powering our MVC wrappers |
@@ -75,3 +75,6 @@ composer require leafs/
| [tilly (WIP)](https://archive.leafphp.dev/#/tilly/) | [![Latest Stable Version](https://poser.pugx.org/leafs/tilly/v/stable)](https://packagist.org/packages/leafs/tilly) [![Total Downloads](https://poser.pugx.org/leafs/tilly/downloads)](https://packagist.org/packages/leafs/tilly) | Simple utility 'toolkit' for PHP applications |
| [veins](/modules/views/veins/) | [![Latest Stable Version](https://poser.pugx.org/leafs/veins/v/stable)](https://packagist.org/packages/leafs/veins) [![Total Downloads](https://poser.pugx.org/leafs/veins/downloads)](https://packagist.org/packages/leafs/veins) | Leaf veins templating engine |
| [viewi](/modules/views/viewi/) | [![Latest Stable Version](https://poser.pugx.org/leafs/viewi/v/stable)](https://packagist.org/packages/leafs/viewi) [![Total Downloads](https://poser.pugx.org/leafs/viewi/downloads)](https://packagist.org/packages/leafs/viewi) | Leaf integration with Viewi PHP |
+| [vite](/modules/views/vite/) | [![Latest Stable Version](https://poser.pugx.org/leafs/vite/v/stable)](https://packagist.org/packages/leafs/vite) [![Total Downloads](https://poser.pugx.org/leafs/vite/downloads)](https://packagist.org/packages/leafs/vite) | Leaf server component for Vite |
+
+
diff --git a/src/modules/mvc-core/api-controller.md b/src/modules/mvc-core/api-controller.md
index 18f1b37c..37e23231 100755
--- a/src/modules/mvc-core/api-controller.md
+++ b/src/modules/mvc-core/api-controller.md
@@ -12,7 +12,7 @@ Below is an example of a basic API controller class. Note that the controller ex
respond([
- "message" => "hello"
+ 'message' => 'hello'
]);
}
}
@@ -74,11 +74,11 @@ use Leaf\Controller;
class NameController extends Controller {
public function index() {
- $profilePic = $_FILES["profile_pic"];
+ $profilePic = $_FILES['profile_pic'];
// file upload
- $this->file_upload("./images/", $profilePic);
+ $this->file_upload('./images/', $profilePic);
// file upload with file type
- $this->file_upload("./images/", $profilePic, "image");
+ $this->file_upload('./images/', $profilePic, 'image');
}
}
```
@@ -89,10 +89,10 @@ The base controller also gives you a simple way to handle form data
```php
public function index() {
- $name = $this->form->get("name");
+ $name = $this->form->get('name');
$this->validate([
- "name" => "text"
+ 'name' => 'text'
]);
}
```
diff --git a/src/modules/mvc-core/controller.md b/src/modules/mvc-core/controller.md
index abf9f114..534cd05c 100755
--- a/src/modules/mvc-core/controller.md
+++ b/src/modules/mvc-core/controller.md
@@ -12,7 +12,7 @@ Below is an example of a basic controller class. Note that the controller extend
veins->configure([
- "veins_dir" => "app/views/",
- "cache_dir" => "app/views/build/"
+ 'veins_dir' => 'app/views/',
+ 'cache_dir' => 'app/views/build/'
]);
}
public function index() {
// set template data
$this->set([
- "name" => "Mychi"
+ 'name' => 'Mychi'
]);
// render your template
- $this->render("index"); // refers to index.vein in the veins_dir
+ $this->render('index'); // refers to index.vein in the veins_dir
}
}
```
@@ -86,7 +86,7 @@ use Leaf\Controller;
class NameController extends Controller {
public function index() {
$this->respond([
- "message" => "hello"
+ 'message' => 'hello'
]);
}
}
@@ -103,11 +103,11 @@ use Leaf\Controller;
class NameController extends Controller {
public function index() {
- $profilePic = $_FILES["profile_pic"];
+ $profilePic = $_FILES['profile_pic'];
// file upload
- $this->file_upload("./images/", $profilePic);
+ $this->file_upload('./images/', $profilePic);
// file upload with file type
- $this->file_upload("./images/", $profilePic, "image");
+ $this->file_upload('./images/', $profilePic, 'image');
}
}
```
@@ -118,10 +118,10 @@ The base controller also gives you a simple way to handle form data
```php
public function index() {
- $name = $this->form->get("name");
+ $name = $this->form->get('name');
$this->validate([
- "name" => "text"
+ 'name' => 'text'
]);
}
```
diff --git a/src/modules/mvc-core/factories.md b/src/modules/mvc-core/factories.md
index a3fb98bc..b062a1d8 100755
--- a/src/modules/mvc-core/factories.md
+++ b/src/modules/mvc-core/factories.md
@@ -7,8 +7,6 @@ Instead of defining 100 dummy rows in your database 1 by 1, you can quickly popu
This version of Leaf comes with a nice integration with your models that allows you to create all the data you need in just a few lines of code.
-**Note that factories are used with models, and come default with Leaf API and Leaf MVC.**
-
## Working with factories
Just like with other Leaf modules, we try to make working with factories as simple as possible. A regular factory file looks something like this:
diff --git a/src/modules/mvc-core/index.md b/src/modules/mvc-core/index.md
index a6c2552f..3daff7c6 100644
--- a/src/modules/mvc-core/index.md
+++ b/src/modules/mvc-core/index.md
@@ -1,10 +1,6 @@
# MVC Core
-MVC core is a module that contains components for transforming leaf into a full-blown MVC framework. MVC Core is used in Leaf MVC, Leaf API and skeleton. It comes with features like controllers, models, eloquent from laravel, factories and more.
-
-::: tip Building with MVC
-If you want a pre-built MVC setup, we recommend checking out Leaf MVC or Leaf API which come with a ton of features in addition to those offered by Leaf and MVC core. You can checkout Skeleton if you want a basic MVC setup without any weird additions.
-:::
+MVC core is a module that contains components for transforming leaf into a full-blown MVC framework. MVC Core is used in Leaf MVC and Leaf API. It comes with features like controllers, models, eloquent from laravel, factories and more.
## Installation
@@ -22,9 +18,7 @@ leaf install mvc-core
## Config
-::: warning Note that
-Leaf MVC, Leaf API and skeleton are already configured out of the box. If you are using any of these setups, you can skip to the documentation for the component you need.
-:::
+Leaf MVC and Leaf API are already configured out of the box. If you are using any of these setups, you can skip to the documentation for the component you need.
## Autoloader
@@ -36,7 +30,7 @@ Leaf MVC Core comes in with two (2) controller classes. `Leaf\Controller` for cr
## Models
-Leaf MVC Core comes with a base model from which all models in your leaf API, leaf MVC and skeleton apps are created. This model is directly built unto [laravel's eloquent](https://laravel.com/docs/10.x/eloquent) and so we'll recommend checking out laravel models for detailed documentation. Models in your app will look something like this:
+Leaf MVC Core comes with a base model from which all models in your leaf API and leaf MVC apps are created. This model is directly built unto [laravel's eloquent](https://laravel.com/docs/10.x/eloquent) and so we'll recommend checking out laravel models for detailed documentation. Models in your app will look something like this:
```php
create(3)->get();
```
## Schema
-
-
-::: warning NOTE THAT
-Schema isn't compatible with Skeleton by default since it doesn't come with aloe cli.
-:::
Schema is a new way to create database migrations. Typing code for migrations the regular way is quite annoying: thinking of the types of data, setting default values and other items. `Schema` allows you to create migration schemas based on example JSON output.
@@ -207,22 +192,12 @@ class CreateUsers extends Database {
* @return void
*/
public function up() {
- Schema::build(static::$capsule, "/Schema/users.json");
+ Schema::build("users");
}
...
```
-In this case leaf will generate a migration to the users table since our filename is `users.json`. Note that leaf schema will always use the filename as the table name. You can go a different route by directly pasting your json into the build method. In that case, you will need to specify a table name.
-
-```php
-public function up() {
- Schema::build(static::$capsule, "users", json_encode([
- ...
- ]));
-}
-```
-
-You don't need to do anything after building your schema. Leaf will do the rest.
+In this case leaf will generate a migration to the users table since our filename is `users.json`. Note that leaf schema will always use the filename as the table name.
## Globals
@@ -234,7 +209,7 @@ Leaf MVC core comes with the most global functions in all of leaf. This includes
$paths = AppPaths();
```
-- **ConfigPath**: This global returns the path to your configuration folder in Leaf MVC, Leaf API or skeleton.
+- **ConfigPath**: This global returns the path to your configuration folder in Leaf MVC and Leaf API.
```php
$dbConfigFile = ConfigPath("db.php");
diff --git a/src/modules/password/index.md b/src/modules/password/index.md
index d72d4fc4..184bdb16 100755
--- a/src/modules/password/index.md
+++ b/src/modules/password/index.md
@@ -1,24 +1,23 @@
----
-title: "Password Helper"
----
+# Leaf Password
-# Leaf Password
+
+Password encoding and verification are one of the most important parts of any application. This usually involves a lot of security concerns and can be a pain to implement. Leaf makes this process a lot easier with the password helper.
This module simply helps create and manage passwords, encrypt and verify without any security concerns. It is fully static, as such, can be used from anywhere in your application.
## Installation
-You can quickly install a password helper through composer or the leaf cli
+You can quickly install a password helper through the leaf cli:
```bash
-composer require leafs/password
+leaf install password
```
-or
+or you can install it via composer:
```bash
-leaf install password
+composer require leafs/password
```
## spice
@@ -34,7 +33,7 @@ This sets the password spice which will be encrypted based on the hash you set:
```php
use Leaf\Helpers\Password;
-Password::spice("#@%7g0!&");
+Password::spice('#@%7g0!&');
```
**The next examples will assume you've added `use Leaf\Helpers\Password`**
@@ -47,7 +46,7 @@ $spice = Password::spice();
**Spices are automaticatically chained to all password related stuff, so after setting your spice, you don't need to worry about it.**
-## hash
+## `Password::hash()`
This method basically creates a password hash. It takes in 3 parameters:
@@ -56,7 +55,7 @@ This method basically creates a password hash. It takes in 3 parameters:
- An array of options for the password hash (optional)
```php
-$hash = Password::hash("USER_PASSWORD", Password::BCRYPT);
+$hash = Password::hash('USER_PASSWORD', Password::BCRYPT);
```
The default encryption hash used if none is provided is `Password::DEFAULT` which is `PASSWORD_DEFAULT`.
@@ -65,7 +64,7 @@ Also, the most commonly used hashes, BCRYPT and Argon2 are accessible on the Pas
The final options array differs based on the hash you're using. See the [password algorithm constants](https://secure.php.net/manual/en/password.constants.php) for documentation on the supported options for each algorithm.
-## verify
+## `Password::verify()`
Verifying a user’s password has been made really simple thanks to the `verify()` method. Simply pass the plaintext password supplied by the user and compare it to the stored hash, like so:
@@ -83,7 +82,7 @@ verify returns true on success and false on failure.
Argon2 is one encryption method heavily used by a lot of developers. Although creating and verifying passwords with argon2 is nothing difficult, Leaf makes it even simpler with methods targetting only argon.
-### argon2
+### `argon2()`
This is a simply method used to create an Argon2 hash for your password. It takes in 2 parameters, the password to encrypt and the options for the hashing.
@@ -93,7 +92,7 @@ $hash = Password::argon2($password, $options);
The options parameter is optional, but in case you want to set your own options, see the [password algorithm constants](https://secure.php.net/manual/en/password.constants.php) for documentation on the supported options for Argon2.
-### argon2Verify
+### `argon2Verify()`
This method simply checks the validity of an Argon2 hash.
@@ -107,7 +106,7 @@ if (Password::argon2Verify($password, $hashedPassword)) {
BCRYPT is another hash used widely by a lot of developers, especially since support with BCRYPT has been on longer than other hashes like Argon 2. We just make hashing with BCRYPT even easier than it currently is.
-### bcrypt
+### `bcrypt()`
This is a simply method used to create an BCRYPT hash for your password. It takes in 2 parameters, the password to encrypt and the options for the hashing.
@@ -117,7 +116,7 @@ $hash = Password::bcrypt($password, $options);
The options parameter is optional, but in case you want to set your own options, see the [password algorithm constants](https://secure.php.net/manual/en/password.constants.php) for documentation on the supported options for BCRYPT.
-### brcyptVerify
+### `brcyptVerify()`
This method simply checks the validity of an BCRYPT hash.
diff --git a/src/modules/router/errors.md b/src/modules/router/errors.md
index 15eebd79..fb9ca3e8 100755
--- a/src/modules/router/errors.md
+++ b/src/modules/router/errors.md
@@ -18,7 +18,7 @@ Router::set404(function () use($app) {
## Application Down
-Leaf router is also able to dynamically handle placing your application in maintainance mode using the `configure` method.
+Leaf router is also able to dynamically handle placing your application in maintenance mode using the `configure` method.
```php
Router::configure([
@@ -26,16 +26,16 @@ Router::configure([
]);
```
-Alternatively, you could also place your application in maintainance mode by setting the `APP_DOWN` environment variable to true. Since `.env` variables are given more priority than router config, the router config will be ignored as long as the env is set.
+Alternatively, you could also place your application in maintenance mode by setting the `APP_DOWN` environment variable to true. Since `.env` variables are given more priority than router config, the router config will be ignored as long as the env is set.
::: warning Note that
Leaf router expects you to manually load your `.env` file and will not be responsible for this. You can use [vlucas/phpdotenv](https://packagist.org/packages/vlucas/phpdotenv) to do this. After loading your `.env` variables into your app, leaf router will automatically pick them up.
:::
-Along with this, we have prepared a simple method to display a custom maintainance error page: `setDown`.
+Along with this, we have prepared a simple method to display a custom maintenance error page: `setDown`.
```php
Router::setDown(function () {
- echo "Down for maintainance";
+ echo "Down for maintenance";
});
```
diff --git a/src/modules/session/flash.md b/src/modules/session/flash.md
index a66d9400..20b54e17 100755
--- a/src/modules/session/flash.md
+++ b/src/modules/session/flash.md
@@ -19,13 +19,13 @@ Using the `config()` method, you can change where Leaf stores flash messages in
```php
flash()->config([
- "key" => "my_flash_items"
+ 'key' => 'my_flash_items'
]);
-flash()->set("This is my message");
+flash()->set('This is my message');
// logging $_SESSION
-=> ["my_flash_items" => ["message" => "This is my message"]]
+=> ['my_flash_items' => ['message' => 'This is my message']]
```
@@ -35,13 +35,13 @@ flash()->set("This is my message");
use Leaf\Flash;
Flash::config([
- "key" => "my_flash_items"
+ 'key' => 'my_flash_items'
]);
-Flash::set("This is my message");
+Flash::set('This is my message');
// logging $_SESSION
-=> ["my_flash_items" => ["message" => "This is my message"]]
+=> ['my_flash_items' => ['message' => 'This is my message']]
```
diff --git a/src/modules/views/bareui/index.md b/src/modules/views/bareui/index.md
index 3a2f5261..aa81386d 100644
--- a/src/modules/views/bareui/index.md
+++ b/src/modules/views/bareui/index.md
@@ -2,8 +2,25 @@
+
+
Most templating engines out there ship with a nice syntax, handy ways to use expressions, layouts and code blocks, however, there's one problem: speed! Bare UI is here to solve that. Bare UI is a barebones templating engine focused on speed, speed and more speed! It lacks all the syntactic sugar added in other engines like blade, but it also requires no compiling, no caching, just speed!
+
+New to template engines?
+
+Watch this video by Dave Hollingworth as an introduction to template engines.
+
+
+
+
## Installation
You can always install BareUI with the Leaf CLI:
@@ -18,6 +35,16 @@ Or with composer:
composer require leafs/bareui
```
+## Usage with Leaf MVC
+
+Leaf MVC and Leaf API come with [Leaf Blade](/modules/views/blade/) out of the box, however, since Leaf is modular at it's core, Leaf MVC and Leaf API allow you easily swap out the blade engine for BareUI (or any other view engine). To do this, you need to swap out the blade engine in your `public/index.php` and `config/view.php` files:
+
+```php
+// public/index.php
+Leaf\View::attach(\Leaf\Blade::class); // remove this
+Leaf\View::attach(\Leaf\BareUI::class); // add this
+```
+
## Introduction
BareUI takes a fully static approach which means you can use all of it's methods without having to initilaize the package first. Also, there are only 2 things you need to keep in mind about Bare UI
diff --git a/src/modules/views/blade/index.md b/src/modules/views/blade/index.md
index 96ab5d1c..1bbd30f0 100755
--- a/src/modules/views/blade/index.md
+++ b/src/modules/views/blade/index.md
@@ -2,9 +2,32 @@
-This is Leaf's implementation of Laravel's blade templating engine.
+
-## Installation
+[Blade](https://laravel.com/docs/10.x/blade#introduction) is the simple, yet powerful templating engine that is included with Laravel. Unlike some PHP templating engines, Blade does not restrict you from using plain PHP code in your templates. In fact, all Blade templates are compiled into plain PHP code and cached until they are modified, meaning Blade adds essentially zero overhead to your application. Blade template files use the `.blade.php` file extension.
+
+Leaf Blade is a port of the [jenssegers/blade](https://github.com/jenssegers/blade) package that allows you to use blade templates in your Leaf PHP projects.
+
+
+
+## Usage with Leaf MVC
+
+Leaf MVC and Leaf API come with blade support out of the box. You can use blade templates in your Leaf MVC and Leaf API projects without any extra configuration.
+
+All you need to do is create a new blade file in your `app/views` folder and you're good to go! You can also create sub-folders in your `app/views` folder to organize your blade files into multiple sections.
+
+You can skip the installation and setup sections if you're using Leaf MVC or Leaf API.
+
+## Usage with Leaf Core
+
+Since Leaf's core doesn't give you any structure, you'll have to set up blade yourself. Don't worry, it's pretty easy. All you need to do is install blade, configure it to match your project's setup and you're good to go.
You can install leaf blade with the Leaf CLI:
@@ -21,63 +44,46 @@ composer require leafs/blade
After this, you simply need to initialize blade:
```php
-// initialising the package
$blade = new Leaf\Blade();
```
-## Usage
-
-To further understand blade, you can view the official documentation [http://laravel.com/docs/5.8/blade](http://laravel.com/docs/5.8/blade).
+## The Blade class
-Leaf Blade only supports directory configurations, which can be passed as params on initialisation.
+The Blade class takes two parameters on initialization. The first is the path to your view files, and the second is the path to your cached files.
```php
use Leaf\Blade;
-// Blade("template dir", "cache dir");
-$blade = new Blade('app/views', 'app/views/cache');
+$blade = new Blade('views', 'storage/cache');
```
-Not to worry, you can configure blade at a later time after initialisation.
+If you want to initialize the package with the default settings, you can simply do:
```php
-$blade = new Leaf\Blade;
-
-// somewhere, maybe in a different file
-$blade->configure("app/views", "app/views/cache");
-```
-
-Since Blade is also bound directly to the Leaf object, you can directly do this
-
-
-
-```php
-app()->blade->configure("app/views", "app/views/cache");
+$blade = new Leaf\Blade();
```
-
-
+And then configure it later using the `configure()` method:
```php
-$app->blade->configure("app/views", "app/views/cache");
+$blade->configure('app/views', 'app/views/cache');
```
-
+## Rendering a blade view
-Now that this is done, we can render our blade template. This is done with `make`.
+Once you have pointed Blade to the location of your view files, you may easily render them using the `make` method. The `make` method accepts the name of the view file as its first argument, and an array of data as its second argument. The data array will be extracted into variables that may be used within the view file:
```php
-// don't forget to chain the render method
-echo $blade->make('index', ['name' => 'Michael Darko'])->render(); // index.blade.php
+echo $blade->make('index', ['name' => 'Michael Darko'])->render();
```
-Alternatively you can use the shorthand method render:
+Alternatively you can use the shorthand `render()` method:
```php
echo $blade->render('index', ['name' => 'Michael Darko']);
```
-We can have this as our template index.blade.php
+The examples above will look for an `index.blade.php` file in the `views` directory. Within the view, you can access the `name` variable like so:
```html
@@ -91,7 +97,9 @@ We can have this as our template index.blade.php