DEV Community

Gabriel Moura
Gabriel Moura

Posted on

Como Instalar o Maizzle no Laravel

Maizzle é uma estrutura que ajuda você a criar rapidamente e-mails em HTML com Tailwind CSS e pós-processamento avançado específico para e-mails.

Recomendo a leitura da documentação em maizzle.com.

Instalação

npm install tailwindcss-box-shadow@"^2.0.3" \
            tailwindcss-email-variants@"^3.0.1" \
            tailwindcss-mso@"^1.4.3" \
            tailwindcss-preset-email@"^1.1.0" \
            @maizzle/framework@"latest" \
            autoprefixer@"^10.4.20"
Enter fullscreen mode Exit fullscreen mode

Configuração

Crie maizzle.config.local.cjs na raiz do projeto com o conteúdo abaixo:

/*
|-------------------------------------------------------------------------------
| Development config  maizzle.config.local.cjs  https://maizzle.com/docs/environments
|-------------------------------------------------------------------------------
|
| The exported object contains the default Maizzle settings for development.
| This is used when you run `maizzle build` or `maizzle serve` and it has
| the fastest build time, since most transformations are disabled.
|
*/

/** @type {import("@maizzle/framework").Config} */
module.exports = {
    locals: {
        assetPath: "static/emails",
        page: {
            language: "pt_BR"
        },
        app: {
            name: "Maizzle",
            url: "https://maizzle.com"
        }
    },
    build: {
        posthtml: {
            expressions: {
                delimiters: ["[[", "]]"],
                unescapeDelimiters: ["[[[", "]]]"]
            }
        },
        browsersync: {
            watch: ["resources/maizzle/**/*.*", "tailwind.maizzle.js"]
        },
        tailwind: {
            config: "tailwind.maizzle.js",
            css: "resources/maizzle/css/tailwind.css"
        },
        templates: {
            source: "resources/maizzle/templates",
            filetypes: ["html", "blade.php"],
            destination: {
                path: "build"
            },
            assets: {
                source: "resources/maizzle/images",
                destination: "images"
            }
        },
        layouts: {
            root: "resources/maizzle/layouts"
        },
        components: {
            root: "resources/maizzle/",
            folders: ["components", "layouts", "templates"]
        },
        fail: "verbose"
    },
    prettify: true
};
Enter fullscreen mode Exit fullscreen mode

Crie maizzle.config.production.cjs na raiz do projeto com o conteúdo abaixo:

/*
|-------------------------------------------------------------------------------
| Production config  maizzle.config.production.cjs  https://maizzle.com/docs/environments
|-------------------------------------------------------------------------------
|
| This is where you define settings that optimize your emails for production.
| These will be merged on top of the base config.js, so you only need to
| specify the options that are changing.
|
*/

/** @type {import("@maizzle/framework").Config} */
module.exports = {
    locals: {
        assetPath: "static/emails",
        page: {
            language: "pt_BR"
        },
        app: {
            name: "Maizzle",
            url: "https://maizzle.com"
        }
    },
    build: {
        posthtml: {
            expressions: {
                delimiters: ['[[', ']]'],
                unescapeDelimiters: ['[[[', ']]]']
            }
        },
        tailwind: {
            config: "tailwind.maizzle.js",
            css: "resources/maizzle/css/tailwind.css"
        },
        templates: {
            source: "resources/maizzle/templates",
            filetypes: ["html", "blade.php"],
            destination: {
                path: "resources/views/emails",
                extension: "blade.php"
            },
            assets: {
                source: "resources/maizzle/images",
                destination: "../../static/emails"
            }
        },
        layouts: {
            root: "resources/maizzle/layouts"
        },
        components: {
            root: "resources/maizzle/",
            folders: ["components", "layouts", "templates"]
        },
        fail: "verbose"
    },
    inlineCSS: true,
    removeUnusedCSS: true,
    shorthandCSS: true,
    minify: true,
    events: {
        afterBuild(files, config) {
            console.log(files);
        }
    }
};
Enter fullscreen mode Exit fullscreen mode

Crie tailwind.maizzle.js na raiz do projeto com o conteúdo abaixo:

/** @type {import("tailwindcss").Config} */
// tailwind.maizzle.js
export default {
    content: [
        "./resources/maizzle/components/**/*.{html,blade.php}",
        "./resources/maizzle/layouts/**/*.{html,blade.php}",
        "./resources/maizzle/templates/**/*.{html,blade.php}",
    ],
    theme: {
        screens: {
            sm: { max: "600px" },
            xs: { max: "425px" },
        },
        extend: {
            spacing: {
                screen: "100vw",
                full: "100%",
                0: "0",
                0.5: "2px",
                1: "4px",
                1.5: "6px",
                2: "8px",
                2.5: "10px",
                3: "12px",
                3.5: "14px",
                4: "16px",
                4.5: "18px",
                5: "20px",
                5.5: "22px",
                6: "24px",
                6.5: "26px",
                7: "28px",
                7.5: "30px",
                8: "32px",
                8.5: "34px",
                9: "36px",
                9.5: "38px",
                10: "40px",
                11: "44px",
                12: "48px",
                14: "56px",
                16: "64px",
                20: "80px",
                24: "96px",
                28: "112px",
                32: "128px",
                36: "144px",
                40: "160px",
                44: "176px",
                48: "192px",
                52: "208px",
                56: "224px",
                60: "240px",
                64: "256px",
                72: "288px",
                80: "320px",
                96: "384px",
            },
            borderRadius: {
                none: "0px",
                sm: "2px",
                DEFAULT: "4px",
                md: "6px",
                lg: "8px",
                xl: "12px",
                "2xl": "16px",
                "3xl": "24px",
            },
            boxShadow: {
                sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
                DEFAULT:
                    "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)",
                md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)",
                lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)",
                xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1)",
                "2xl": "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
                inner: "inset 0 2px 4px 0 rgba(0, 0, 0, 0.05)",
            },
            fontFamily: {
                sans: [
                    "ui-sans-serif",
                    "system-ui",
                    "-apple-system",
                    '"Segoe UI"',
                    "sans-serif",
                ],
                serif: [
                    "ui-serif",
                    "Georgia",
                    "Cambria",
                    '"Times New Roman"',
                    "Times",
                    "serif",
                ],
                mono: ["ui-monospace", "Menlo", "Consolas", "monospace"],
            },
            fontSize: {
                0: "0",
                xxs: "11px",
                xs: "12px",
                "2xs": "13px",
                sm: "14px",
                "2sm": "15px",
                base: "16px",
                lg: "18px",
                xl: "20px",
                "2xl": "24px",
                "3xl": "30px",
                "4xl": "36px",
                "5xl": "48px",
                "6xl": "60px",
                "7xl": "72px",
                "8xl": "96px",
                "9xl": "128px",
            },
            letterSpacing: (theme) => ({
                ...theme("width"),
            }),
            lineHeight: (theme) => ({
                ...theme("width"),
            }),
            maxWidth: (theme) => ({
                ...theme("width"),
                xs: "160px",
                sm: "192px",
                md: "224px",
                lg: "256px",
                xl: "288px",
                "2xl": "336px",
                "3xl": "384px",
                "4xl": "448px",
                "5xl": "512px",
                "6xl": "576px",
                "7xl": "640px",
            }),
            minHeight: (theme) => ({
                ...theme("width"),
            }),
            minWidth: (theme) => ({
                ...theme("width"),
            }),
        },
    },
    corePlugins: {
        preflight: false,
        backgroundOpacity: false,
        borderOpacity: false,
        divideOpacity: false,
        placeholderOpacity: false,
        textOpacity: false,
    },
    plugins: [
        require("autoprefixer")(),
        require("tailwindcss-mso"),
        require("tailwindcss-box-shadow"),
        require("tailwindcss-email-variants"),
    ],
    presets: [require("tailwindcss-preset-email")],
};
Enter fullscreen mode Exit fullscreen mode

Copie o conteúdo de src/ que pode ser encontrado no repositório oficial para resources/maizzle .

Altere o package.json para :

"scripts":{
    ...
    "mail": "maizzle serve",
    "mail:build": "maizzle build production"
}
Enter fullscreen mode Exit fullscreen mode

Altere os conteúdos das pastas components, layouts, templates para usar [[ ]] e [[[ ]]] ao invés de {{ }} e {{{ }}}, pois a configuração permite usar as diretivas do blade sem usar @{{}} .

# find resources/maizzle -type f: Encontra todos os arquivos dentro do diretório resources/maizzle
# -exec sed -i 's/{{{/[[[/g; s/}}}/]]]/g; s/{{/[[/g; s/}}/]]/g' {} \;: Para cada arquivo encontrado, o comando sed faz as substituições.
find resources/maizzle -type f -exec sed -i 's/{{{/[[[/g; s/}}}/]]]/g; s/{{/[[/g; s/}}/]]/g' {} \;
Enter fullscreen mode Exit fullscreen mode

Altere o nome dos arquivos em components, layouts, templates para terminarem com blade.php, isso ajudará o seu IDE a identificar as diretivas blade.

# find resources/maizzle -type f -name "*.html": Encontra todos os arquivos que terminam com .html no diretório resources/maizzle.
# -exec bash -c 'mv "$0" "${0%.html}.blade.php"' {}: Para cada arquivo encontrado, o comando mv renomeia o arquivo removendo a extensão .html e adicionando .blade.php.
find resources/maizzle -type f -name "*.html" -exec bash -c 'mv "$0" "${0%.html}.blade.php"' {} \;
Enter fullscreen mode Exit fullscreen mode

Uso

php artisan make:mail OrderShipped
Enter fullscreen mode Exit fullscreen mode
<?php

namespace App\Mail;

use App\Models\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Queue\SerializesModels;

class OrderShipped extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     */
    public function __construct(
        public Order $order,
    ) {}

    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'mail.welcome',
            with: [
                'orderName' => $this->order->name,
                ],
        );
    }
}
Enter fullscreen mode Exit fullscreen mode

Um exemplo de template resources/maizzle/templates/welcome.blade.php

<x-main>
    <div class="bg-slate-50 font-sans sm:px-4">
        <table align="center">
            <tr>
                <td class="w-[552px] max-w-full">
                    <div class="my-12 text-center sm:my-8">
                        <a href="https://maizzle.com">
                            <img
                                src="{{ asset("/static/logo.svg") }}"
                                width="70"
                                alt="Maizzle"
                            />
                        </a>
                    </div>

                    <table class="w-full">
                        <tr>
                            <td class="rounded bg-white p-12 text-base text-slate-700 shadow-sm sm:px-6" >
                                <h1 class="m-0 mb-6 text-2xl font-semibold text-black sm:leading-8" >
                                    Hello, {{ $orderName }}
                                </h1>

                                <p class="m-0 leading-6">
                                    Is it you we're looking for?
                                    <br />
                                    <br />
                                    Please confirm your email address by
                                    clicking the button below:
                                </p>

                                <x-spacer height="24px" />

                                <x-button href="https://maizzle.com">
                                    Confirm email address &rarr;
                                </x-button>

                                <x-divider
                                    space-y="32px"
                                    class="bg-slate-200"
                                />

                                <p class="m-0">
                                    If you didn't sign up for Maizzle, you can
                                    safely ignore this email.
                                    <br />
                                    <br />
                                    Thanks,
                                    <br />
                                    The Maizzle Team
                                </p>
                            </td>
                        </tr>
                        <tr role="separator">
                            <td class="leading-12">&zwj;</td>
                        </tr>
                        <tr>
                            <td class="px-6 text-center text-xs text-slate-600">
                                <p class="m-0 mb-4 uppercase">
                                    Powered by Maizzle
                                </p>

                                <p class="m-0 italic">
                                    Quickly build HTML emails with Tailwind CSS
                                </p>

                                <p class="cursor-default">
                                    <a
                                        href="https://maizzle.com/docs/"
                                        class="text-indigo-700 [text-decoration:none] hover:![text-decoration:underline]"
                                    >
                                        Docs
                                    </a>
                                    &bull;
                                    <a
                                        href="https://github.com/maizzle"
                                        class="text-indigo-700 [text-decoration:none] hover:![text-decoration:underline]"
                                    >
                                        Github
                                    </a>
                                    &bull;
                                    <a
                                        href="https://twitter.com/maizzlejs"
                                        class="text-indigo-700 [text-decoration:none] hover:![text-decoration:underline]"
                                    >
                                        Twitter
                                    </a>
                                </p>
                            </td>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </div>
</x-main>

Enter fullscreen mode Exit fullscreen mode

Rode o comando abaixo para gerar o arquivo blade final.

npm run mail:build
Enter fullscreen mode Exit fullscreen mode

Top comments (0)