Limit Words not Characters in Laravel
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Mastering Text Limits in Laravel: Words vs. Characters
As senior developers working within the Laravel ecosystem, we often deal with data presentation challenges, especially when dealing with text fields fetched from a database. One common requirement is limiting content—whether it's by character count or word count—to ensure clean, digestible output for the end-user.
The scenario you’ve described—trying to use Str::words() in a Laravel application and grappling with where to place that logic (Controller vs. Blade)—is a classic example of navigating the separation of concerns within the MVC architecture. Let's break down the correct, most robust way to handle this in Laravel, ensuring clean code and proper scope management.
The Core Issue: Where Should Logic Reside?
The confusion arises because the Controller handles business logic and data preparation, while the Blade file handles presentation logic. When you try to use a class like Illuminate\Support\Str directly in the Controller without proper setup, PHP throws an error because that class isn't automatically available in the scope of your controller method unless explicitly imported.
The key principle here is: Data manipulation and transformation should generally happen on the backend (Controller or Model), not purely for presentation in the view. This keeps your views clean and your controllers focused on data flow.
Solution 1: Processing Data in the Controller (Best Practice)
The most idiomatic Laravel approach is to perform any necessary data manipulation just before passing the data to the view. This ensures that the view only deals with the final, formatted output, making debugging easier.
In this approach, you bring the necessary classes into scope within your controller method, and then modify the Eloquent collection or individual items before returning the view.
Here is how you correctly apply the logic in your Controller:
<?php
namespace App\Http\Controllers;
use App\Testimonial;
use Illuminate\Http\Request;
use Illuminate\Support\Str; // Import the necessary class
class TestimonialController extends Controller
{
public function index()
{
// Fetch all testimonials
$testimonials = Testimonial::all();
// Process the data before sending it to the view
$processedTestimonials = $testimonials->map(function ($testimonial) {
// Limit the testimonial text to 25 words
$testimonial->short_description = Str::words($testimonial->description, 25);
return $testimonial;
});
return view('testimonials.index', compact('processedTestimonials'));
}
}
Why this is better: By using the map function on your collection, you are transforming the data layer before it ever reaches the view. This adheres to the principle that controllers manage data flow and manipulation, which aligns perfectly with Laravel's philosophy regarding Eloquent relations and data handling. As we explore more advanced features in Laravel, understanding this data pipeline is crucial for building scalable applications on platforms like Laravel Company.
Solution 2: Using Helpers in the Blade View (For Presentation)
If you prefer to keep the controller strictly focused on fetching data and let the view handle all presentation formatting, you can certainly use the Str class directly in Blade. However, you must ensure the class is accessible.
The original method you tried using @php use Illuminate\Support\Str; @endphp is a valid way to bring classes into scope within a specific block of Blade code. It ensures that the helper functions are available only where needed.
{{-- In your view file (e.g., index.blade.php) --}}
@php use Illuminate\Support\Str; @endphp
@foreach ($testimonial as $testimonial)
<div>
{!! nl2br(e(Str::words($testimonial->description, 25))) !!}
</div>
@endforeach
While this works, relying heavily on these inline PHP blocks within views can sometimes make the view layer less readable. For complex data transformations, as demonstrated in Solution 1, preparing the data in the controller is often a cleaner separation of concerns.
Conclusion
To summarize, while both methods achieve the goal of limiting text to 25 words, processing the data in the Controller using Eloquent methods (like map) and utilizing helper classes like Illuminate\Support\Str there is the recommended Laravel practice. This keeps your application modular, testable, and adheres to the principle of separating business logic from presentation. Always aim to let your models and controllers handle the heavy lifting of data transformation before rendering it in the Blade view.