Minibase_Readme
========================
# Introduction
Minibase is a management tool for companies that need a high flexibility and manage interlaced projects.
In this Readme I will focus on the entry point and the structure of the main application. For more detailed information of each part you will find a separated Readme in each *module* *template* *Static* files etc...  
**Hope You enjow it**

# Knowledge required to deploy Minibase 
The list can be scary for but if you don't want to make some changes, some basic python and web knowlegde would de sufficient.
-   [Python](https://www.python.org/) 
-   [Flask](https://flask.palletsprojects.com/en/3.0.x/)
    -   [flask-sqlalchemy](https://flask-sqlalchemy.palletsprojects.com/en/3.1.x/)
    -   [flask-wtf](https://flask-wtf.readthedocs.io/en/1.2.x/)
    -   [flask-session](https://flask-session.readthedocs.io/en/latest/)
    -   [flask-bcrypt](https://flask-bcrypt.readthedocs.io/en/1.0.1/)
    -   [flask-login](https://flask-login.readthedocs.io/en/latest/)
    -   [flask-mail](https://flask-mail.readthedocs.io/en/latest/)
    -   [flask-migrate](https://flask-migrate.readthedocs.io/en/latest/)
    -   [f]
-   [Sql](https://en.wikipedia.org/wiki/SQL)
-   [Postgres](https://www.postgresql.org/)
-   [Docker](https://www.docker.com/)(Otpional)
    -   [Dockefile](https://docs.docker.com/guides/workshop/02_our_app/)
    -   [Docker-compose](https://docs.docker.com/compose/gettingstarted/)
    -   [Traefik](https://traefik.io/traefik/)
-   [HTML](https://www.w3schools.com/html/)
-   [CSS](https://www.w3schools.com/css/)
-   [Bootsrap](https://getbootstrap.com/docs/5.3/getting-started/introduction/)

# The struture 
The main overwiev how the file structure is organised. This Flask Application is using [Blueprints](https://flask.palletsprojects.com/en/3.0.x/blueprints/) for modularity purposes. In odrder to not overencoumber this docuemntation I will isolate each blueprint and the main app.

```Bash
inibase/
├── docker-compose.yml  "Docker compose file to start create an start the container"(optinal)
├── LICENSE
├── README.md
└── web
    ├── run.py          "Entry point to the app ->" `python3 run.py`
    ├── Dockerfile      "Docker file to containerize the application"(optinal)
    ├── requirments.txt "Python requirement."
    └── minibase       "Main App folder"
        ├── app.py     "Main application called by" `../run.py`
        ├── config.py  "Configurarion for Flask"
        ├── theme.py   "My approach to make a semi interractive color sheme and navbar menus"
        ├── blueprints "Main Blueprint folder"
        │   └── <Blueprint_Name> "Blueprint folder -> named as you like"
        │       ├── forms.py     "Definition of the forms to be used for the blueprint"
        │       ├── models.py    "Database models"
        │       ├── routes.py    "Routes for the html files and interractions for them"
        │       ├── utils.py     "Every Bluprint has it's functionalities coded here"
        │       └── templates    "Template folder for the current blueprint"
        │           └── <Blueprint_Name>    "Same as the blueprint name (this is a naming convention)"
        │               └── <template>.html "Names of the HTML templates for this Blueprint"
        ├── static   "Default location for Static files for the app"
        │   ├── css  "Here will be the CSS for Bootstrap and your own"
        │   ├── img  "Images as logos and icons"
        │   ├── js   "Here will be the JS for Bootstrap and your own"
        │   └── pics "Pictures for users avatars etc.."
        └── templates           "Main Templates folder : for the entire app, Ex: base.html is here"
            └── <template>.html "Names of the HTML templates for main app"
``` 
# The Entry point and the main App
## Building the virtual enviroment and running the app
I would make sense to start from the [benninging](https://www.youtube.com/watch?v=vacJSHN4ZmY)! so we are int he *minibase/web/* directory and working with *run.py* is our entry point and the one which will call *minibase/app.py*. 
- To Sart you need to create a Python *virtual envirement* and *activate it* -> [Instructions](https://git.keydev.me/Kerem/miniBase/src/branch/master/.trainings/flask_to_docker/README.md#create-a-python-virtual-enviroement)
- There is nothing special going on on the code, just *creating* and *running* the application -> [Instructions](https://git.keydev.me/Kerem/miniBase/src/branch/master/.trainings/flask_to_docker/README.md#the-main-funtion-to-start-a-flask-server) 
- PLease note that it still runs in debug `debug=True` enviroment so please be careful if you are wiling to open it to the WWW. 
```python
from minibase.app import create_app

# Creation of the main app
flask_app = create_app()

# Running ht main app the flask app is configured at app.py with an external config.py file
if __name__ == '__main__':
    flask_app.run(debug=True)
```  
## Main Application and initialisation
Here is where the magic starts, all the *Blueprints* and [Modules](https://docs.python.org/3/tutorial/modules.html) comes together the form the main application. We will habve a look a *app.py*, *config.py* and *theme.py*. we Dont need any initial steps as they are taken care of from *run.py*
### *app.py*
- Modules for the modules used here please refer to the links liusted at th beginning. 
```Python
from flask import Flask
from flask_session import Session
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_mail import Mail
from flask_migrate import Migrate
from minibase.config import AppConfig
```
- Global declarations Code comments should suffice. In othe case write to me ;)
```python
# (DATABASE) Definition
db = SQLAlchemy()

# (PASSWORD) Hashing Module to save paswords safely
bcrypt = Bcrypt()

# (LOGIN) Login manage plugin configuration
login_manager = LoginManager()
login_manager.login_view = 'users.login'        # User management (current_user) 
login_manager.login_message_category = 'info'   # Boostrap Info Message

# (EMAIL AGENT) Definition
mail = Mail() # So that we can send mails

# (SESSION) Starts the curren flask session
session = Session()
```
- Definition and initialisation of the *app*.
```python

def create_app():
    # (APP) Definition
    app = Flask(__name__)
    # (APP) Configure configuration
    app.config.from_object(AppConfig)
    # (DATABASE) Initialisation
    db.init_app(app)
    # (PASSWORD) Initialisation
    bcrypt.init_app(app)
    # (LOGIN) Initialisation
    login_manager.init_app(app)
    # (EMAIL AGENT) Initialisation
    mail.init_app(app)
    # Session for variable manipulation on server side
    
    # (DATABASE) Linking the app and the Database
    Migrate(app, db)
```
- *Blueprints* being imported and registered. We will go deeper in Bluprints Afterward
- 
**_NOTE:_**  This is not an exaustive list of *Blueprints* just some exmaples to make it more understandable.
```python
    # (BLUEPRINTS) Importing the blueprints. 
    # Include are made here to awoid the Circular import issues
    from minibase.blueprints.main.routes import main
    from minibase.blueprints.user.routes import user
    from minibase.blueprints.errors.routes import errors
    
    # (BLUEPRINTS) Registering the blueprints. 
    # Giving them theie ulr_prefixes that will define their links on the webBrowser.
    app.register_blueprint(main, url_prefix='/')
    app.register_blueprint(user, url_prefix='/user')
    app.register_blueprint(errors, url_prefix='/errors')

    # (APP) Returning the initialised app 
    return app
```
# Main Templates
Here you will find the what i call the Main *templates*, what do i mean by that ? 
- Flask allows us to work with [templates](https://flask.palletsprojects.com/en/3.0.x/tutorial/templates/) which are *HTML* files, in combination with [Jinja2](https://jinja.palletsprojects.com/en/3.1.x/templates/) template engine  
- This means we can use some *Python* code in out *HTML*
- The most common practice is to define a *Base template* which defines the parts of our website that will stay the same. like the nav bar footer etc...
    - have called it *base.html*
Let's have a look and i guess you will understand it better

## Base template
So as this is the *base* *template* which every other template *will* [extend](https://flask.palletsprojects.com/en/2.3.x/patterns/templateinheritance/) from, i have overly commented it. 
- `{# #}` are *Jinja* *Comments* and are *not visible* at the website source code
- `<!-- --!>` are *HTML* *Comments* and are *visible* at the website source code
### base.html
- Here you can already see some interesting use of *Jinja*
    - To add a Variable we use `{{ <varible> }}` 
    - To add a loop of a comparison we use : `{% <statement> %}` 
- The rest is Standart [HTML](https://www.w3schools.com/html/)
- So what is going on here :
    - `<head>` we define the *HTML* propoerties an reference our [CSS](https://www.w3schools.com/css/) *stylesheets*
    - `<title>{% block title %}Minibase{% endblock %}</title>` We define the *title* with a *default* value | which will be *overwritten* if another html file has a `<{% block title %}{% endblock %}` block
    - `<body style="{{ theme.maineTheme.div_style }}"> ` Here is a an example of how to use *Varible* in *HTLM*. Here I define the `<body style=` with a *varibale* tha is *declared* in *theme.py*.
    - ` {% with messages = get_flashed_messages(with_categories=true) %}` Here we do a check everytime that *base.html* is loaded to see if there is any *messages* to [Flash](https://flask.palletsprojects.com/en/2.3.x/patterns/flashing/). and *show* them *dynamically* wiht their appropriate *categories*. We will also see som examples in the future don't worry. 
    - `{% block content %} {% endblock %}` Same as for the title content there here will be *inserted* the *content* of each *template*
```html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">

        <!-- Referencing custom CSS stylesheet --!> 
        <link rel="stylesheet" type="text/css" href="/css/style.css"/>
        <!-- Referencing Bootstrap CSS stylesheet --!> 
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
        <!-- Referencing Favicon --!> 
        <link rel="shortcut icon" href="{{ url_for('static', filename='img/logo.png') }}">

        {# Title Block : wit Minibase as defauls value : will be overwritten if anothe page has the same title block #}
        <title>{% block title %}Minibase{% endblock %}</title>
    </head>

    {# Here You can see how we use variables in HTML code #}
    <body style="{{ theme.maineTheme.div_style }}"> 

        {# We can also include othe html files #}
        {% include 'navbar.html' %}
        
        <main>
            {# This part will catch anny messages that we want to FLASH when something has been updated #}
            {# Gets the messages with their respective categories #}
            {% with messages = get_flashed_messages(with_categories=true) %}
                {% if messages %} {# If there are messages present #}
                    {% for category, message in messages %} {# Get the message and his category #}
                        <div class="alert alert-{{ category }}">
                            {{ message }} {# Print it #}
                        </div>
                    {% endfor %}
                {% endif %}
            {% endwith %}

            {% block content %}
                {# Every extra template will be placed here for examplem login.htlm and so on #}
            {% endblock %}
        </main>
        
        <!-- Incluting the scrips for bootstrap | Bootstrap 5 don't need jquery anymore --> 
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>

        {% block scripts %}{% endblock %}
    </body>
</html>  

{# These are Jinja comments and will not be shown if someone was to look at the source code of this page contrary to the HTML comments#}
```