Adding Dynamic Behavior to Stubs in Laravel: Step-by-Step Guide

A Comprehensive Guide to Implementing Dynamic Features in Laravel Stubs

techiydude
6 min readNov 30, 2024

Introduction to Laravel Stubs

Laravel stubs are powerful tools for generating boilerplate code. But what if you could make them smarter, more adaptable, and tailored to your specific project needs? This guide walks you through the stepwise process of adding dynamic behavior to stubs in Laravel.

Understanding the Stub Files

Default Stub Files Provided by Laravel

Laravel's core contains a set of default stub files. These include stubs for controllers, models, policies, migrations, factories, etc.

Common Use Cases for Stub Customization

Developers often customize stubs to:

  • Add namespaces or imports.
  • Modify default class properties or methods.
  • Predefine specific coding standards or design patterns.

If you want to know about Stub in detail. You can check Stub in Laravel.

Why Add Dynamic Behavior to Stubs?

When I started working with stubs, I found myself wondering, Why do we need this dynamic behavior? You might be asking the same question: “Why would I need dynamic behavior in stubs?” The answer is straightforward: flexibility. With dynamic stubs, you can:

Automatically adjust generated code based on user input.

Inject logic into your generated files, saving you time on repetitive edits.

Tailor generated code to specific conditions in your project.

Increase consistency across the entire project by ensuring stubs follow your project’s architecture.

AIMING

First, let’s understand what we’re trying to accomplish. In the next step, we’ll demonstrate how to create dynamic behavior for the stub using an example. In this example, we’ll create a custom command. When we run the command, it will prompt us to enter a method name and a response. Once we provide those, the method and response will be created dynamically in the controller.

Step-by-Step Guide to Adding Dynamic Behavior

Step 1: Publish Default Stubs

To begin customizing stubs, you first need to publish Laravel’s default stubs into your project.

php artisan stub:publish

What Happens?

This command copies Laravel’s default stubs into a stubs directory at the root of your project. These files are now yours to modify.

Step 2: Locate and Edit a Stub

After publishing, navigate to the stubs directory and open a stub file.

Example: Controller Stub

File path: stubs/controller.plain.stub

Default content:

// controller.plain.stub
<?php

namespace {{ namespace }};

use {{ rootNamespace }}Http\Controllers\Controller;
use Illuminate\Http\Request;

class {{ class }} extends Controller
{


}

Modify it to add custom placeholders:

// controller.plain.stub
<?php

namespace {{ namespace }};

use {{ rootNamespace }}Http\Controllers\Controller;
use Illuminate\Http\Request;

class {{ class }} extends Controller
{
{{ methods }}

}

Step 3: Create a Custom Artisan Command

Laravel’s Artisan commands allow you to extend functionality, such as generating files dynamically from your customized stubs.

Generate a Command:

php artisan make:command MakeCustomController

After running this command, a command file will be created inside the console folder.

path : app > Console > Commands > MakeCustomController

Update the Command Logic

Open the generated command file: app/Console/Commands/MakeCustomController.php. Modify it to link with your custom stub and replace placeholders dynamically.

Now break down the above code

Purpose:
The MakeCustomController class extends Laravel's GeneratorCommand class to streamline creating custom controllers with dynamically added methods.

Namespace Declaration:

  • namespace App\Console\Commands;: This defines the namespace for the command class, which helps to organize your code in Laravel.

Namespace Definition:

  • protected function getDefaultNamespace($rootNamespace):
    Sets the default namespace for the generated controller to App\Http\Controllers.

Command Properties:

  • protected $name = 'make:custom-controller';: Defines the name of the custom Artisan command (php artisan make:custom-controller).
  • protected $description = 'Create a custom controller with multiple dynamic methods';: A brief description of what this command does.
  • protected $type = 'Controller';: Defines the type of class the command will generate (in this case, a Controller).

getStub Method:

  • protected function getStub(): This method returns the path to the stub file (controller.stub), which will be used as the template for the generated controller.
  • base_path('stubs/controller.stub'): Locates the controller.stub file in the stubs folder of your project. This file defines the base structure of the generated controller.

buildClass Method:

  • protected function buildClass($name): This method is responsible for generating the class content. It customizes the controller template based on user input.

Dynamic Method Creation:

  • $methodArray = [];: Initializes an array to store the dynamically generated methods.
  • while($this->confirm('Do you want to Add Method ? ',true)): Asks the user if they want to add a new method to the controller. If the user responds with "yes" (true), the loop continues.
  • $methodName = $this->ask('Enter the method name');: Prompts the user to enter the method name.
  • $response = $this->ask('Enter the response content for ' . $methodName);: Prompts the user to enter the response content for the method.
  • $methodsArray[] = $this->generateMethod($methodName, $response);: Adds the generated method (based on user input) to the methodsArray.

Method String Assembly:

  • $methodsString = implode("\n\n", $methodsArray);: Combines all the generated methods into one string, separating them with new lines.
  • $replace = ['{{ methods }}' => $methodsString];: Prepares the placeholder {{ methods }} in the stub file to be replaced with the dynamically generated methods string.

Replace Placeholder in Stub:

  • return str_replace(array_keys($replace), array_values($replace), parent::buildClass($name));: Replaces the {{ methods }} placeholder in the stub with the generated methods and returns the final class code.

generateMethod Method:

  • protected function generateMethod($methodName, $response): This method generates a single method based on the $methodName and $response parameters.
  • Heredoc Syntax:
  • The method is wrapped in a Heredoc (<<<EOD) to format the generated method correctly.
  • The method body returns the response provided by the user.

Step 4: Register the Command

For the new command to work, register it in the bootstrap/app.php file in Laravel 11 but in the previous version register it in the Kernel.php file.

Laravel 11.

In the previous Version Path: app/Console/Kernel.php

Add your command to the $commands array:

protected $commands = [  
\App\Console\Commands\MakeCustomController::class,
];

Step 5: Test the Custom Command

Run your new Artisan command to see dynamic stubs in action:

Example Command:

php artisan make:custom-controller TechiedudeController

Output:

A new controller will be generated with placeholders replaced dynamically:

output

Conclusion

By adding dynamic behavior to stubs, you elevate Laravel’s scaffolding capabilities to the next level. Whether you’re tailoring templates for a large project or simply automating repetitive tasks, dynamic stubs save time, enforce consistency, and make your development workflow more efficient.

What customizations have you tried in Laravel stubs? Share your experiences and stay tuned for more Laravel insights!

If you enjoyed what you read & found it insightful, please consider supporting me here Your support is greatly appreciated!

Thanks for sticking around! If you found this helpful, don’t forget to give it a clap 👏. And hit that subscribe button to stay updated with more content 🔔.

If you need additional help, please contact me 🤠.

✉️ Send me an email

🤝Contact me on LinkedIn

📮 Contact me on Twitter

Thank you very much for reading, I appreciate your time.

--

--

techiydude
techiydude

Written by techiydude

I’m a developer who shares advanced Laravel and Node.js insights on Medium.

Responses (3)