<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Cláudio Oliveira</title>
    <description>The latest articles on Forem by Cláudio Oliveira (@claudio1994oliveira).</description>
    <link>https://forem.com/claudio1994oliveira</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F767495%2F8e79b925-256f-44d1-b2b3-a2486be78797.jpeg</url>
      <title>Forem: Cláudio Oliveira</title>
      <link>https://forem.com/claudio1994oliveira</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/claudio1994oliveira"/>
    <language>en</language>
    <item>
      <title>MY PHP MVC</title>
      <dc:creator>Cláudio Oliveira</dc:creator>
      <pubDate>Fri, 13 Sep 2024 13:29:14 +0000</pubDate>
      <link>https://forem.com/claudio1994oliveira/my-php-mvc-3n9d</link>
      <guid>https://forem.com/claudio1994oliveira/my-php-mvc-3n9d</guid>
      <description>&lt;p&gt;Hello everyone!&lt;/p&gt;

&lt;p&gt;This is my first post in English, and I hope I don't write too much nonsense 😅&lt;/p&gt;

&lt;p&gt;Well, as I’ve already written here before in Portuguese, I’m a PHP developer currently working with Laravel. I have no complaints—I love Laravel and its ecosystem.&lt;/p&gt;

&lt;p&gt;But I decided to study and understand how a framework works. So, I started creating a PHP framework from scratch just for fun. &lt;/p&gt;

&lt;p&gt;I'm one of those developers who like to code in my spare time. 😅&lt;/p&gt;

&lt;p&gt;So, I went ahead and started.&lt;/p&gt;

&lt;p&gt;The result is this: &lt;strong&gt;My PHP MVC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;composer create-project claud/my-php-mvc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Well, it’s a small framework.&lt;/p&gt;

&lt;p&gt;I know, I know, there are sooo many others out there, so why another one? Look, I'm not trying to compete—I just did this to better understand the concepts and have fun coding.&lt;/p&gt;

&lt;p&gt;But now, I’d like to invite you to take a look and maybe contribute to making it more polished.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/claudio1994-oliveira/my-php-mvc" rel="noopener noreferrer"&gt;GitHub - My PHP MVC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you can, download it, give it a star on the repository—it would make me really happy, and you can even call "My PHP MVC" your own.&lt;/p&gt;

&lt;p&gt;Oh, and I’m open to any feedback or critiques you might have&lt;/p&gt;

&lt;p&gt;If you can, download it, give it a star on the repository—it would make me really happy, and you can even call "My PHP MVC" your own.&lt;/p&gt;

&lt;p&gt;Oh, and I’m open to any feedback or critiques you might have.&lt;/p&gt;

</description>
      <category>php</category>
      <category>mvc</category>
    </item>
    <item>
      <title>Introdução ao My PHP MVC Framework: Construindo seu próprio Framework PHP do zero</title>
      <dc:creator>Cláudio Oliveira</dc:creator>
      <pubDate>Sun, 18 Feb 2024 19:54:44 +0000</pubDate>
      <link>https://forem.com/claudio1994oliveira/introducao-ao-my-php-mvc-framework-construindo-seu-proprio-framework-php-do-zero-1cbn</link>
      <guid>https://forem.com/claudio1994oliveira/introducao-ao-my-php-mvc-framework-construindo-seu-proprio-framework-php-do-zero-1cbn</guid>
      <description>&lt;p&gt;No mundo do desenvolvimento web, frameworks desempenham um papel crucial na simplificação do processo de desenvolvimento e na organização do código. É difícil encontrar times de desenvolvimento que começam um novo projeto do zero sem pelo menos um "esqueleto", uma base - que justamente os frameworks provém (com algumas outras facilidades).&lt;/p&gt;

&lt;p&gt;No mundo PHP (no qual eu tenho maior experiência) temos vários (e bons) exemplos de frameworks web como Laravel, Symfony, CodeIgniter, Zend Framework (Laminas Framework?), Yii, CakePHP, Slim e etc.&lt;/p&gt;

&lt;p&gt;Atualmente eu trabalho com Laravel e seu ecossistema para desenvolver soluções web mas em essência eu sou desenvolvedor PHP. Decidi decidi desenvolver um pequeno projeto, um pequeno framework do zero para exercitar um pouco e se divertir.&lt;/p&gt;

&lt;p&gt;Criei o &lt;a href="https://github.com/claudio1994-oliveira/my-php-mvc"&gt;"My PHP MVC Framework&lt;/a&gt;". A ideia é relativamente simples, um projeto com o padrão MVC (&lt;a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;Model-View- Controller&lt;/a&gt;) com um código simples e com menos dependências externas possíveis. Por que? Quero escrever a maior parte que conseguir para ter mais resultados educacionais e até mesmo de portifólio. &lt;/p&gt;

&lt;h2&gt;
  
  
  Funcionalidades
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fácil de usar;&lt;/li&gt;
&lt;li&gt;Simples e intuitivo;&lt;/li&gt;
&lt;li&gt;Suporte para rotas com parâmetros;&lt;/li&gt;
&lt;li&gt;Funções ou métodos associados com rotas&lt;/li&gt;
&lt;li&gt;Gerenciador de banco de dados simples&lt;/li&gt;
&lt;li&gt;Componentes de visualização&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Você pode encontrar o repositório &lt;a href="https://github.com/claudio1994-oliveira/my-php-mvc"&gt;aqui&lt;/a&gt; ou pode criar um novo projeto via composer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer create-project claud/my-php-mvc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Núcleo do framework:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Roteamento
&lt;/h3&gt;

&lt;p&gt;Dentro do diretório _config _ existe um arquivo &lt;code&gt;router.php&lt;/code&gt; e é nele que declaramos nossas rotas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
require_once __DIR__ . '/../vendor/autoload.php';

use Router\Router\Router;

$router = new Router();

/*
 * Add routes here
 */

$router-&amp;gt;addRoute('/', 'App\Controller\WelcomeController@render');



return $router;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementação de controladores e modelos básicos
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Controler\WelcomeController.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

declare(strict_types=1);

namespace App\Controller;


class WelcomeController
{
    public function render()
    {
        return view("welcome", ['title' =&amp;gt; "Bem vindo!"]);
    }

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Entity\User.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Entity;

class User
{
    public  int $id;
    public string $name;
    public string $username;

    public string $email;

    public string $password;

    public ?string $created_at;

    public ?string $updated_at;

    public function __construct(string $name, string $username, string $email, string $password, ?string $created_at = null, ?string $updated_at = null)
    {
        $this-&amp;gt;name = $name;
        $this-&amp;gt;username = $username;
        $this-&amp;gt;email = $email;
        $this-&amp;gt;password = $password;
        $this-&amp;gt;created_at = $created_at;
        $this-&amp;gt;updated_at = $updated_at;
    }

    public function setId(int $id): void
    {
        $this-&amp;gt;id = $id;
    }

    public function getId(): ?int
    {
        return $this-&amp;gt;id;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Repositpry\UserRepository.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Repository;

use App\Contracts\RepositoryInterface;
use App\Entity\User;
use PDO;

class UserRepository implements RepositoryInterface
{
    private PDO $pdo;

    public function __construct(PDO $pdo)
    {
        $this-&amp;gt;pdo = $pdo;
    }

    public function create(object $user): object
    {
        $sql = 'INSERT INTO users (name, username, email, password) VALUES (?, ?, ?, ?);';
        $statement = $this-&amp;gt;pdo-&amp;gt;prepare($sql);
        $statement-&amp;gt;bindValue(1, $user-&amp;gt;name);
        $statement-&amp;gt;bindValue(2, $user-&amp;gt;username);
        $statement-&amp;gt;bindValue(3, $user-&amp;gt;email);
        $statement-&amp;gt;bindValue(4, $user-&amp;gt;password);

        $result = $statement-&amp;gt;execute();
        if (!$result) {
            throw new \RuntimeException('Could not save user');
        }

        $id = $this-&amp;gt;pdo-&amp;gt;lastInsertId();

        $user-&amp;gt;setId(intval($id));

        return $user;
    }

    public function update(int $id, object $user): bool
    {
        $sql = 'UPDATE users SET name = ?, username = ?, email = ?, password = ? WHERE id = ?;';
        $statement = $this-&amp;gt;pdo-&amp;gt;prepare($sql);
        $statement-&amp;gt;bindValue(1, $user-&amp;gt;name);
        $statement-&amp;gt;bindValue(2, $user-&amp;gt;username);
        $statement-&amp;gt;bindValue(3, $user-&amp;gt;email);
        $statement-&amp;gt;bindValue(4, $user-&amp;gt;password);
        $statement-&amp;gt;bindValue(5, $user-&amp;gt;id);

        return $statement-&amp;gt;execute();
    }

    public function delete(int $id): bool
    {
        $sql = 'DELETE FROM users WHERE id = ?;';
        $statement = $this-&amp;gt;pdo-&amp;gt;prepare($sql);
        $statement-&amp;gt;bindValue(1, $id);

        return $statement-&amp;gt;execute();
    }

    public function all(): array
    {
        $sql = 'SELECT * FROM users;';

        $statement = $this-&amp;gt;pdo-&amp;gt;prepare($sql);

        $statement-&amp;gt;execute();

        return $statement-&amp;gt;fetchAll(\PDO::FETCH_ASSOC);
    }

    public function findByUsername(string $username)
    {
        $statement = $this-&amp;gt;pdo-&amp;gt;prepare('SELECT * FROM users WHERE username = ?;');
        $statement-&amp;gt;bindValue(1, $username);
        $statement-&amp;gt;execute();

        return $statement-&amp;gt;fetch(\PDO::FETCH_ASSOC);
    }

    public function find(int $id): null|object
    {
        $statement = $this-&amp;gt;pdo-&amp;gt;prepare('SELECT * FROM users WHERE id = ?;');
        $statement-&amp;gt;bindValue(1, $id);
        $statement-&amp;gt;execute();

        $userArr = $statement-&amp;gt;fetch(\PDO::FETCH_ASSOC);
        $user = new User($userArr['name'], $userArr['username'], $userArr['email'], $userArr['password'], $userArr['created_at'], $userArr['updated_at']);

        return $user;
    }

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exemplo prático:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Criando um site
&lt;/h3&gt;

&lt;p&gt;Criando o projeto&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer create-project claud/my-php-mvc site
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro da pasta de &lt;code&gt;Controller&lt;/code&gt; crie o arquivo &lt;code&gt;SiteController.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

declare(strict_types=1);

namespace App\Controller;


class SiteController
{
    public function render(): void
    {
        view("site.index", ['title' =&amp;gt; "Bem vindo!"]);
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O retorno da view renderizar o arquivo index.php dentro da pasta site. Os nomes dos arquivos e pastas ficam a critério do DEV.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqzncg6ht8h5gehtzdqe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxqzncg6ht8h5gehtzdqe.png" alt="Estrutura de pastas" width="311" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Criei uma pastas chamada &lt;code&gt;__partials&lt;/code&gt; para colocar os dados da tag &lt;code&gt;head&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xb2854wqnywdx6bltm2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xb2854wqnywdx6bltm2.png" alt="Estruturas de pastas" width="310" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como exemplo, eu peguei um projeto no &lt;a href="https://github.com/luizomf/landing-page-cursojs"&gt;Git Hub&lt;/a&gt; e usei para criar o site.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;head.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;&amp;lt;?= $title ?&amp;gt;&amp;lt;/title&amp;gt;
    &amp;lt;link rel="stylesheet" href="css/variables.css"&amp;gt;
    &amp;lt;link rel="stylesheet" href="css/elements.css"&amp;gt;
    &amp;lt;link rel="stylesheet" href="css/classes.css"&amp;gt;
    &amp;lt;link rel="stylesheet" href="css/menu.css"&amp;gt;
    &amp;lt;link rel="stylesheet" href="css/style.css"&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;views\site\index.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="pt_BR"&amp;gt;
&amp;lt;?php include '__partials/head.php' ?&amp;gt;

&amp;lt;body&amp;gt;

    &amp;lt;input id="close-menu" class="close-menu" type="checkbox" aria-label="Close menu" role="button"&amp;gt;
    &amp;lt;label class="close-menu-label" for="close-menu" title="close menu"&amp;gt;&amp;lt;/label&amp;gt;
    &amp;lt;aside class="menu white-bg"&amp;gt;
        &amp;lt;div class="main-content menu-content"&amp;gt;
            &amp;lt;h1 onclick="getElementById('close-menu').checked = false;"&amp;gt;
                &amp;lt;a href="#home"&amp;gt;LOGO&amp;lt;/a&amp;gt;
            &amp;lt;/h1&amp;gt;

            &amp;lt;nav&amp;gt;
                &amp;lt;ul onclick="getElementById('close-menu').checked = false;"&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;a href="#intro"&amp;gt;intro&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;a href="#grid-one"&amp;gt;grid-one&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;a href="#gallery"&amp;gt;gallery&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;a href="#grid-two"&amp;gt;grid-two&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;a href="#pricing"&amp;gt;pricing&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                    &amp;lt;li&amp;gt;&amp;lt;a href="/contact"&amp;gt;contact&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
                &amp;lt;/ul&amp;gt;
            &amp;lt;/nav&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/aside&amp;gt;

    &amp;lt;div class="menu-spacing"&amp;gt;&amp;lt;/div&amp;gt;

    &amp;lt;section id="home" class="intro main-bg section"&amp;gt;
        &amp;lt;div class="main-content intro-content"&amp;gt;
            &amp;lt;div class="intro-text-content"&amp;gt;
                &amp;lt;h2&amp;gt;January brings us Firefox 85&amp;lt;/h2&amp;gt;
                &amp;lt;p&amp;gt;To wrap up January, we are proud to bring you the release of Firefox 85. In this version we are bringing you
                    support for the :focus-visible pseudo-class in CSS and associated devtools, and the complete removal of Flash
                    support from Firefox.&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="intro-img"&amp;gt;
                &amp;lt;img src="img/javascript.svg" alt="Logo de HTML, CSS e JS."&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;

    &amp;lt;section id="intro" class="white-bg section"&amp;gt;
        &amp;lt;div class="main-content top3-content"&amp;gt;
            &amp;lt;h2&amp;gt;news coverage and some
                surprises&amp;lt;/h2&amp;gt;
            &amp;lt;p&amp;gt;The release of Apple Silicon-based Macs at the end of last year generated a flurry of news coverage and some
                surprises at the machine’s performance. This post details some background information on the experience of
                porting Firefox to run natively on these CPUs.&amp;lt;/p&amp;gt;
            &amp;lt;p&amp;gt;We’ll start with some background on the Mac transition and give an overview of Firefox internals that needed to
                know about the new architecture, before moving on to the concept of Universal Binaries.&amp;lt;/p&amp;gt;
            &amp;lt;p&amp;gt;We’ll then explain how DRM/EME works on the new platform, talk about our experience with macOS Big Sur, and
                discuss various updater problems we had to deal with. We’ll conclude with the release and an overview of various
                other improvements that are in the pipeline.&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;


    &amp;lt;section id="grid-one" class="grid-one main-bg section"&amp;gt;
        &amp;lt;div class="main-content grid-one-content"&amp;gt;
            &amp;lt;h2 class="grid-main-heading"&amp;gt;My Grid&amp;lt;/h2&amp;gt;
            &amp;lt;p class="grid-description"&amp;gt;Uma breve descrição.&amp;lt;/p&amp;gt;

            &amp;lt;div class="grid"&amp;gt;
                &amp;lt;article&amp;gt;
                    &amp;lt;h3&amp;gt;Teste 1&amp;lt;/h3&amp;gt;
                    &amp;lt;p&amp;gt;Lorem ipsum dolor sit, amet consectetur adipisicing elit. Debitis cum delectus molestias. Atque doloribus
                        nobis laudantium esse ut, non commodi maxime distinctio veritatis unde, reprehenderit minus ad dolores
                        provident maiores.&amp;lt;/p&amp;gt;
                &amp;lt;/article&amp;gt;
                &amp;lt;article&amp;gt;
                    &amp;lt;h3&amp;gt;Teste 2&amp;lt;/h3&amp;gt;
                    &amp;lt;p&amp;gt;Lorem ipsum dolor sit, amet consectetur adipisicing elit. Debitis cum delectus molestias. Atque doloribus
                        nobis laudantium esse ut, non commodi maxime distinctio veritatis unde, reprehenderit minus ad dolores
                        provident maiores.&amp;lt;/p&amp;gt;
                &amp;lt;/article&amp;gt;
                &amp;lt;article&amp;gt;
                    &amp;lt;h3&amp;gt;Teste 2&amp;lt;/h3&amp;gt;
                    &amp;lt;p&amp;gt;Lorem ipsum dolor sit, amet consectetur adipisicing elit. Debitis cum delectus molestias. Atque doloribus
                        nobis laudantium esse ut, non commodi maxime distinctio veritatis unde, reprehenderit minus ad dolores
                        provident maiores.&amp;lt;/p&amp;gt;
                &amp;lt;/article&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;

    &amp;lt;section id="gallery" class="grid-one white-bg section"&amp;gt;
        &amp;lt;div class="main-content grid-one-content"&amp;gt;
            &amp;lt;h2 class="grid-main-heading"&amp;gt;Gallery&amp;lt;/h2&amp;gt;
            &amp;lt;p class="grid-description"&amp;gt;Uma breve descrição.&amp;lt;/p&amp;gt;

            &amp;lt;div class="grid"&amp;gt;
                &amp;lt;div class="gallery-img"&amp;gt;
                    &amp;lt;img src="http://source.unsplash.com/random/360x360?r=1" alt="random image from unsplash" /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="gallery-img"&amp;gt;
                    &amp;lt;img src="http://source.unsplash.com/random/360x360?r=2" alt="random image from unsplash" /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="gallery-img"&amp;gt;
                    &amp;lt;img src="http://source.unsplash.com/random/360x360?r=3" alt="random image from unsplash" /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="gallery-img"&amp;gt;
                    &amp;lt;img src="http://source.unsplash.com/random/360x360?r=4" alt="random image from unsplash" /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="gallery-img"&amp;gt;
                    &amp;lt;img src="http://source.unsplash.com/random/360x360?r=5" alt="random image from unsplash" /&amp;gt;
                &amp;lt;/div&amp;gt;
                &amp;lt;div class="gallery-img"&amp;gt;
                    &amp;lt;img src="http://source.unsplash.com/random/360x360?r=6" alt="random image from unsplash" /&amp;gt;
                &amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;

    &amp;lt;section id="grid-two" class="grid-one main-bg section"&amp;gt;
        &amp;lt;div class="main-content grid-one-content"&amp;gt;
            &amp;lt;h2 class="grid-main-heading"&amp;gt;My Grid&amp;lt;/h2&amp;gt;
            &amp;lt;p class="grid-description"&amp;gt;Uma breve descrição.&amp;lt;/p&amp;gt;

            &amp;lt;div class="grid"&amp;gt;
                &amp;lt;article&amp;gt;
                    &amp;lt;h3&amp;gt;Teste 1&amp;lt;/h3&amp;gt;
                    &amp;lt;p&amp;gt;Lorem ipsum dolor sit, amet consectetur adipisicing elit. Debitis cum delectus molestias. Atque doloribus
                        nobis laudantium esse ut, non commodi maxime distinctio veritatis unde, reprehenderit minus ad dolores
                        provident maiores.&amp;lt;/p&amp;gt;
                &amp;lt;/article&amp;gt;
                &amp;lt;article&amp;gt;
                    &amp;lt;h3&amp;gt;Teste 2&amp;lt;/h3&amp;gt;
                    &amp;lt;p&amp;gt;Lorem ipsum dolor sit, amet consectetur adipisicing elit. Debitis cum delectus molestias. Atque doloribus
                        nobis laudantium esse ut, non commodi maxime distinctio veritatis unde, reprehenderit minus ad dolores
                        provident maiores.&amp;lt;/p&amp;gt;
                &amp;lt;/article&amp;gt;
                &amp;lt;article&amp;gt;
                    &amp;lt;h3&amp;gt;Teste 2&amp;lt;/h3&amp;gt;
                    &amp;lt;p&amp;gt;Lorem ipsum dolor sit, amet consectetur adipisicing elit. Debitis cum delectus molestias. Atque doloribus
                        nobis laudantium esse ut, non commodi maxime distinctio veritatis unde, reprehenderit minus ad dolores
                        provident maiores.&amp;lt;/p&amp;gt;
                &amp;lt;/article&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;

    &amp;lt;section id="pricing" class="white-bg section"&amp;gt;
        &amp;lt;div class="main-content top3-content"&amp;gt;
            &amp;lt;h2&amp;gt;Pricing&amp;lt;/h2&amp;gt;
            &amp;lt;p&amp;gt;The release of Apple Silicon-based Macs at the end of last year generated a flurry of news coverage and some
                surprises at the machine’s performance. This post details some background information on the experience of
                porting Firefox to run natively on these CPUs.&amp;lt;/p&amp;gt;
            &amp;lt;p&amp;gt;We’ll start with some background on the Mac transition and give an overview of Firefox internals that needed to
                know about the new architecture, before moving on to the concept of Universal Binaries.&amp;lt;/p&amp;gt;

            &amp;lt;div class="responsive-table"&amp;gt;
                &amp;lt;table&amp;gt;
                    &amp;lt;caption&amp;gt;Pricing table&amp;lt;/caption&amp;gt;

                    &amp;lt;thead&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;th&amp;gt;Title 1&amp;lt;/th&amp;gt;
                            &amp;lt;th&amp;gt;Title 2&amp;lt;/th&amp;gt;
                            &amp;lt;th&amp;gt;Title 3&amp;lt;/th&amp;gt;
                            &amp;lt;th&amp;gt;Title 4&amp;lt;/th&amp;gt;
                            &amp;lt;th&amp;gt;Title 5&amp;lt;/th&amp;gt;
                        &amp;lt;/tr&amp;gt;
                    &amp;lt;/thead&amp;gt;

                    &amp;lt;tbody&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;td&amp;gt;Content 1&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 2&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;td&amp;gt;Content 1&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 2&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;td&amp;gt;Content 1&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 2&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Content 3&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                    &amp;lt;/tbody&amp;gt;

                    &amp;lt;tfoot&amp;gt;
                        &amp;lt;tr&amp;gt;
                            &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;
                            &amp;lt;td&amp;gt;Testando&amp;lt;/td&amp;gt;
                        &amp;lt;/tr&amp;gt;
                    &amp;lt;/tfoot&amp;gt;
                &amp;lt;/table&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;

    &amp;lt;section id="contact" class="intro main-bg section"&amp;gt;
        &amp;lt;div class="main-content intro-content"&amp;gt;
            &amp;lt;div class="intro-text-content"&amp;gt;
                &amp;lt;h2&amp;gt;January brings us Firefox 85&amp;lt;/h2&amp;gt;
                &amp;lt;p&amp;gt;To wrap up January, we are proud to bring you the release of Firefox 85. In this version we are bringing you
                    support for the :focus-visible pseudo-class in CSS and associated devtools, and the complete removal of Flash
                    support from Firefox.&amp;lt;/p&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="intro-img"&amp;gt;
                &amp;lt;img src="img/javascript.svg" alt="Logo de HTML, CSS e JS."&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div class="contact-form"&amp;gt;
                &amp;lt;fieldset class="form-grid"&amp;gt;
                    &amp;lt;legend&amp;gt;Contact me&amp;lt;/legend&amp;gt;

                    &amp;lt;div class="form-group"&amp;gt;
                        &amp;lt;label for="first-name"&amp;gt;First name&amp;lt;/label&amp;gt;
                        &amp;lt;input type="text" name="first-name" id="first-name" placeholder="Your name"&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div class="form-group"&amp;gt;
                        &amp;lt;label for="last-name"&amp;gt;last name&amp;lt;/label&amp;gt;
                        &amp;lt;input type="text" name="last-name" id="last-name" placeholder="Your last name"&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div class="form-group"&amp;gt;
                        &amp;lt;label for="email"&amp;gt;E-mail&amp;lt;/label&amp;gt;
                        &amp;lt;input type="email" name="email" id="email" placeholder="Your e-mail"&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div class="form-group full-width"&amp;gt;
                        &amp;lt;label for="message"&amp;gt;Message&amp;lt;/label&amp;gt;
                        &amp;lt;textarea name="message" id="message" cols="30" rows="10" placeholder="Your message"&amp;gt;&amp;lt;/textarea&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div class="form-group full-width"&amp;gt;
                        &amp;lt;button type="submit"&amp;gt;Send message&amp;lt;/button&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/fieldset&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/section&amp;gt;

    &amp;lt;footer id="footer" class="footer white-bg"&amp;gt;
        &amp;lt;p&amp;gt;&amp;lt;a rel="nofollow" target="_blank" href="https://beacons.page/otaviomiranda"&amp;gt;Feito com &amp;lt;span class="heart"&amp;gt;❤&amp;lt;/span&amp;gt; por Otávio Miranda&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;/footer&amp;gt;

    &amp;lt;a class="back-to-top" href="#"&amp;gt;➤&amp;lt;/a&amp;gt;

    &amp;lt;script src="js/script.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora tem que criar a rota para exibir a página. No arquivo &lt;code&gt;router.php&lt;/code&gt; dentro da pasta de config vamos escrever o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$router-&amp;gt;addRoute('/', 'App\Controller\SiteController@render');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Iniciando o servidor de desenvolvimento&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php -S localhost:8000 -t public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos acessar a página&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O resultado deve ser esse algo como a imagem abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgj0flsbzz65qqtfu6eg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgj0flsbzz65qqtfu6eg2.png" alt="Exemplo do projeto" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O projeto completo está neste &lt;a href="https://github.com/claudio1994-oliveira/site-exemple"&gt;repositório&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Próximos passos
&lt;/h2&gt;

&lt;p&gt;Bom, eu estou pretendendo criar um projeto de gerenciamento de tickets para exemplo. A aplicação terá gerenciamento de usuários, chamados e autenticação de usuários.&lt;/p&gt;

&lt;p&gt;Quer me ajudar? Assim que criar o repositório eu edito essa postagem e quem sabe escreva outro post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O My PHP MVC é um pequeno projeto que visa simplificar e estudar PHP para aplicações web simples. Saliento que o principal objetivo dele é para estudo, ou seja, não é aconselhável usa-lo em ambiente de produção - quem sabe um dia.&lt;/p&gt;

&lt;p&gt;Espero que este artigo tenha fornecido insights e inspirado você a quem sabe criar o seu próprio framework. Haaa, você pode me ajudar a melhorar o código também! Escreve nos comentários sugestões de _features _ ou melhor, manda um PR! ⭐⭐⭐&lt;/p&gt;

&lt;p&gt;Obs: Fiz uso de IA para me ajudar a escrever esse post (correções ortográficas e sugestões de tópicos) 😉&lt;/p&gt;

</description>
      <category>php</category>
      <category>webdev</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Explorando o Padrão de Projeto Template Method com Laravel e Livewire</title>
      <dc:creator>Cláudio Oliveira</dc:creator>
      <pubDate>Fri, 05 Jan 2024 00:06:39 +0000</pubDate>
      <link>https://forem.com/claudio1994oliveira/explorando-o-padrao-de-projeto-template-method-com-laravel-e-livewire-d0g</link>
      <guid>https://forem.com/claudio1994oliveira/explorando-o-padrao-de-projeto-template-method-com-laravel-e-livewire-d0g</guid>
      <description>&lt;p&gt;Olá, nesse post eu quero tentar simplificar a codificação usando o padrão &lt;em&gt;Template Method&lt;/em&gt; em uma aplicação Laravel com Livewire.&lt;/p&gt;

&lt;h2&gt;
  
  
  Template Method?
&lt;/h2&gt;

&lt;p&gt;O Template Method é um padrão de projeto que define a estrutura básica em uma classe base (superclasse), mas permite que as subclasses alterem partes específicas dessa estrutura sem mudar sua comportamento geral. Isso proporciona flexibilidade e reuso de código já que definimos comportamentos gerias na superclasse que são executados nas subclasses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://refactoring.guru/pt-br/design-patterns"&gt;Saiba mais sobre padrões de projeto aqui.&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Aplicando o Template Method
&lt;/h2&gt;

&lt;p&gt;Para exemplificar, iremos usar o famoso CRUD de posts em um blog.&lt;/p&gt;

&lt;p&gt;Dentro de um projeto Laravel criei um modelo Post e fiz a associação com o User. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['user_id', 'title', 'body'];

    public  function  user(): BelongsTo
    {
        $this-&amp;gt;belongsTo(User::class);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;User.php&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];

    protected $casts = [
        'email_verified_at' =&amp;gt; 'datetime',
        'password' =&amp;gt; 'hashed',
    ];

    public function posts(): HasMany
    {
        return $this-&amp;gt;hasMany(Post::class);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Iremos criar os componentes Livewire responsáveis pelo CRUD e nesta postagem iremos nos atentar a criação e a edição: &lt;strong&gt;Post\Create, Post\Edit&lt;/strong&gt; &lt;a href="https://dev.to/claudio1994oliveira/organizando-os-livewire-components-4bj2"&gt;(eu escrevi outro post de como costumo organizar os meus componentes livewire)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5O5e_r9o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cjyd1j7xeouby3o8hsdu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5O5e_r9o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cjyd1j7xeouby3o8hsdu.png" alt="Image description" width="265" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O componente &lt;em&gt;Create&lt;/em&gt; é responsável por criar um post e o &lt;em&gt;Edit&lt;/em&gt;  por atualizar um post existente. Os campos são simples, um título e um "corpo" da postagem.&lt;/p&gt;

&lt;p&gt;Agora iremos aplicar o &lt;em&gt;Template Method.&lt;/em&gt; Criaremos uma classe base (superclasse) para que as subclasses (Create e Edit) possam herdar diretamente dela. Nesse caso, elas deixariam de herdar da classe &lt;em&gt;Component&lt;/em&gt; do Livewire.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
namespace App\Livewire\Post;

class Create extends PostBase
{
 // Create component
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php
namespace App\Livewire\Post;

class Edit extends PostBase
{
 // Edit component
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criaremos a superclasse como abstrata para podermos "forçar" as subclasses a implementarem alguns métodos em comum, mas isso não é uma regra. Poderíamos tranquilamente criar uma classe normal com seus devidos métodos para serem herdados pelas subclasses.&lt;/p&gt;

&lt;p&gt;Para que o comportamento do Livewire funcione normalmente, a superclasse irá herdar de &lt;em&gt;Component&lt;/em&gt; do Livewire, assim a reatividade/funcionalidades providas pelo pacote continuarão funcionando normalmente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Livewire\Post;

use Illuminate\View\View;
use Livewire\Component;

abstract class PostBase extends Component
{
    public array $fields;

    protected array $rules = [
        'fields.title' =&amp;gt; 'required',
        'fields.body' =&amp;gt; 'required'
    ];

    protected array $messages = [
        'fields.*' =&amp;gt; 'The field is required.'
    ];

    public function mount(): void
    {
        $this-&amp;gt;fields = [];
    }

    abstract function render(): View;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dentro da superclasse podemos colocar tudo que é comum como validações, declaração de atributos e etc.&lt;/p&gt;

&lt;p&gt;Aproveitando que estamos usando uma classe abstrata - &lt;code&gt;abstract class PostBase {}&lt;/code&gt; - iremos criar um método abstrato - &lt;code&gt;abstract function render(): View&lt;/code&gt; -  com sua respectivas assinatura que deverá ser implementada nas subclasses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Post.php
&amp;lt;?php

namespace App\Livewire\Post;

use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\View\View;

class Create extends PostBase
{

    public function render(): View
    {
        return view('livewire.post.create');
    }

    public function store(): RedirectResponse|Redirector
    {
        $this-&amp;gt;validate();

        Post::create([
        'user_id' =&amp;gt; auth()-&amp;gt;user()-&amp;gt;id,
        ... $this-&amp;gt;fields
        ]);

        session()-&amp;gt;flash('success', 'Post successfully created.');

        return to_route('dashboard');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Edit.php
&amp;lt;?php

namespace App\Livewire\Post;

use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\View\View;

class Edit extends PostBase
{
    public Post $post;

    public function mount(): void
    {
        $this-&amp;gt;fields = $this-&amp;gt;post-&amp;gt;toArray();
    }

    public function render(): View
    {
        return view('livewire.post.edit');
    }

    public function update(): RedirectResponse|Redirector
    {
        $this-&amp;gt;validate();

        $this-&amp;gt;post-&amp;gt;update($this-&amp;gt;fields);

        session()-&amp;gt;flash('success', 'Post successfully updated.');

        return to_route('dashboard');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A sobrescrita do método é livre por parte do desenvolvedor, caso necessite. Por isso o &lt;em&gt;Template Method&lt;/em&gt; é tão produtivo, pois evita repetição de código e fluidez no fluxo do desenvolvimento. Neste caso, sobrescrevemos o método &lt;code&gt;mount()&lt;/code&gt; na classe Edit para inicializarmos os campos com os dados que recebemos na criação do componente.&lt;/p&gt;

&lt;p&gt;O projeto completo deste post está no &lt;a href="https://github.com/claudio1994-oliveira/blog-laravel"&gt;github&lt;/a&gt;, se puder da uma ⭐ eu ficaria grato.&lt;/p&gt;

&lt;p&gt;Ha, fique a vontade para criticar e sugerir melhorias na aplicação do padrão. Essa é uma solução que utilizo no meu dia a dia e gostaria de aprender com você caso queira compartilhar algo 😎✌️.&lt;/p&gt;

&lt;p&gt;Abraços!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Organizando os Livewire Components</title>
      <dc:creator>Cláudio Oliveira</dc:creator>
      <pubDate>Sun, 26 Nov 2023 18:45:27 +0000</pubDate>
      <link>https://forem.com/claudio1994oliveira/organizando-os-livewire-components-4bj2</link>
      <guid>https://forem.com/claudio1994oliveira/organizando-os-livewire-components-4bj2</guid>
      <description>&lt;p&gt;Olá, nesse pequeno post eu quero compartilhar como organizo a criação dos componentes livewire nos meus projetos.&lt;/p&gt;

&lt;p&gt;Se você não conhece o Livewire, basicamente, ele faz parte do ecossistema &lt;a href="https://laravel.com/" rel="noopener noreferrer"&gt;Laravel &lt;/a&gt;e serve para criar componentes reativos sem precisar usar (ou muito pouco) javascript, dando "super-poderes" a classe em PHP. Você pode dar uma lida na &lt;a href="https://livewire.laravel.com/docs/quickstart" rel="noopener noreferrer"&gt;documentação&lt;/a&gt; para entender melhor.&lt;/p&gt;

&lt;p&gt;Bom, já faz quase dois anos que trabalho diretamente com aplicações Laravel que utilizam o Livewire para construir monolitos. O Livewire ajuda a criar toda a reatividade no &lt;em&gt;front-end&lt;/em&gt; sem sairmos do bom e velho PHP.&lt;/p&gt;

&lt;p&gt;A criação de um componente Livewire é fácil, após termos &lt;a href="https://livewire.laravel.com/docs/installation" rel="noopener noreferrer"&gt;instalado&lt;/a&gt; ele no projeto, conseguimos fazê-lo por um comando do artisan.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:livewire CreatePost&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O resultado será uma classe do nosso componente e uma &lt;strong&gt;view.blade.php&lt;/strong&gt; correspondente a essa classe.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Eis que chegamos no ponto central deste post ...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Diferentemente dos _Controllers _"normais" do Laravel, a documentação do Livewire não adota, ou melhor, não oferece nenhum padrão arquitetural para organizarmos nossos componentes. Na documentação do Laravel, por exemplo, nós conseguimos ver as sugestões dos &lt;a href="https://laravel.com/docs/10.x/controllers#resource-controllers" rel="noopener noreferrer"&gt;Resource Controllers&lt;/a&gt; que nos guiam em como nomear nossos métodos e organizar nossas rotas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcj9yq03i6y2rg6vaivc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcj9yq03i6y2rg6vaivc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Foi a partir desse modelo que comecei a padronizar a criação dos meus componentes conforme os &lt;em&gt;resource controllers&lt;/em&gt;. Deixando claro, que isso é uma sugestão. Caso você adote algo diferente ou não concorde, tudo bem!&lt;/p&gt;

&lt;p&gt;Voltando ao exemplo do Post, eu o faria da seguinte maneira:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:livewire Post\Create&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O resultado seria:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;app/Livewire/Post/Create.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Livewire\Post;

use Livewire\Component;

class Create extends Component
{
    public function render()
    {
        return view('livewire.post.create');
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;resources/views/livewire/post/create.blade.php&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
    &amp;lt;h1&amp;gt; My Component! &amp;lt;/h1&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E seguiria o mesmo raciocínio para os outros recursos, por exemplo &lt;strong&gt;show ** e **index&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:livewire Post\Show&lt;/code&gt;&lt;br&gt;
&lt;code&gt;php artisan make:livewire Post\Index&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Isso me ajudou a organizar melhor a estrutura do meu projeto já que já era familiarizado com os trabalhos dos &lt;em&gt;resource controllers&lt;/em&gt; e espero que possa ser interessante para você também. Deixa nos comentários se você concorda ou não e me da sugestões de organização do código.&lt;/p&gt;

&lt;p&gt;Um abraço!&lt;/p&gt;

</description>
      <category>php</category>
      <category>laravel</category>
      <category>livewire</category>
    </item>
  </channel>
</rss>
