© Christopher Pitt and Joe Mancuso 2020
C. Pitt, J. MancusoThe Definitive Guide to Masonitehttps://doi.org/10.1007/978-1-4842-5602-2_9

9. Using Helpers

Christopher Pitt1  and Joe Mancuso2
(1)
Cape Town, South Africa
(2)
Holbrook, NY, USA
 

We’ve already covered a lot of ground, so we’re going to change gears and talk about helpers. In short, helpers are functions we can use from anywhere that do things for us quicker or more efficiently than we could otherwise do. It’s tricky to explain their use without looking at code, so that’s what we’re going to do.

These helpers are available, globally, so you won’t need to import most of them. I’ll tell you what the exceptions are, when it’s important.

The Request and Auth Helpers

This code can be found at https://github.com/assertchris/friday-server/tree/chapter-10.

We’re no stranger to the Request class. It’s common for us to inject it into a controller action:
def show(self, request: Request, view: View):
    return view.render('home', {
        'name': request.param('name'),
    })

What if we wanted to use the request from somewhere else? I’m not talking about whether we should, or not, but rather, “could we?”

An obvious place we might want to use it would be in the view:
@extends 'layout.html'
@block content
    hello {{ request().param('name') }}
@endblock
If you like this style, you may like using the request helper in actions, as well:
from masonite.auth import Auth
from masonite.view import View
class HomeController:
    def show(self, view: View, auth: Auth):
        return view.render('home', {
            'name': request().param('name') or request().input('name'),
        })
Similarly, we can shorten the auth code by using an Auth helper:
from masonite.view import View
class HomeController:
    def show(self, view: View):
        return view.render('home', {
            'name': request().param('name') or auth().email,
        })

This is from app/http/controllers/HomeController.py.

The auth() function can be super helpful, but be careful using it. If the user isn’t logged in, then auth() will return False. Your code should take that into account. It’s also great in the view layer:
<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <link href="/static/style.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div class="container mx-auto p-4">
            @if (auth())
               <a href="{{ route('logout') }}">log out</a>
            @else
               <a href="{{ route('login') }}">log in</a>
            @endif
            @block content
                <!-- template content will be put here-->
            @endblock
        </div>
    </body>
</html>

This is from resources/templates/layout.html.

The auth() function will return None if the user isn’t logged in, which can be reused to toggle UI based on the presence of a user session. This is also an example of another helper.

The Route Helper

The Route helper is essential for larger apps, but you have to name your routes for it to work:
Get('/profile/@id', 'ProfileController@show').name('profile')
We can use the route() function to build out any named route, including routes that we’ve defined parameters for:
<a href="{{ route('profile', { 'id': auth().id }) }}">public profile</a>

The Container and Resolve Helpers

Sometimes we may want to add our own classes and functions to the service container, we learned about in Chapter 4. You may not always be inside an action with access to “the app,” but you can access the container helper:
from app.Service import Service
container().bind('Service', Service)
# ...later
container().make('Service')

Service is an example, here. Think of it as a placeholder for whatever custom class your next application may need.

This is great for extending things already in the container and for accessing things stored in the container from other contexts, like views and models. In a similar vein, it can be useful to resolve dependencies of a function, like Masonite does automatically for actions.

Here’s an example of how a controller action’s request parameter is automatically resolved:
from masonite.helpers import compact
# ...later
def respond(request: Request):
    action = request.param('action')
    name = request.param('name')
    if (action == 'read'):
        return view('read.html', compact(name))
    if (action == 'write'):
        return view('write.html', compact(name))
def handle(self):
    return resolve(respond)

The resolve helper takes another function and resolves the parameters it needs out of the container. This is also an example of our first non-global helper (the compact() function), which takes a list of variables and returns a dictionary where each key is the string variable name and each value is the variable’s value.

Non-global helpers are just helpers you still need to import in every file where they are used. Here, we’re importing the compact helper. You can make non-global helpers globally available by following a similar pattern to this: https://docs.masoniteproject.com/the-basics/helper-functions#introduction.

The Env and Config Helpers

env() and config() are closely related helpers, which pull configuration variables out of the environment (or .env files) and files within the config folder, respectively. The main difference between them, other than that they look in different files, is that data returned from env() is aggressively cached, whereas data returned from config() can be changed and lazy-loaded.

When using these, it’s best to only use env() inside config files and only use config() everywhere else:
FROM = {
    'address': env('MAIL_FROM_ADDRESS', '[email protected]'),
    'name': env('MAIL_FROM_NAME', 'Masonite')
}

This is from config/mail.py.

As this demonstrates, the second parameter to the env() function is a default value. This is great if or when the environment variable isn’t guaranteed to exist. Once the configuration variables are in a config file, we can pull them out with the config() function :
from config import mail as mail_config
# ...later
print(mail_config.FROM['address'])

The Dump-and-Die Helper

Like so much of Masonite, the dump-and-die helper is inspired by the same helper in Laravel: https://laravel.com/docs/6.x/helpers#method-dd. It’s a quick way to stop what’s going on, so you can inspect the contents of multiple variables:
dd(User.find(1).email, request().params('email'))

It’s not a step debugger, but it’s great in a pinch!

Summary

In this chapter, we’ve taken a look at the most popular helper functions. They’re certainly not the only helper functions, so I encourage you to take a look at the documentation to learn more: https://docs.masoniteproject.com/the-basics/helper-functions. Chances are you’ll find something there that you like.

In the next chapter, we’re going to learn about all the different ways we can send notifications from our applications.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.193.129