Construir um sistema de comentários ao vivo em Laravel

Publicados: 2021-09-22

Para construir confiança em sua comunidade online ou blog, um elemento crucial que você vai querer é um sistema de comentários ao vivo Laravel bem projetado.

No entanto, não é fácil acertar na primeira tentativa, a menos que você confie em sistemas de comentários auto-hospedados, como Disqus ou Commento, cada um com seu próprio conjunto de desvantagens. Eles possuem seus dados, oferecem designs e personalizações limitados e, o mais importante, não são gratuitos.

Com essas limitações, se a ideia de construir seu sistema de comentários em tempo real — com os benefícios de controlar seus dados, projetar e personalizar a aparência para se adequar ao seu blog — agrada a você, continue lendo.

Este artigo ensinará como desenvolver um sistema de comentários bem projetado e em tempo real com diferentes funcionalidades de comentários. Seguindo os princípios de construção de um aplicativo de bate-papo em tempo real com Vue.js e Socket.io, usaremos Laravel, Pusher e React para desenvolver o sistema de comentários em tempo real.

Vamos mergulhar!

O que vamos construir

Construiremos um sistema de comentários em tempo real que pode ser integrado a qualquer site ou blog para criar confiança na comunidade.

Para criar confiança em sua comunidade online ou blog, um elemento crucial que você deseja é um sistema de comentários ao vivo Laravel bem projetado. Saiba como começar aqui Click to Tweet

Visão geral dos blocos de construção: Laravel, Pusher e Vue

Antes de nos aprofundarmos no desenvolvimento, vamos discutir as tecnologias que usaremos para desenvolver nosso sistema de comentários em tempo real.

Laravel

Laravel é um framework PHP orientado a MVC de código aberto. É usado para construir aplicações web PHP simples a complexas, conhecidas por sua sintaxe elegante. Aprender o que Laravel é essencial para construir este sistema de comentários.

Empurrador

O Pusher permite que os desenvolvedores criem recursos em tempo real em escala. Este artigo combinará o Laravel Echo para criar um evento de transmissão em tempo real para o servidor Pusher e exibir o conteúdo no frontend com o Vue.js.

Vue.js

Vue.js é a nossa estrutura de front-end preferida. Vue.js é uma estrutura de front-end de JavaScript progressiva conhecida por sua abordagem fácil de aprender e direta para o desenvolvimento de front-end. Usaremos Vue.js para desenvolver nosso sistema de comentários em tempo real.

Construindo o sistema de comentários

Se o sistema de comentários que descrevemos acima parece com o que você deseja, vamos seguir em frente para construí-lo.

1. Instalar e configurar Laravel, Pusher e Echo

A instalação e configuração do Laravel, Echo e Pusher é simples, pois o Laravel fez todas as tarefas em segundo plano configurando e configurando o Laravel Echo para funcionar perfeitamente com o Pusher.

Primeiramente, vamos começar instalando e configurando o Laravel, nosso framework PHP de backend. Você pode pegar uma nova instância do Laravel com este comando, desde que tenha instalado a CLI do Laravel globalmente:

 laravel new commenter

Sua nova instância do Laravel será instalada em uma pasta chamada commenter. Vamos abrir a pasta em nosso VSCode e navegar até ela em nosso terminal:

 cd commenter code .

Antes de iniciarmos nosso servidor de desenvolvimento, vamos instalar e configurar alguns pacotes necessários que serão utilizados para o projeto.

Execute este comando para instalar o Pusher PHP SDK:

 composer require pusher/pusher-php-server

Execute este comando para instalar os pacotes NPM necessários para o front-end Vue.js:

 npm install --save laravel-echo pusher-js

Em seguida, vamos configurar o Laravel Echo e Pusher. Abra seu arquivo resources/js/bootstrap.js e cole os seguintes scripts:

 window._ = require("lodash"); window.axios = require("axios"); window.moment = require("moment"); window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; window.axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; window.axios.defaults.headers.common.crossDomain = true; window.axios.defaults.baseURL = "/api"; let token = document.head.querySelector('meta[name="csrf-token"]'); if (token) { window.axios.defaults.headers.common["X-CSRF-TOKEN"] = token.content; } else { console.error("CSRF token not found"); } /** * Echo exposes an expressive API for subscribing to channels and listening * for events that Laravel broadcasts. Echo and event broadcasting * allows your team to build robust real-time web applications quickly. */ import Echo from "laravel-echo"; window.Pusher = require("pusher-js"); window.Echo = new Echo({ broadcaster: "pusher", key: process.env.MIX_PUSHER_APP_KEY, cluster: process.env.MIX_PUSHER_APP_CLUSTER, forceTLS: true });

Você notará no script acima que estamos apenas configurando a instância do Axios com nossas configurações padrão. Em seguida, vamos configurar o Laravel Echo para usar o Pusher e suas configurações.

2. Configuração e migração do banco de dados

Em seguida, vamos criar e configurar nosso banco de dados para armazenar os comentários para persistência. Usaremos o SQLite, embora você possa usar qualquer cliente de banco de dados de sua escolha.

Crie um arquivo database.sqlite dentro da pasta do banco de dados e atualize seu arquivo .env da seguinte forma:

 DB_CONNECTION=sqlite DB_DATABASE=/Users/all/paths/to/project/commenter_be/database/database.sqlite DB_HOST=127.0.0.1 DB_PORT=3306 DB_USERNAME=root DB_PASSWORD=

Em seguida, execute este comando para criar a migração de comentários e atualize-a com os seguintes scripts:

 php artisan make:migration create_comments_table

Abra o arquivo database/migrations/xxxx_create_comments_table_xxxx.php e cole este código:

 <?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateCommentsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('comments', function (Blueprint $table) { $table->id(); $table->string('content'); $table->string('author'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('comments'); } }

Isso criará uma nova tabela de banco de dados de comentários e adicionará colunas de conteúdo e autor.

Por fim, para criar a migração, execute este comando:

 php artisan migrate

3. Criando Modelos

No Laravel, os modelos são importantes - eles são a maneira mais segura de se comunicar com nosso banco de dados e lidar com o gerenciamento de dados.

Para criar um modelo em Laravel, executaremos o seguinte comando:

 php artisan make:model Comment

Em seguida, abra o arquivo app/models/Comment.php e cole o seguinte código:

 <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Comment extends Model { use HasFactory; protected $fillable = ['content', 'author']; } O array $fillable nos permite criar e atualizar o modelo em massa.

4. Criando Controladores

Os controladores são cruciais porque abrigam toda a lógica, negócios e outros de nossos aplicativos, então vamos criar um para lidar com a lógica de comentários:

 php artisan make:controller CommentController

Em seguida, abra o arquivo app/Http/Controllers/CommentController.php e cole o seguinte código:

 <?php namespace App\Http\Controllers; use App\Models\Comment; use App\Events\CommentEvent; use Illuminate\Http\Request; class CommentController extends Controller { // public function index() { return view('comments'); } public function fetchComments() { $comments = Comment::all(); return response()->json($comments); } public function store(Request $request) { $comment = Comment::create($request->all()); event(new CommentEvent($comment)); return $comment; } }

O controlador tem três métodos diferentes: retornar uma visualização de comentários, buscar todos os comentários e armazenar um novo comentário, respectivamente. Mais importante, acionamos um evento cada vez que armazenamos um novo comentário, que o frontend ouvirá para atualizar a página relevante com o novo comentário em tempo real usando Pusher e Laravel Echo.

5. Criando Rotas

Para configurar nossas rotas corretamente, precisaremos atualizar muitos arquivos, então vamos começar.

Primeiramente, vamos atualizar o arquivo api.php na pasta de rotas. Abra o arquivo e adicione o seguinte código:

 use App\Http\Controllers\CommentController; //... Route::get('/', [CommentController::class, 'index']); Route::get('/comments', [CommentController::class, 'fetchComments']); Route::post('/comments', [CommentController::class, 'store']);

Em seguida, abra o arquivo channels.php na mesma pasta e adicione o seguinte código para autorizar o evento que disparamos anteriormente:

 Broadcast::channel('comment', function ($user) { return true; });

Em seguida, abra o arquivo web.php na mesma pasta e adicione o seguinte código para redirecionar nossa solicitação para a página inicial, onde o Vue.js irá buscá-la:

 use App\Http\Controllers\CommentController; //... Route::get('/', [CommentController::class, 'index']);

Por fim, criaremos um novo arquivo blade na pasta resources/views chamado comments.blade.php e adicionaremos o seguinte código:

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Commenter</title> <meta name="csrf-token" content="{{ csrf_token() }}"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css" /> <style> .container { margin: 0 auto; position: relative; width: unset; } #app { width: 60%; margin: 4rem auto; } .question-wrapper { text-align: center; } </style> </head> <body> <div> <div class="container"> <div class="question-wrapper"> <h5 class="is-size-2"> What do you think about <span>Dogs</span>?</h5> <br> <a href="#Form" class="button is-medium has-shadow has-text-white">Comment</a> </div> <br><br> <comments></comments> <new-comment></new-comment> </div> </div> <script async src="{{mix('js/app.js')}}"></script> </body> </html>

O script adiciona um título de postagem e um componente Vue para exibir e adicionar novos comentários ao título de postagem criado acima.

Execute os seguintes comandos para testar se você obteve tudo corretamente:

 npm run watch php artisan serve

Se você for apresentado a esta página, você está pronto para passar para a próxima etapa deste artigo.

Precisa de uma solução de hospedagem que lhe dê uma vantagem competitiva? Kinsta cobre você com velocidade incrível, segurança de última geração e dimensionamento automático. Confira nossos planos

Sistema de comentários ao vivo em Laravel
Sistema de comentários ao vivo em Laravel

6. Configurando o Vue (Frontend)

Vamos criar e configurar nossa instância Vue para criar e exibir todos os comentários feitos neste post.

Começaremos configurando nossa loja Vuex. Crie os seguintes arquivos na pasta resource/js/store.

Criar estado de comentário

Crie actions.js e adicione o seguinte código:

 let actions = { ADD_COMMENT({ commit }, comment) { return new Promise((resolve, reject) => { axios .post(`/comments`, comment) .then(response => { resolve(response); }) .catch(err => { reject(err); }); }); }, GET_COMMENTS({ commit }) { axios .get("/comments") .then(res => { { commit("GET_COMMENTS", res.data); } }) .catch(err => { console.log(err); }); } }; export default actions;

O arquivo Action faz uma chamada para o endpoint de comentário no back-end.

Em seguida, crie um arquivo getters.js e adicione o seguinte código:

 let getters = { comments: state => { return state.comments; } }; export default getters;

O arquivo Getter é usado para recuperar todos os comentários no estado.

Crie o arquivo mutations.js e cole-o no código a seguir:

 let mutations = { GET_COMMENTS(state, comments) { state.comments = comments; }, ADD_COMMENT(state, comment) { state.comments = [...state.comments, comment]; } }; export default mutations;

Em seguida, crie um arquivo state.js e cole-o no código a seguir:

 let state = { comments: [] }; export default state;

Por fim, adicionaremos tudo ao arquivo index.js exportado para a instância Vue, criaremos um arquivo index.js e adicionaremos o seguinte:

 import Vue from "vue"; import Vuex from "vuex"; import actions from "./actions"; import mutations from "./mutations"; import getters from "./getters"; import state from "./state"; Vue.use(Vuex); export default new Vuex.Store({ state, mutations, getters, actions });

Criar componentes

Por fim, vamos criar nossos componentes de comentários para exibir e adicionar novos comentários. Vamos começar criando o componente de comentário único.

Crie uma pasta na pasta resource/js chamada components, adicione o comment.vue e adicione o seguinte código:

 <template> <li class="comment-wrapper animate slideInLeft"> <div class="profile"> </div> <div class="msg has-shadow"> <div class="msg-body"> <p class="name"> {{ comment.author }} <span class="date">{{ posted_at }}</span> </p> <p class="content">{{ comment.content }}</p> </div> </div> </li> </template> <script> export default { name: "Comment", props: ["comment"], computed: { posted_at() { return moment(this.comment.created_at).format("MMMM Do YYYY"); }, }, }; </script> <style lang="scss" scoped> .comment-wrapper { list-style: none; text-align: left; overflow: hidden; margin-bottom: 2em; padding: 0.4em; .profile { width: 80px; float: left; } .msg-body { padding: 0.8em; color: #666; line-height: 1.5; } .msg { width: 86%; float: left; background-color: #fff; border-radius: 0 5px 5px 5px; position: relative; &::after { content: " "; position: absolute; left: -13px; top: 0; border: 14px solid transparent; border-top-color: #fff; } } .date { float: right; } .name { margin: 0; color: #999; font-weight: 700; font-size: 0.8em; } p:last-child { margin-top: 0.6em; margin-bottom: 0; } } </style>

Em seguida, crie o seguinte arquivo chamado comments.vue na mesma pasta e adicione o seguinte código:

 <template> <div class="container"> <ul class="comment-list"> <Comment :key="comment.id" v-for="comment in comments" :comment="comment" ></Comment> </ul> </div> </template> <script> import { mapGetters } from "vuex"; import Comment from "./Comment"; export default { name: "Comments", components: { Comment }, mounted() { this.$store.dispatch("GET_COMMENTS"); this.listen(); }, methods: { listen() { Echo.channel("comment").listen("comment", (e) => { console.log(e); this.$store.commit("ADD_COMMENT", e); }); }, }, computed: { ...mapGetters(["comments"]), }, }; </script> <style scoped> .comment-list { padding: 1em 0; margin-bottom: 15px; } </style>

Por fim, crie um arquivo chamado NewComment.vue e adicione o seguinte código:

 <template> <div class="box has-shadow has-background-white"> <form @keyup.enter="postComment"> <div class="field has-margin-top"> <div class="field has-margin-top"> <label class="label">Your name</label> <div class="control"> <input type="text" placeholder="Your name" class="input is-medium" v-model="comment.author" /> </div> </div> <div class="field has-margin-top"> <label class="label">Your comment</label> <div class="control"> <textarea name="comment" class="input is-medium" autocomplete="true" v-model="comment.content" placeholder="lorem ipsum" ></textarea> </div> </div> <div class="control has-margin-top"> <button :class="{ 'is-loading': submit }" class="button has-shadow is-medium has-text-white" :disabled="!isValid" @click.prevent="postComment" type="submit" > Submit </button> </div> </div> </form> <br /> </div> </template> <script> export default { name: "NewComment", data() { return { submit: false, comment: { content: "", author: "", }, }; }, methods: { postComment() { this.submit = true; this.$store .dispatch("ADD_COMMENT", this.comment) .then((response) => { this.submit = false; if (response.data) console.log("success"); }) .catch((err) => { console.log(err); this.submit = false; }); }, }, computed: { isValid() { return this.comment.content !== "" && this.comment.author !== ""; }, }, }; </script> <style scoped> .has-margin-top { margin-top: 15px; } </style>

Agora, abra o arquivo app.js e adicione o seguinte código para registrar os componentes Vue que você criou anteriormente:

 // resource/js/app.js require("./bootstrap"); window.Vue = require("vue"); import store from "./store/index"; Vue.component("comment", require("./components/Comment")); Vue.component("comments", require("./components/Comments")); Vue.component("new-comment", require("./components/NewComment")); const app = new Vue({ el: "#app", store });
Quer construir seu próprio sistema de comentários personalizado? Este post tem tudo que você precisa para começar Click to Tweet

Resumo

E é isso! Você acabou de aprender como construir um sistema de comentários ao vivo para o seu site usando Laravel.

Discutimos os benefícios de criar e gerenciar um sistema de comentários em sua busca para criar confiança em sua comunidade ou blog. Também exploramos como desenvolver um sistema de comentários bem projetado e em tempo real desde o início, utilizando diferentes funcionalidades de comentários.

Você pode clonar o código-fonte deste projeto neste repositório do Github.

O que você acha do sistema de comentários ao vivo do Laravel que construímos juntos? Deixe-nos saber nos comentários!