Tips Posts

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 minutesMitul GolakiyaMitul Golakiya
DateTimeLocal with LaravelCollective Model Binding

Last week, we were working on one project where we were using LaravelCollective for generating our form. LaravelCollective is a really awesome package and reduces lots of efforts, specifically for automatically binding old inputs to our forms.

Problem

With LaravelColletive when we pass null as a second value, it tried to get old inputs if available and inject them. But for some reason, it was not working with datetimelocal.

datetimelocal need a date in Y-m-d\TH:i Format. When I went into the code of FormBuilder.php it’s already managing that and tries to convert date into that format if you have passed DateTime object.

So it was completely working fine while creating a record when you do not have any value.

But I have the same form which was used at both the time of Create and Update. And I was passing null into the value field at both of the time and LaravelCollective injects it automatically from model or old inputs if there is some error. Something like the following,

<div class="form-group col-sm-6">     
{!! Form::label('due_date', 'Due Date:') !!}     
{!! Form::datetimeLocal('due_date', null, ['class' => 'form-control']) !!} 
</div>

So, Due date will be automatically placed from the model. It’s working fine with all other fields except datetimelocal.

Solution

The reason behind that is, the value is retrieved from model due_date field, but it comes in Carbon instance and when it converts to a date string, it’s converted into default format which is Y-m-d h:i:s. So it will not work for datetimelocal input since it requires Y-m-d\TH:i format.

So as a solution, what change we did is, instead of passing null value, we first check, if the model is there then pass the value directly to the input. Something like,

<div class="form-group col-sm-6">     
{!! Form::label('due_date', 'Due Date:') !!}     
{!! Form::datetimeLocal('due_date', (isset($task)) ? $task->due_date : null, ['class' => 'form-control']) !!} 
</div>

So, I will check if I have passed the model $task to the view and then I will pass a due_date value to input. So FormBuilder will convert it to the proper format and it will get displayed into an input.

Now, when we save the form, it will also return the date into Y-m-d\TH:i format, so again we need to convert it to the proper format. For that, we created a mutate attribute for due_date in my Task Model.

public function setDueDateAttribute($value) 
{    
    $this->attributes['due_date'] = Carbon::parse($value); 
}

And that’s it. Our datetimelocal input gets working. I have seen lots of issues on stackoverflow for it. So hope it may help someone.

November 14, 20192 minutesMitul GolakiyaMitul Golakiya
Things/Tips to Remember while submitting your first Envato CodeCyan App

Last week we submitted our first app to Envato - CodeCyan called InfyLMS. InfyLMS is a full-fledged library management system to manage libraries built on Laravel+ReactJS.

But it was not just an easy upload. When you upload an item to CodeCyan, they have a dedicated team that tests your application and reviews the code quality of your app.

We have faced a few problems that I want to share, so if someone is uploading his first item to CodeCyan then he/she can review those points before submission and the chances of rejection can be reduced.

1. Do not use remote CDN

We have used Bootstrap in our system as a theme and we were using remote CDN URLs for JS and CSS. for e.g.

// CSS 
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
// JS

All your assets need to be offline. so download all these files via either some package manager or just go and download it and put it under the respective asset folder.

2. Use Strict Mode in JS

All Javascript files need to be written into Strict mode.

For example, you can do this with jQuery as follows:

(function($) {     
"use strict";     
// Author code here 
})(jQuery);

Or you can put

use "strict";

at the start of your file if they are generated via some webpack. There is a babel plugin available which you can use with a webpack.

3. Attach documentation into the main file

Attach documentation into the main file which you are uploading. Create a docs folder into the root folder and attach full documentation to set up the application. Also, remember that this doc should work offline as well. so attach all your assets here as well.

4. Have Clear & Easy documentation for Non-Technical Users

All the customers or buyers do not have technical knowledge that needs to be there to set up an application. so try to make your application setup as easy as possible. for e.g, create a setup wizard which executes step by step and ask for details from customers.

Or create a dedicated section in your documentation for Non Technical users with clear, precise and minimal steps that needs to be performed.

If possible, then try to give two different zip files under your main zip file, like

  • dist - Distribution which can be set up with minimal efforts for non-technical users
  • source - Original source file for technical users

I hope this will help new Envato Authors who are uploading their very first item.

November 04, 20193 minutesMitul GolakiyaMitul Golakiya