Skip to content

Commit

Permalink
feat(docs): add documentation files for controllers, index, quickstar…
Browse files Browse the repository at this point in the history
…t, router, usage, and views

feat(mkdocs.yml): configure navigation and theme for documentation site
feat(pyproject.toml): add mkdocs-material as a dev dependency for documentation site
  • Loading branch information
marcuxyz committed Nov 10, 2023
1 parent 2fc33e9 commit 36197c9
Show file tree
Hide file tree
Showing 9 changed files with 847 additions and 5 deletions.
29 changes: 29 additions & 0 deletions docs/controllers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Controllers

Now that configured routes, the `home_controller.py` file must contain the HomeController class, registering the action.

from flask import render_template

```python
class HomeController:
def index(self):
return render_template("index.html")
```

If you have a question, please, check the app directory for more details.

To use the hooks as `before_request`, `after_request`, etc... Just describe it in the controller, see:

```python
class HomeController:
before_request = ["hi"]

def index(self):
return "home"

def hi(self):
...
```

The method `hi(self)` will be called whenever the visitors access the controller.

63 changes: 63 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Introduction

<p align="center">This extension facilitates the application of this design pattern in Flask </p>
<p align="center">
<a href="https://github.com/marcuxyz/mvc-flask/actions/workflows/test.yml">
<img src="https://github.com/marcuxyz/mvc-flask/actions/workflows/test.yml/badge.svg?branch=main" alt="unit test" height="18">
</a>
<a href="https://badge.fury.io/py/mvc-flask">
<img src="https://badge.fury.io/py/mvc-flask.svg" alt="PyPI version" height="18">
</a>
</p>


Designed to allow developers to implement the Model-View-Controller (MVC) design pattern in Flask applications with the help of this extension.
<hr />

Install MVC Flask using pip:

```shell
$ pip install mvc_flask
```

Install MVC Flask using poetry:

```shell
$ poetry add mvc_flask
```

Now, let's get started:

```python
from flask import Flask
from mvc_flask import FlaskMVC
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'

# registering extensions
FlaskMVC(app)
db.init_app(app)

return app
```

![Image of structure](assets/images/structure.png)

## Features

MVC Flask builds on provides the best architecture experience for Flask, and gives you:

- You can directories as controllers, models, and views.
- It Supports the controllers' creation, and you can separate the logic of your application of business rules
- You can separate routes of business rules
- You can use the before_action to execute a specific code
- You can integrate with other extensions of Flask, Flask-SQLAlchemy, Flask-Migrate, etc.

## Dependencies

MVC Flask just depends on the Flask extensions to working and requires Python >=3.8.0,<4.0.0.
44 changes: 44 additions & 0 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Quickstart

To start the use `mvc_flask` you need to import and register in your application, e.g:

```python
from flask import Flask
from mvc_flask import FlaskMVC

app = Flask(__name__)
FlaskMVC(app)
```

Or use `application factories`, e.g:

```python
mvc = FlaskMVC()

def create_app():
...
mvc.init_app(app)
```

Now, you can use src as the default directory to prepare your application. Your structure should look like this:

```python
app
├── __ini__.py
├── controllers
│ └── home_controller.py
├── routes.py
└── views
├── index.html
```

**By default, the mvc_flask assumes that your application directory will be app and if it doesn't exist, create it! If you can use another directory, you can use the path parameter when the instance of FlaskMVC is initialized. E.g:**

```python
mvc = FlaskMVC()

def create_app():
...
mvc.init_app(app, path='src')
```

89 changes: 89 additions & 0 deletions docs/router.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Router

You can create routes in `app/routes.py` and after creating file, you can start to register routes, e.g:

```python
from mvc_flask import Router

Router.get("/", "home#index")
```

The same must be done to `POST`, `PUT` and `DELETE` methods. E.g: `Router.post("/messages", "messages#create")`

The first param represents the relative path and the second represents the controller#action. Remember that we are working with an MVC pattern, so we have a controller and action.

The controller can be created in `app/controllers` and action is a method of the controller.

You can use `Router.all()` to register all routes of CRUD.

```python
Router.all("messages")
```

The previous command produces this:

```python
messages.create POST /messages
messages.delete DELETE /messages/<id>
messages.edit GET /messages/<id>/edit
messages.index GET /messages
messages.new GET /messages/new
messages.show GET /messages/<id>
messages.update PATCH, PUT /messages/<id>
```

You can also use only parameters to control routes, e.g:

```python
Router.all("messages", only="index show new create")
```

The previous command produces this:

```python
messages.index GET /messages
messages.show GET /messages/<id>
messages.new GET /messages/new
messages.create POST /messages
```

The parameter only accept `string` or `array`, so, you can use `only=["index", "show", "new", "create"]` or `only='index show new create'`

## Namespaces

You can use namespaces to group the routes.

```python
from mvc_flask import Router

api = Router.namespace("/api/v1")

api.get("/health", "health#index")

api.all("user")

posts = api.namespace("/posts")
posts.get("", "posts#index")
posts.post("", "posts#create")
posts.get("/<id>", "posts#show")
posts.put("/<id>", "posts#update")
posts.get("/<id>", "posts#delete")
```

The previous command produces this:

```shell
health.index GET /api/v1/health
posts.create POST /api/v1/posts
posts.delete GET /api/v1/posts/<id>
posts.index GET /api/v1/posts
posts.show GET /api/v1/posts/<id>
posts.update PATCH, PUT /api/v1/posts/<id>
user.create POST /api/v1/user
user.delete DELETE /api/v1/user/<id>
user.edit GET /api/v1/user/<id>/edit
user.index GET /api/v1/user
user.new GET /api/v1/user/new
user.show GET /api/v1/user/<id>
user.update PATCH, PUT /api/v1/user/<id>
```
40 changes: 40 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Usage

We know that the HTML form doesn't send the payload for methods other than Get and Post. But, the FLASK MVC does the work for you, everything you need is to add the tag in the HTML template. Look:

```python
# app/controllers/messages_controller.py

from flask import render_template, redirect, url_for, flash, request

class MessagesController:
def edit(self, id):
message = Message.query.get(id)

return render_template("messages/edit.html", message=message)

def update(self, id):
message = Message.query.get(id)
message.title = request.form.get('title')

db.session.add(message)
db.session.commit()
flash('Message sent successfully!')

return redirect(url_for(".edit"))
```

```jinja
<!-- app/views/messages/edit.html -->
{% block content %}
<form action="{{ url_for('messages.update', id=message.id) }}" method="POST">
<input type="hidden" name="_method" value="put">
<input type="text" name="title" id="title" value="Yeahh!">
<input type="submit" value="send">
</form>
{% endblock %}
```

The <input type="hidden" name="_method" value="put"> is necessary to work successfully!
7 changes: 7 additions & 0 deletions docs/views.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Views

Flask uses the templates directory by default to store HTML files. However, using the `mvc-flask` the default becomes `views`.
You can use the app/views directory to store templates.

Please if you create template, use `views` for folder name, instead of `templates`.

24 changes: 24 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
site_name: FLASK MVC
theme:
name: material
features:
- navigation.sections
nav:
- Introduction: 'index.md'
- Usage:
- QuickStart: 'quickstart.md'
- Configuration:
- Router: 'router.md'
- Controllers: 'controllers.md'
- Views: 'views.md'
- Forms:
- Usage: 'usage.md'


repo_name: marcuxyz/mvc_flask
repo_url: https://github.com/marcuxyz/mvc_flask/
edit_uri: ""

markdown_extensions:
- codehilite:
css_class: highlight
Loading

0 comments on commit 36197c9

Please sign in to comment.