Our Latest Blog Posts

latest-post

Businesses are always looking for new ways to improve efficiency and promote smoother customer service. A relatively new trend that has become popular over the past several years is using ChatGPT, a next-level chatbot based on OpenAI's language models. ChatGPT humanizes responses with a chorus of text. Text responses are human-made personas. This often quickly revolutionizes how businesses interact with their customers.

Understanding the Role of ChatGPT in Business

So, let us start with the basics of ChatGPT before discussing how to customise it and what it can do for you. ChatGPT is a question answering language model that leverages the power of deep learning algorithms to craft human-like responses for addressing user queries. These models utilise a huge dataset of text from the internet to produce coherent and contextually related answers.

One of the most important strengths of ChatGPT is its ability to perform a diverse range of functions, such as responding to FAQs or giving suggestions. Businesses spanning a broader array of industries could utilise it in different ways thanks to its flexibility.

The Basics of ChatGPT

How does ChatGPT work with input and output? Users will type in their questions or ask the chatbot, and ChatGPT then replies with a suitable answer based on its understanding of all text. Usually facilitated by a chat interface built into a website or app.

ChatGPT's amazing ability to mimic human conversation often convinces users that they are talking to a real person. Human-like behaviour is made possible by a combination of pre-training on a wide range of text data and fine-tuning on specific custom datasets.

The Importance of Customization in Chatbots

Even though ChatGPT provides a powerful out-of-the-box solution, customization is an essential part of leveraging its full potential for business use. Adjusting the chatbot to your brand’s tone and specific needs is effective for improving customer satisfaction and making the human-computer interaction more personalised.

First, customization helps businesses in creating a chatbot that fits their brand needs. Over time, a chatbot is likely to communicate with hundreds or thousands of customers, and for a business, it is important to retain a high level of customer recognising the brand. A well-customised chatbot will speak with a customer using a language, tone, and style specific to a brand, and this will positively affect the customer recognition of a brand.

Second, customization is also highly useful for training ChatGPT to be a more competent assistant in a specific industry. For example, it can be trained on specific medical terms and how to respond to patients’ queries in the medical field. The same can be said about an e-commerce field: after customisation, an e-commerce chatbot will have a chance to provide a customer with more specific information, such as tailored product recommendations, based on their product-viewing history and preferences.

In conclusion, while customization is a time-consuming process, it can help to create a chatbot that is not a generic assistant, but a truly unique one. The benefits attached to this will be heard in the level of customer satisfaction, the level of efficiency, and business profitability.

The Process of Customizing ChatGPT

Customizing ChatGPT requires a systematic approach to prevent the situation where existing functionality is upset by new features before customisation is complete. We need to take a look at the various steps involved in configuring ChatGPT so that it can serve your specific needs:

Identifying Your Business Needs

Before embarking on the customization journey, it's crucial to identify your business objectives and how ChatGPT can help achieve them. Whether you aim to automate repetitive tasks, provide instant responses to customer queries, or foster engagement, having a clear understanding of your business needs sets the foundation for successful customization.

Moreover, conducting market research and analysing customer feedback can provide valuable insights into the type of interactions your audience expects. By understanding your target demographic and their preferences, you can tailor ChatGPT to deliver personalised and relevant responses, enhancing the overall user experience.

Tailoring ChatGPT to Your Business

The first step after defining your objectives is to customise ChatGPT to be relevant to your company and cater to its unique needs. To do so, you will need to provide the chatbot with training data appropriate to your sector and domain.

Utilising a custom dataset consisting of examples of contextually relevant questions and answers derived from your faculty and fine-tuning properties will aid in generating responses that are accurate and contextually relevant. Finally, the model’s capabilities should always be tested, and its performance should be refined over time.

You can also facilitate the flow of data and improve the chatbot’s functionality by connecting ChatGPT to your CRM system or other platforms. The AI model relies on data from a variety of sources to provide users with more personalised solutions and suggestions, which boosts customer satisfaction and results in repeat business.

Benefits of Using Custom ChatGPT

Custom ChatGPT has tons of benefits that can make it go a long way in improving your business operations and customer experience. Let’s discuss,

Enhancing Customer Service

Businesses that want to be successful have quality customer service or personalised functionality gates. ChatGPT can be tailor-made to understand what your customers are asking and answer them accordingly, thus optimising the support process and helping resolve issues faster.

Additionally, ChatGPTs capacity to handle a high number of concurrent conversations enables businesses to serve multiple customers at the same time, leading to an even faster response and, therefore, helping maintain greater customer satisfaction! Say a customer has an intricate situation that needs minute-by-minute support. Not only does Custom ChatGPT know how to read the problem precisely, but it can also look for solutions piece by piece gratifying an enhanced customer service experience.

Streamlining Business Operations

With a Custom ChatGPT, internal operations can also turnaround as automating repetitive tasks and helping employees in their day-to-day jobs are some of the ways it can make an impact. By scheduling the appointment to give reports, these boring and tedious tasks can be done with ease from Chatbots freeing hours of workforce time so that your team can spend more energy on real work.

In addition to this, integrating ChatGPT with your CRM system means the chatbot can update you in real-time as customers interact and offer preferences or feedback. This kind of smooth integration helps various departments within an organization to manage data more efficiently and make better-informed decisions, ultimately leading to increased operational efficiency.

Potential Challenges and Solutions with Custom ChatGPT

The ability to customise ChatGPT is full of promise, however, there are limitations and hurdles that businesses should be mindful of as they start using it. Here, I will explain about two key issues along with their solutions,

Addressing Common Concerns

A typical fear with AI chatbots is that it can produce inaccurate outcomes which might lead to incorrect and misleading information. In order to offset this, businesses should establish sufficient testing coverage so as to approve the replies provided by ChatGPT. Monitoring, feedback loops and the escalation process are designed so that anything there is out of spec can be identified in near real time.

Reliability and accuracy of the answers that are given by AI chatbots is an essential thing to consider both for maintaining trust with customers keeping their satisfaction level high. This directly improves the responses ability which in turn making it more relevant to the new situation being discussed, for a business that employs chatbot developers and having them actively manage by continually updating training data gets better performance out of their chatbots. Also, a human-in-the-loop mechanism that allows the interference of manpower is also an additional layer for ensuring data quality.

Overcoming Implementation Hurdles

Although challenging, it is possible to roll out a custom version of ChatGPT by businesses that have little or no experience in AI implementations. That said, it becomes far easier to implement when working alongside established AI solution providers. These specialists can walk you through implementation and customization, provide the necessary training to your team to utilize it effectively, and constant support for managing change.

In addition, doing the proper research and analysis of your unique business needs prior to jumping into customization ensures as smooth a process as possible and avoids unnecessary roadblocks along way. When you work hand in glove with the AI-solution provider to set specific goals, develop KPIs and lay out a clear path it makes sure that whatever customization effort has been done is perfectly aligned with your business objectives.

Future Trends in Chatbot Technology

The evolution of chatbot technology continues to shape the future of customer interactions. Here are two trends that are expected to drive the development of custom ChatGPT:

AI and Machine Learning in Chatbots

The utilisation of AI and machine learning in chatbots renders them with the ability to learn from user interactions and become personalised over time. This journey of learning from transactions helps in enhancing the accuracy and responsiveness of your chatbot, thereby turning into a more dependable tool for businesses.

The Future of Custom ChatGPT in Business

With the development of technology, every successful business may profit significantly from using custom ChatGPT. No matter if it is used for creating unique marketing campaigns or more efficient support systems, it is apparent that the tool will help businesses interact with their customers better and, in some cases, be the defining factor of success.

Over the next several years, demand for chatbots such as with ChatGPT are expected to soar even higher, given an increasing portion of shopping and socialisation now occurs online. The world is coming to think of chatbots with AI and machine learning that can provide real-time personalised responses to customers on the GO from businesses.

Custom ChatGPT is far more than just the future of customer service. Modern healthcare, education, and plenty of other industries are now actively using chatbots to improve the efficiency of services, organise information in more digestible ways, and simply create exciting user experiences. This tool’s flexibility and adaptability will allow it to take the leading positions in numerous fields and adapt to the new requirements demanded by these industries.

Would you like to be among the first to try this innovation? Then try InfyGPT today!

September 07, 20249 minutesuserAnkit Kalathiya

Posts

Using Common StatusTrait in Laravel in multiple models

Recently, we were working on a laravel app where we have a status column in multiple models. We have multiple processes going on for which we have different jobs.

Initially job status will be "Pending", then each job will take one record, change the status to "Running" and process that record, and update the status to either "Completed" or "Failed".

We have constants for each status. Something like below,

static $STATUS_PENDING = 0; 
static $STATUS_RUNNING = 1; 
static $STATUS_COMPLETED = 2; 
static $STATUS_FAILED = 3;

And the problem is, we need to go and define the status in every model that we have (around 10+ models).

Then we have functions to update status and check the status in each model like,

public function markRunning($saveRecord = true) 
{     
    $this->status = static::$STATUS_RUNNING;
    if ($saveRecord) {
        $this->save();
    }
}

public function isRunning()
{
    return $this->status === static::$STATUS_RUNNING;
}

And above functions existed for each 4 status. So what we did is, we created a common StatusTrait which can be used across multiple models.

Here is the code of StatusTrait that you can find for that.

Then in each model, we use this trait. For e.g.,

class SavePdf extends Model 
{     
    use StatusTrait;
    .....
}

And then can use any method of trait in all the models,

... 
$savePdf = new SavePdf(); 
$savePdf->markRunning(); 
...

Or we can check if the status of the model is running or not. For e.g.,

... 
if ($savePdf->isRunning()) 
{     
    // logic here 
} 
...

This is how we have saved tons of writing code and optimized the code. Another advantage is, we can just update the value of any status from one single place.

You can also check this kind of pattern and do something like this.

August 26, 20201 minuteauthorMitul Golakiya
Use Laravel Debugbar's measure function to optimize application performance

Laravel Debugbar is a great package to debug Laravel applications while developing. But it's not just limited to debugging. You can use it to optimize the performance of your app a lot as well. Like,

  • number of models loaded in a memory
  • number of queries fired with timing
  • memory used and more.

In short, we can have a complete view of what's going on in each request.

But the less known and used feature it gives is the Timeline tab. Where you can see how much time is taken for each request. And more than that, how much time Laravel took to boot up and how much time our other code has taken. Check the below screenshot.

Timeline

Recently we came to the case, where one of our consultation clients' CRM application was taking too much time on the first load. Their developers were not able to spot a problem. They checked queries and other stuff which looked completely good. so we were not sure where the time had been spent by the application.

That's where debugbar came to rescue us. We used its measure function facility by which we can measure the time spent in each of the functions wherever we want to use. It gives simply two functions startMeasure and stopMeasure to measure the time spent between these two statements.

so we can put startMeasure in the starting of function and put stopMeasure at the end of the function which will render something like this in the timeline tab.

public function searchClients($department) 
{     
    \Debugbar::startMeasure("searchClients'');
    // logic here

    \Debugbar::stopMeasure("searchClients");

    return $result;
}

Once we put this, we get a time that < code > searchClients is taking. Check the screenshot below,

Timeline

Hope this can help you to figure out what piece of code is taking the time and you can optimize it.

Happy Optimizing :)

August 22, 20201 minuteauthorMitul Golakiya
Efficient and Fast Data Import with Laravel Jobs & Queues

Recently Spatie released a brand new package for multi-tenancy called laravel-multitenancy.

It comes with great support to work out of the box with sub-domains like,

https://zluck.infychat.com

https://infyom.infychat.com

https://vasundhara.infychat.com

It identifies the tenant based on the sub-domain and sets a database runtime for your tenant-specific models.

Recently, we used it in one of our clients for Snow Removal CRM. Here we have two models,

  1. Freemium Model - with no sub-domain (application will work on main domain only)
  2. Premium Model - where the tenant will get its subdomain

And a user can convert his account from Freemium to Premium at any point in time by just subscribing to the plan.

So what we want is, on the backend, we want to have a separate database for each tenant, but the application should run on main as well as a sub-domain.

So what we want to have is the ability to extend/customize the tenant detection mechanism. And Spatie does a very good job there where you can customize the logic.

You can create your own TenantFinder class and configure it in the config file of the package. And there is very good documentation for that here:herehttps://docs.spatie.be/laravel-multitenancy/v1/installation/determining-current-tenant/

To do that, what we did is, we have a field called tenant_id in our users table. All of our users are stored in the main database since we may have user access across the tenant.

And when any user does a login, we listen for the event Illuminate\Auth\Events\Login which is documented in Laravel Docs over here.

When a user does a login, our listener will be called and will create a cookie called tenant on the browser with the tenant id of the user. So our listener will look like,

<?php
namespace App\Listeners;

use App\Models\User;
use Cookie;
use Illuminate\Auth\Events\Login;

class LoginListener
{
    public function handle(Login $event)
    {
        /* @var User $authUser /
        $authUser = $event->user;

        Cookie::forget('tenant');
        Cookie::queue(Cookie::forever('tenant', encrypt($authUser->tenant_id)));
    }
}

Also, we encrypt the cookie on our end, so we do not want Laravel to encrypt it again, so we added the tenant cookie into except array of EncryptCookies middleware as per documentation here. so our middleware looks like,

<?php
namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    /**
      The names of the cookies should not be encrypted.

      @var array
     /
    protected $except = [undefined];
}

Now at the last point, we extended our logic to find a tenant and get it to work on the main domain as well as sub-domain.

We have created our own custom class called InfyChatTenantFinder, which looks like,

<?php
namespace App\TenantFinder;

use App\Models\Account;
use App\Models\SubDomain;
use Illuminate\Http\Request;
use Spatie\Multitenancy\Models\Concerns\UsesTenantModel;
use Spatie\Multitenancy\Models\Tenant;
use Spatie\Multitenancy\TenantFinder\TenantFinder;

class InfyChatTenantFinder extends TenantFinder
{
    use UsesTenantModel;

    public function findForRequest(Request $request): ?Tenant
    {
        $host = $request->getHost();

        list($subDomain) = explode('.', $host, 2);

        // Get Tenant by subdomain if it's on subdomain
        if (!in_array($subDomain, ["www", "admin", "infychat"])) {
            return $this->getTenantModel()::whereDomain($host)->first();
        }

        // Get Tenant from user's account id if it's main domain
        if (in_array($subDomain, ["www", "infychat"])) {

            if ($request->hasCookie('tenant')) {
                $accountId = $request->cookie('tenant');
                $accountId = decrypt($accountId);
                $account = $this->getTenantModel()::find($accountId);

                if (!empty($account)) {
                    return $account;
                }

                \Cookie::forget('tenant');
            }
        }
        return null;
    }
}

So basically, first we check if the sub-domain is there, then find a tenant from the sub-domain.

If the domain is the main domain then get the tenant id from the cookie and return the account (tenant) model.

So this is how you can customize the logic the way you want to have a custom tenant identification system.

August 14, 20202 minutesauthorMitul Golakiya
How to remove public path from URL in Laravel Application

While hosting on the Laravel project on cPanel, the traditional problem that lots of developers get is, /public path is appended to the URL. Because in most cases, we put a project directly into the public_html folder, so public_html is our root for the website and that's where our laravel application is also placed.

But to run the Laravel application, we need to point our domain root to the public folder of the laravel. It is possible to do it with cPanel but you need to go through some steps which are not known by most of the people and also the tedious process. So to make it simple, what you can do is, there is a way we can do it via the .htaccess file in our root folder.

We can copy the .htaccess file from our public folder and then make modifications to it to work with the direct root folder and route every request to the public folder.

Here is the final .htaccess file,

<IfModule mod_rewrite.c>     <IfModule mod_negotiation.c>         Options -MultiViews -Indexes     </IfModule>
    RewriteEngine On

    # Handle Authorization MemberHeader
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Remove public URL from the path
    RewriteCond %{REQUEST_URI} !^/public/
    RewriteRule ^(.*)$ /public/$1 [L,QSA]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]

By adding the above file to the root folder we can use laravel projects without the public path. Check out the following two lines:

  RewriteCond %{REQUEST_URI} !^/public/   RewriteRule ^(.*)$ /public/$1 [L,QSA]

These two lines make magic and our application will work without public path in URL.

August 01, 20201 minuteauthorMitul Golakiya
Custom path generation in Spatie Media Library while multi-tenant

Recently we use Spatie laravel-multitenancy package in our of our client's CRM project along with spatie/laravel-medialibrary.

The default behavior of the media library package is, it generates a folder for each media with its ID in our configured disk, like a public folder or s3 or whatever disk we configured.

This works really great when you are dealing with a single-tenant application. But while using multi-tenant, you got a media table in each of your tenant databases. so this pattern simply doesn't work. Because then you will end up having multiple media files under the same folder from different tenants.

So what we want to do is, instead of having a structure like,

public -- media 
---- 1 
------ file.jpg 
---- 2 
------ file.jpg 
...

What we want to achieve is, we want to have a folder structure where media of every tenant will be in a separate folder with tenant unique id,

public -- media 
---- abcd1234 
// tenant1 Id 
------ 1 
-------- file.jpg 
------ 2 
-------- file.jpg 
---- efgh5678 
// tenant2 Id 
------ 1 
-------- file.jpg 
------ 2 
-------- file.jpg 
...

Spatie Media library is very configurable out of the box where you can write your own media library path generator. That is documented very well over here

So what we did is, we wrote our own Path Generator, which can store files into tenants folder. Here is how it looks like,

<?php
namespace App\MediaLibrary;

use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator;

class InfyCRMMediaPathGenerator extends DefaultPathGenerator
{
    /*
      Get a unique base path for the given media.
     /
    protected function getBasePath(Media $media): string
    {
        $currentTenant = app('currentTenant');
        return $currentTenant->unique_id.DIRECTORY_SEPARATOR.$media->getKey();
    }
}

What we did here is, we just simply extended the Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator of Media Library and override the function getBasePath. We attached the prefix of the tenant's unique_id to the path. so instead of 1/file.png, it will return abcd1234/1/file.png.

All you need to make sure is, whenever you are uploading a media, your application should be tenant aware. Otherwise, it will not able to get the current tenant.

Hope this helps while using spatie media library along with spatie multi-tenant.

Even if you are not using a spatie multi-tenant, still you can create your own PathGenerator and use it your own way to have a media structure you want.

July 30, 20202 minutesauthorMitul Golakiya
Spatie Laravel Multi-Tenancy without Sub Domain (customize TenantFinder)

Recently Spatie released a brand new package for multi-tenancy called laravel-multitenancy.

It comes with great support to work out of the box with sub-domains like,

https://zluck.infychat.com

https://infyom.infychat.com

https://vasundhara.infychat.com

It identifies the tenant based on the sub-domain and sets a database runtime for your tenant-specific models.

Recently, we used it in one of our clients for Snow Removal CRM. Here we have two models,

  1. Freemium Model - with no sub-domain (application will work on main domain only)
  2. Premium Model - where the tenant will get its subdomain

And a user can convert his account from Freemium to Premium at any point in time by just subscribing to the plan.

So what we want is, on the backend, we want to have a separate database for each tenant, but the application should run on main as well as a sub-domain.

So what we want to have is the ability to extend/customize the tenant detection mechanism. And Spatie does a very good job there where you can customize the logic.

You can create your own TenantFinder class and configure it in the config file of the package. And there is very good documentation for that here:https://docs.spatie.be/laravel-multitenancy/v1/installation/determining-current-tenant/

To do that, what we did is, we have a field called tenant_id in our users table. All of our users are stored in the main database since we may have user access across the tenant.

And when any user does a login, we listen for the event Illuminate\Auth\Events\Login which is documented in Laravel Docs over here.

When a user does a login, our listener will be called and will create a cookie called tenant on the browser with the tenant id of the user. So our listener will look like,

<?php
namespace App\Listeners;

use App\Models\User;
use Cookie;
use Illuminate\Auth\Events\Login;

class LoginListener
{
    public function handle(Login $event)
    {
        /* @var User $authUser /
        $authUser = $event->user;

        Cookie::forget('tenant');
        Cookie::queue(Cookie::forever('tenant', encrypt($authUser->tenant_id)));
    }
}

Also, we encrypt the cookie on our end, so we do not want Laravel to encrypt it again, so we added the tenant cookie into except array of EncryptCookies middleware as per documentation here. so our middleware looks like,

<?php
namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    /**
      The names of the cookies should not be encrypted.

      @var array
     /
    protected $except = [undefined];
}

Now at the last point, we extended our logic to find a tenant and get it to work on the main domain as well as sub-domain.

We have created our own custom class called InfyChatTenantFinder, which looks like,

<?php
namespace App\TenantFinder;

use App\Models\Account;
use App\Models\SubDomain;
use Illuminate\Http\Request;
use Spatie\Multitenancy\Models\Concerns\UsesTenantModel;
use Spatie\Multitenancy\Models\Tenant;
use Spatie\Multitenancy\TenantFinder\TenantFinder;

class InfyChatTenantFinder extends TenantFinder
{
    use UsesTenantModel;

    public function findForRequest(Request $request): ?Tenant
    {
        $host = $request->getHost();
        list($subDomain) = explode('.', $host, 2);

        // Get Tenant by subdomain if it's on subdomain
        if (!in_array($subDomain, ["www", "admin", "infychat"])) {
            return $this->getTenantModel()::whereDomain($host)->first();
        }

        // Get Tenant from user's account id if it's main domain
        if (in_array($subDomain, ["www", "infychat"])) {

            if ($request->hasCookie('tenant')) {
                $accountId = $request->cookie('tenant');
                $accountId = decrypt($accountId);
                $account = $this->getTenantModel()::find($accountId);

                if (!empty($account)) {
                    return $account;
                }
                \Cookie::forget('tenant');
            }
        }
        return null;
    }
}

So basically, first we check if the sub-domain is there, then find a tenant from the sub-domain.

If the domain is the main domain then get the tenant id from the cookie and return the account (tenant) model.

So this is how you can customize the logic the way you want to have a custom tenant identification system.

July 24, 20203 minutesauthorMitul Golakiya
toBase function in Laravel Eloquent

Sometimes we need to load a large amount of data into memory. Like all the models we have in the database.

For e.g. PDF Printing, Perform some global updates, etc.

So the general practices we use in Laravel is to write the following code,

$users = User::all();

Just imagine I have 10,000 users in the database and when I load all the users in one shot.

But it takes a really high amount of memory to load all the records and prepare Laravel Model class objects. And sometimes we also load them in chunks to save the memory, but in some use cases, chunking can not be the option.

Here is the screenshot of mine when I load 10,000 users into memory with the above code.


10k Models


It's using 37MB memory. Also, imagine the required memory if we are loading some relationships as well with these 10,000 records.

The Eloquent model is a great way to handle operations with lots of features like Mutators, Relationships, and much more.

But we really do not use these features all the time. We simply output or use the direct values which are stored in the table. So ideally, we do not need an eloquent model at all, if we are not going to use these features.

In those cases, Laravel also has a handy function toBase(). By calling this function it will retrieve the data from the database but it will not prepare the Eloquent models, but will just give us raw data and help us to save a ton of memory.

So my revised code will look something like this,

$users = User::toBase()->get();

Check the revised memory screenshot after adding the toBase function.


10k Models toBase


So it almost saves 50% of the memory. It's reduced from 35MB to 20MB and the application also works much much faster, because it doesn't need to spend time in preparing 10,000 Eloquent models.

So if you are not really going to use features of Eloquent and loading a large amount of data, then the toBase function can be really useful.

Here you can find a full video tutorial for the same.

June 21, 20202 minutesauthorMitul Golakiya
Make long path shorter in asset function in laravel

Recently, I've started working on one project where we follow modules patterns and for the same, we have different assets folders for the different modules and the folder named common for assets which are common across all the modules.

So our public folder looks like the following,

Module Asset Functions

The problem that I started facing was everywhere I needed to give a full path to import/include any of the files from any of the folders. For e.g.

<img src="{{ asset('assets/tasks/images/delete.png') }}"alt="Delete Task">

Even if we have some folder in images to group similar images then it was even becoming longer. For e.g.

<img src="{{ asset('assets/tasks/images/social/facebook.png') }}" alt="Facebook">

The workaround that I used is, I created one file called helpers.php and created dedicated asset functions for each of the modules. For e.g., for tasks,

if (!function_exists('tasks_asset')) {     
/**      
* Generate an asset path for the tasks module folder.
*      
* @param  string  $path      
* @param  bool|null  $secure      
* @return string      
*/     
function tasks_asset($path, $secure = null){
    $path = "assets/tasks/".$path;         
    return app('url')->asset($path, $secure);     
  } 
}

With this function, I can use,

<img src="{{ tasks_asset('images/delete.png') }}" alt="Delete Task">

Other advantages it gives are,

  1. if in future if the path of tasks folder changed, then I do not need to go and update every single import/include.
  2. I (or any new developer) do not need to remember the long paths and can always use direct function names for modules.

Even I like this pattern so much, so I went further and created dedicated image function as well,

if (!function_exists('tasks_image')) {     
/**      
* Generate an asset path for the tasks module images folder.
*      
* @param  string  $path      
* @param  bool|null  $secure      
* @return string      
*/     
function tasks_image($path, $secure = null){
    $path = "images/".$path;         
    return tasks_asset($path, $secure);     
  } 
}

So I can use it as,

<img src="{{ tasks_image('delete.png') }}" alt="Delete Task">

Simple and handy functions to use everywhere.

May 16, 20202 minutesauthorMitul Golakiya