TV Channel Website: Building Login Page
Tags: webdev, tutorial, python, bottle
Published: 2022-08-23 13:53:00

GitHub: [https://github.com/Sokhavuth/TV-Channel](https://github.com/Sokhavuth/TV-Channel)
Vercel: [https://khmerweb-tv-channel.vercel.app/login](https://khmerweb-tv-channel.vercel.app/login)
<br/>

<p>So far, we have only a blank homepage, and we do not have anything to put on this page. So, we need to build an admin page or a dashboard to create posts to populate this page. But, as the dashboard is a restricted area, we need to build a login page first to authenticate user before letting them get into this area.</p>

<p>In web programming, the MVC (Models, Views, Controllers) pattern is the most adopted by web developers. For our web application, we can follow this pattern too. </p>

<p>We have been already creating views folder since the beginning, we need only to add controllers and models folders to follow the MVC pattern.</p>

<p>Moreover, we can code login mechanism as a separated application or a blueprint to be mounted with the main application in the entry point index.py file.</p>

```python
# index.py

from bottle import static_file, get
from routes.frontend import index
from routes.frontend import login


app = index.app
app.mount('/login', login.app)

@app.get('/static/<filepath:path>')
def staticFile(filepath):
    return static_file(filepath, root="public")


###################################################################
import socket
host = socket.getfqdn()    
addr = socket.gethostbyname(host)
if(addr == '127.0.1.1'):
    app.run(host='localhost', port=8000, debug=True, reloader=True)

###################################################################
```

```python
# routes/frontend/login.py

from bottle import Bottle, get, post
from controllers.frontend.login import Login


app = Bottle()
login = Login()

@app.get("/")
def getLogin():
    return login.getPage()
```

```python
# controllers/frontend/login.py

import config, copy
from bottle import template


class Login:
    def __init__(self):
        settings = copy.deepcopy(config.settings)
        self.setup = settings()

    def getPage(self):
        self.setup["pageTitle"] = "Log into Admin Page"
        self.setup["route"] = "/login"

        return template("base", data=self.setup)


```

```html
<!--views/frontend/login.tpl-->

<link rel="stylesheet" href="/static/styles/frontend/login.css" />

<section class="Login">
    <div class="outer region">
        <div class="title">{{ data["pageTitle"] }}</div>
        <form action="/login" method="post">
            <a>Email:</a><input type="email" name="email" />
            <a>Password:</a><input type="password" name="password" />
            <a></a><input type="submit" value="Submit" />
            <a></a><div class="message">{{ data["message"] }}</div>
        </form>
    </div>
</section>
```

```html
<!--views/base.tpl-->

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>{{ data["siteTitle"] }} | {{ data["pageTitle"] }}</title>
        <script src="/static/scripts/jquery.js"></script>
        <link href="/static/images/sitelogo.png" rel="icon" />
        <link href="/static/fonts/setup.css" rel="stylesheet" />
        <link href="/static/styles/base.css" rel="stylesheet" />
    </head>
    <body>
        <%  
        if(data["route"] == "/login"):
            include('./frontend/login.tpl')
        end
        %>
    </body>
</html>
```

```css
/* public/styles/frontend/login.css */

.Login .outer{
    margin-top: 100px;
    width: 400px;
    background-color: var(--background);
}

.Login .outer .title{
    text-align: center;
    border-bottom: 1px solid var(--background-light);
    font: 25px/1.5 BlackOpsOne;
}

.Login .outer form{
    display: grid;
    grid-template-columns: 20% auto;
    grid-gap: 5px;
    padding: 20px;
    align-items: center;
}

.Login .outer form input{
    font: var(--body-font);
    padding: 1px 5px;
}

.Login .outer form a{
    text-align: right;
    color: white;
}

.Login .outer form .message{
    text-align: center;
}
```