The essential news about content management systems and mobile technology. Powered by Perfect Publisher and XT Search for Algolia.
The News Site publishes posts to the following channels: Facebook, Instagram, Twitter, Telegram, Web Push, Tumblr, and Blogger.
The Laravel team released v11.13 mid-week last week and v11.14
this week. These releases add new string methods like
chopStart
and chopEnd
, Commonmark
extension support with Laravel's String markdown method, a
Number::pairs()
method, and more.
chopStart
and chopEnd
(v11.13)Tim MacDonald contributed two string methods for
chopping characters off the beginning or end of a string. The
chopStart
and chopEnd
methods are
available using the Str
o Stringable` class:
Str::chopEnd('path/to/file.php', '.php');
// "path/to/file"
Str::chopStart('https://laravel.com', ['https://', 'https://']);
// laravel.com
Str::markdown()
and
the Stringable ClassTony Lea contributed support for passing Commonmark
extensions as a third parameter to the the
Str::markdown()
method:
$html = Str::markdown($markdown_contents, [], [
new AttributesExtension(),
new TaskListExtension(),
]);
In Laravel 11.14, Luke
Downing followed up Tony Lea's contribution by adding support
for Commonmark extensions to the Stringable
class:
$html = str('# My Heading')->markdown(
extensions: [new HeadingPermalinksExtension()]
);
@Iman added the Macroable
trait in
the TokenGuard
class to support custom macros on this
guard. See Pull Request #51922 for details.
Number::pairs()
(v11.13)Adam Campbell contributed the
Number::pairs()
method that " provides the ability to
'split' a number into pairs of min/max values. It's sort of like
sliding, except the method will determine the values for you.":
$output = Number::pairs(25, 10);
// [[1, 10], [11, 20], [21, 25]]
$output = Number::pairs(25, 10, 0);
// [[0, 10], [10, 20], [20, 25]]
$output = Number::pairs(10, 2.5, 0)
// [[0, 2.5], [2.5, 5.0], [5.0, 7.5], [7.5, 10.0]]
SensitiveParameter
Attribute (v11.14)Philip Iezzi contributed updates to Laravel to attempt to mark sensitive parameters with PHP >= 8.2's SensitiveParameter attribute. This is an excellent reminder to leverage this attribute in application code if you run PHP >= 8.2.
See Pull Request #51940 for details.
artisan serve
CommandSeth Phat contributed improvements to the
artisan serve
command:
Requests that take less than 1 second now print the time in
milliseconds instead of 0s
:
Laravel 11.13 was released mid-week last week so the following release notes are from both versions. You can see the complete list of new features and updates below and the diff between 11.12.0 and 11.14.0 on GitHub. The following release notes are directly from the changelog:
mapSpread
Method in
Arr
Class & Remove Warning from IDE by @lmottasin in https://github.com/laravel/framework/pull/51952SensitiveParameter
attribute by @onlime in
https://github.com/laravel/framework/pull/51940Stringable
class. by @lukeraymonddowning in https://github.com/laravel/framework/pull/51932HttpResponseException
by @hafezdivandari in https://github.com/laravel/framework/pull/51968$queue
as nullable by @timacdonald in https://github.com/laravel/framework/pull/51912Macroable
trait on TokenGuard by @imanghafoori1 in https://github.com/laravel/framework/pull/51922Str::chopStart
and
Str::chopEnd
by @timacdonald
in https://github.com/laravel/framework/pull/51910The post New String Helpers and ServeCommand Improvements in Laravel 11.14 appeared first on Laravel News.
Join the Laravel Newsletter to get all the latest Laravel articles like this directly in your inbox.
Read more https://laravel-news.com/laravel-11-14-0
Managing multiple Laravel applications can be challenging, especially when it comes to modifying each app individually. For instance, if you wanted to add social authentication or change the user login process, you would find yourself changing the functionality in several places. Wouldn't it be more efficient if your authentication functionality was centralized? Imagine simply flipping a switch when you need a new feature or you need to incorporate a new social provider. That’s exactly why we created DevDojo Auth.
DevDojo Auth is a free, open-source project that provides you with customizable authentication pages for your Laravel app. It's compatible with any Laravel application (version 10.x or higher) and any of the available starter kits.
Setting up is really simple. Once you have a fresh Laravel application ready, you can install the package using Composer:
composer require devdojo/auth
Next, you’ll want to publish the assets, configs, and more:
php artisan vendor:publish --tag=auth:assets
php artisan vendor:publish --tag=auth:config
php artisan vendor:publish --tag=auth:ci
php artisan vendor:publish --tag=auth:migrations
Lastly, you need to run the migrations, and then extend the DevDojo User model.
php artisan migrate
App\Models\User.php
:use Devdojo\Auth\Models\User as AuthUser;
class User extends AuthUser
That's it! You're now ready to begin onboarding users. However, if you wish to customize the pages with your own colors and logo, please continue reading.
After installing this package, you can access a simple setup
page at /auth/setup
.
From this setup page, you can change the appearance, add social providers, adjust the language copy, and modify settings related to your authentication functionality.
This package offers many common authentication pages to help your users authenticate with your app. Plus, the user experience of these pages will maintain your professional image and encourage your users to return.
Here is the list of authentication pages you will have available in your application after installation.
You can learn more about these pages by visiting the documentation
Adding social authentication with this package is very simple.
You simply need to obtain the CLIENT_ID
and
CLIENT_SECRET
for each provider you wish to include.
Then, go to the social providers page on the setup
screen and activate the desired social providers.
Bring up your login and/or registration page and you’ll see that the social providers are locked and loaded, ready to authenticate user from their favorite social networks.
There are so many other features you can take advantage of with this package. One of which is the Github action workflows. You can publish CI files to your application and have them run everytime a new PR is opened. This package ships with Pest and Dusk tests to make sure your authentication is fully operational at all times ✨
Be sure to visit the Devdojo Auth official documentation to learn more.
The post Auth Screens for Your Laravel Apps appeared first on Laravel News.
Join the Laravel Newsletter to get all the latest Laravel articles like this directly in your inbox.
Read more https://laravel-news.com/laravel-auth-screens
Inertia Table is the ultimate table for Inertia.js with built-in query builder support. Inertia Table is included with the premium Inertia UI, a suite of packages designed for Laravel, Vue, and Tailwind CSS created by Pascal Baljet. The table component makes it super easy to build tables based on your Eloquent Models with the following features:
You can create class-based tables using the provided
make:inertia-table
command, and you can also use the
package's anonymous table builder on the fly:
use App\Models\User;
use InertiaUI\Table\Columns;
use InertiaUI\Table\Filters;
class UsersController
{
public function index()
{
return inertia('Users', [
'users' => Table::build(
resource: User::class,
columns: [
Columns\TextColumn::make('name'),
],
filters: [
Filters\TextFilter::make('name'),
],
),
]);
}
}
At the time of writing, this package requires either MySQL 8, PostgreSQL 14, or SQLite 3, as well as Tailwind CSS 3.4+ and Vue 3.4+ with a React version in the works.
A demo is available to see Inertial Table in action at table-demo.inertiaui.com. You can get started with Inertia.js Table by purchasing a license (valid for a single project) on the Inertia Table website.
The post Build Tables Based on Eloquent Models with Inertia Table appeared first on Laravel News.
Join the Laravel Newsletter to get all the latest Laravel articles like this directly in your inbox.
Read more https://laravel-news.com/inertia-table
Laravel, the web artisan's favorite PHP framework, has just got a whole new powerful tool in its arsenal: Reverb. Among the official packages of Laravel, this WebSocket server application would seamlessly let you integrate real-time features in your Laravel-based applications, thereby taking interaction to a whole new level.
Reverb acts as a mediator between your Laravel-based application and its users. It establishes two-way, real-time communication based on WebSockets technology that allows web pages to receive updates on the server without a complete page refresh. This means that your users experience your application more dynamically and responsively.
Blazing Speed: Provides outstanding performance for real-time information with no lags.
Scalability: Grow with your applications to handle increased user traffic.
Seamless Integration: It works with broadcasting features added to Laravel and Laravel Echo to make development simple.
Push Updates: Push updates, messages, or events to clients to share your information instantly.
Built-in Security: Data encryption and authentication assurance for security communication
With Laravel Reverb, you can build dynamic chat applications. The messages are posted instantly, making users involved comprehensively. Here's a breakdown of the steps involved:
Ensure you have a Laravel application set up (version 11 or above is recommended).
If you're starting fresh, use composer create-project
laravel/laravel your-chat-app-name
.
Install Laravel Reverb by running the following command:
php artisan install:broadcasting
Once you’ve installed Reverb, you can now modify its
configuration from the config/reverb.php
file. To
establish a connection to Reverb, a set of Reverb “application”
credentials must be exchanged between the client and server. These
credentials are configured on the server and are used to verify the
request from the client. You can define these credentials using the
following environment variables:
BROADCAST_DRIVER=reverb
REVERB_APP_ID=my-app-id
REVERB_APP_KEY=my-app-key
REVERB_APP_SECRET=my-app-secret
It also automatically creates echo.js
in the
resources/js
directory.
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
});
Follow the Laravel documentation for configuration steps specific to your application server https://laravel.com/docs/11.x/reverb
You can launch the Reverb server by using the
reverb:start
Artisan command:
php artisan reverb:start
By default, the Reverb server will be started at
0.0.0.0:8080
, which makes it accessible from all
network interfaces.
If you want to set a specific host or port, you can use the
–host
and –port
options when starting the
server.
php artisan reverb:start --host=127.0.0.1 --port=9000
You can also define REVERB_SERVER_HOST
and
REVERB_SERVER_PORT
environment variables in your
application’s .env
configuration file.
Open your .env
file and adjust the settings to set
up your database. Here’s an example using SQLite for
simplicity:
DB_CONNECTION=sqlite
DB_DATABASE=/path/to/database.sqlite
You can create an SQLite database by simply running:
touch /path/to/database.sqlite
For this demo, we’ll create five predefined rooms. Let’s start
by generating a model ChatMessage
with migration for a
chat_messages
table.
php artisan make:model ChatMessage --migration
To make it simpler, only create name attributes for this model and migrate it.
Schema::create('chat_messages', function (Blueprint $table) {
$table->id();
$table->foreignId('receiver_id');
$table->foreignId('sender_id');
$table->text('text');
$table->timestamps();
});
php artisan migrate
Now, let's add the necessary relationships in the
ChatMessage
model. Open the
ChatMessage.php
file in the app/Models
directory and update it as follows:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ChatMessage extends Model
{
use HasFactory;
protected $fillable = [
'sender_id',
'receiver_id',
'text'
];
public function sender()
{
return $this->belongsTo(User::class, 'sender_id');
}
public function receiver()
{
return $this->belongsTo(User::class, 'receiver_id');
}
}
To handle the broadcasting of messages, we'll create an event
called MessageSent
. This event will implement
Laravel's ShouldBroadcastNow
interface, which allows
for immediate broadcasting over WebSockets without queuing. Follow
these steps to create and set up the event:
Create a new PHP file in the App\Events
directory
and name it MessageSent.php
.
Open the newly created file and add the following code:
<?php
namespace App\Events;
use App\Models\ChatMessage;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcastNow
{
use Dispatchable;
use InteractsWithSockets;
use SerializesModels;
/**
* Create a new event instance.
*/
public function __construct(public ChatMessage $message)
{
//
}
/**
* Get the channels the event should broadcast on.
*
* @return array<int, \Illuminate\Broadcasting\Channel>
*/
public function broadcastOn(): array
{
return [
new PrivateChannel("chat.{$this->message->receiver_id}"),
];
}
}
The channels.php
file in Laravel applications plays
a crucial role in defining broadcast channels used for real-time
communication features.
<?php
use Illuminate\Support\Facades\Broadcast;
Broadcast::channel('chat.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
This code defines a private channel named chat.{id}
using Laravel's Broadcast
facade. Private channels
restrict access based on user authentication and authorization
logic.
1. Chat Room Route:
Route::get('/chat/{friend}', function (User $friend) {
return view('chat', [
'friend' => $friend
]);
})->middleware(['auth'])->name('chat');
This route is responsible for rendering the chat interface. It
accepts a dynamic parameter {friend}
representing the
user's chat partner.
3. Get Chat Messages Route:
Route::get('/messages/{friend}', function (User $friend) {
return ChatMessage::query()
->where(function ($query) use ($friend) {
$query->where('sender_id', auth()->id())
->where('receiver_id', $friend->id);
})
->orWhere(function ($query) use ($friend) {
$query->where('sender_id', $friend->id)
->where('receiver_id', auth()->id());
})
->with(['sender', 'receiver'])
->orderBy('id', 'asc')
->get();
})->middleware(['auth']);
This route retrieves chat messages exchanged between the
authenticated user and the specified friend
({friend}
). The query ensures it retrieves messages
where either the user is the sender or receiver, including both
directions of the conversation.
4. Send Chat Message Route:
Route::post('/messages/{friend}', function (User $friend) {
$message = ChatMessage::create([
'sender_id' => auth()->id(),
'receiver_id' => $friend->id,
'text' => request()->input('message')
]);
broadcast(new MessageSent($message));
return $message;
});
After creating the message, it leverages Laravel's broadcasting
functionality using broadcast(new
MessageSent($message))
. This line broadcasts the newly
created message to all connected users through Reverb, enabling
real-time chat functionality.
To render the chat interface, you'll need to create a Blade view
file. Create a new file named chat.blade.php
in the
resources/views
directory and add the following
code:
<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800">
{{ $friend->name }}
</h2>
</x-slot>
<div class="py-12">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<chat-component
:friend="{{ $friend }}"
:current-user="{{ auth()->user() }}"
/>
</div>
</div>
</div>
</div>
</x-app-layout>
The key element here is <chat-component :friend="{{
$friend }}" :current-user="{{ auth()->user() }}" />
.
This line renders a Vue.js component named
chat-component
.
<template>
<div>
<div class="flex flex-col justify-end h-80">
<div ref="messagesContainer" class="p-4 overflow-y-auto max-h-fit">
<div
v-for="message in messages"
:key="message.id"
class="flex items-center mb-2"
>
<div
v-if="message.sender_id === currentUser.id"
class="p-2 ml-auto text-white bg-blue-500 rounded-lg"
>
{{ message.text }}
</div>
<div v-else class="p-2 mr-auto bg-gray-200 rounded-lg">
{{ message.text }}
</div>
</div>
</div>
</div>
<div class="flex items-center">
<input
type="text"
v-model="newMessage"
@keydown="sendTypingEvent"
@keyup.enter="sendMessage"
placeholder="Type a message..."
class="flex-1 px-2 py-1 border rounded-lg"
/>
<button
@click="sendMessage"
class="px-4 py-1 ml-2 text-white bg-blue-500 rounded-lg"
>
Send
</button>
</div>
<small v-if="isFriendTyping" class="text-gray-700">
{{ friend.name }} is typing...
</small>
</div>
</template>
<script setup>
import axios from "axios";
import { nextTick, onMounted, ref, watch } from "vue";
const props = defineProps({
friend: {
type: Object,
required: true,
},
currentUser: {
type: Object,
required: true,
},
});
const messages = ref([]);
const newMessage = ref("");
const messagesContainer = ref(null);
const isFriendTyping = ref(false);
const isFriendTypingTimer = ref(null);
watch(
messages,
() => {
nextTick(() => {
messagesContainer.value.scrollTo({
top: messagesContainer.value.scrollHeight,
behavior: "smooth",
});
});
},
{ deep: true }
);
const sendMessage = () => {
if (newMessage.value.trim() !== "") {
axios
.post(`/messages/${props.friend.id}`, {
message: newMessage.value,
})
.then((response) => {
messages.value.push(response.data);
newMessage.value = "";
});
}
};
const sendTypingEvent = () => {
Echo.private(`chat.${props.friend.id}`).whisper("typing", {
userID: props.currentUser.id,
});
};
onMounted(() => {
axios.get(`/messages/${props.friend.id}`).then((response) => {
console.log(response.data);
messages.value = response.data;
});
Echo.private(`chat.${props.currentUser.id}`)
.listen("MessageSent", (response) => {
messages.value.push(response.message);
})
.listenForWhisper("typing", (response) => {
isFriendTyping.value = response.userID === props.friend.id;
if (isFriendTypingTimer.value) {
clearTimeout(isFriendTypingTimer.value);
}
isFriendTypingTimer.value = setTimeout(() => {
isFriendTyping.value = false;
}, 1000);
});
});
</script>
This Vue.js component manages the chat interface's dynamic
behaviour. It displays a scrollable message list, styled
differently based on the sender (current user or friend). It
provides an input field for composing new messages and a button to
send them. It leverages axios
for making HTTP requests
to fetch initial messages and send new ones.
Real-time functionality is achieved using Laravel Echo:
It listens for broadcasted MessageSent
events to
update the message list whenever a new message arrives.
It utilizes whispers on private channels to notify the chat partner about the user's typing activity and receive similar notifications from the friend.
To run the Laravel project, we need to execute the following command:
php artisan serve
For starting front:
npm run dev
Run reverb:
php artisan reverb:start
You can find the source code for this Laravel Reverb chat implementation in the following GitHub repository: https://github.com/qirolab/laravel-reverb-chat
By utilizing Laravel Reverb, developers can ensure their applications remain responsive and dynamic, providing real-time updates and interactions that modern users expect. Happy coding!
The post Adding Real Time Chat to Laravel Using Reverb & Vue appeared first on Laravel News.
Join the Laravel Newsletter to get all the latest Laravel articles like this directly in your inbox.
Read more https://laravel-news.com/laravel-real-time-chat
“WordPress” and “plugins” are often thought to be synonymous. The two go together like peanut butter and jam, like summer and watermelon, like yin and yang . . . you get the idea. It often seems like you can’t have one without the other. While plugins are indeed one way to supercharge your WordPress.com site, the truth is that there’s a lot you can do without ever installing a plugin. In fact, I can almost guarantee that our out-of-the-box WordPress.com experience is more powerful than you think.
(Quick reminder: WordPress plugins are available and installable on our Creator and Entrepreneur plans.)
Today, we’d like to highlight six surprising things you can do with WordPress.com from the moment you start building a website.
There’s no plugin needed to make a living or earn some cash on the side by selling digital products like ebooks, songs, or photographs on WordPress.com. With our built-in payment blocks Payment Buttons, Pay with PayPal, and Donations Form, you’re one click away from collecting money on your website. Best of all? Most of these blocks can be used on any plan, including Free, the exception being the PayPal block, which requires the Explorer plan or above.
Simply connect your Stripe account to get started selling today.
Just like the spam comments and messages you’re trying to block, the number of anti-spam plugins has proliferated in recent years. Luckily, you don’t need any of them, because Akismet, an Automattic product, is baked into every WordPress.com website and provided at no extra cost. With advanced filtering that blocks 99.99% of spam, you’ll never have to worry about unwanted visitors again.
On WordPress.com websites, SSL certificates are provided free of charge and automatically installed for you. This feature provides important security against hackers and other malicious actors, particularly if your website collects user information of any kind. At other hosts, you’ll often have to either pay extra or install your own (expensive) plugin in order to add an SSL certificate. Not at WordPress.com. Learn more about our SSL process here.
Since 2009 WordPress.com has had the built-in functionality of sending new posts as emails. That’s right, you don’t need a third-party service or platform (like Mailchimp or Substack) to send newsletter emails to your audience. Using a Subscribe block gives visitors a simple and convenient way to enter their email and get your posts right to their inbox.
You can also set up paywalls (with the Paywall block) and paid content tiers, allowing for multiple subscription levels. Additionally, you can view and manage subscriber details from the Subscribers page (found under “Jetpack” on the left-side menu). Learn more at WordPress.com/newsletters.
Videos can be a vitally important part of your website and content flow, but uploading them can be a pain in the neck—if you’re not using WordPress, that is. If you’re embedding a video from another source, like Vimeo or YouTube, use our built-in blocks of the same name. And here’s a helpful tip: you don’t even need to select the block first. Simply copy and paste the video link right into the editor, and WordPress will automagically do the rest.
For embedding your original video files (.mov, .mp4, .mwv, etc.), Automattic’s very own VideoPress block offers a straightforward and robust solution. With caption and chapter support, as well as detailed data and insights on views, once you try out VideoPress you won’t look back. This feature is available on Explorer plans and above.
Well-done imagery on a website can mean the difference between an engaged visitor and a bounced visitor. Rather than experimenting with overly complicated plugins, use the various image blocks that come with WordPress. Our Gallery, Slideshow, and Image Compare blocks are especially fun and offer a range of easy-to-use customizations that don’t overwhelm. Plus, these blocks are always optimized for mobile.
This is just a sampling of what you can do with WordPress.com. We didn’t even mention some of our favorite blocks, including: table of contents, music/podcast player, countdown timer, tables, and so much more.
Ready to explore these powerful built-ins? Get started today:
Start buildingYou may still find that using plugins solves your specific needs a bit better than what’s already built into the editor. If that’s the case, consider our world-class Creator or Entrepreneur plan.
Read more https://wordpress.com/blog/2024/06/26/no-plugin-needed/