Using both Tailwind and Bootstrap 5 in Laravel 9

Here is a scenario, You are using the socialstream laravel plugin by Joel Butcher (You can donate to the guy for his hard work), You don’t have the time to modify the pages, and you want to throw in bootstrap alongside tailwind that ships with socialstream, the process to do this is not so hard, let us stick to this example and resolve the issue and then you can adapt this to whatever your situation is.

Off the bat, bootstrap and tailwind have conflicting class names ! they can not be used together without adding a prefix, but there are solutions to make it happen depending on your use case.

Again, whatever your use case may be, there are multiple solutions that need to be mixed and matched, I will start by providing the methods to allow both Bootstrap and Tailwind to co-exist, then, I will provide the common use cases below and refer to the solution(s) that work best with them

Solution 1- Change the tailwind class prefix !

This is the simplest solution

You start by editing the file tailwind.config.js and adding the prefix option.

module.exports = {
  prefix: 'tw-',
}

The run “npm install && npm run build”

On laravel, this will add tw- as a prefix to all the utility classes, the effect can be seen in the files

the use of tailwind CSS that came with your scaffolding plugins probably is not massive.

Case 1: My design is in bootstrap, but scaffolding packages use tailwind !

For example, one reason you are probably trying to do this is when you have Laravel packages that provide a front end that uses tailwind, but your design is all done in bootstrap !

The solutions are

Laravel Social Login, simple step by step (The whole story)

What is OAuth2

If you are a web developer, you probably understand that OAuth (2) is how you allow your visitors to login to your website using their facebook, twitter, or even github credentials (Too many to name).

The uncontested champion of a plugins to log in users to your website using social networks is Laravel Socialite, (More like register to your website, but you get the idea)

So, to avoid confusion, socialite is the plugin you are looking for, Passport and Sanctum ARE NOT MEANT FOR THIS PURPOSE. here is how they are different

PluginAbout
SocialiteAllows you to easily integrate the option to login to your website with a popular website's credentials
SanctumThe opposite of Socialite, Allows an application to authenticate users using your website as a back-end, usually useful when you create mobile apps for example.
PassportSame concept as Sanctum, but with OAuth2, Unless you need OAuth2, don't use this, Sanctum provides a much simpler API authentication development experience.

Now, let us get to adding social login to our application, socialite.

Laravel development under Linux (Dev Tools)

At this stage, this posst is a stub, I am simply compiling information here then I will come back to edit this

Under linux, the Laravel extensions that i like up to now are

  • Laravel Blade Snippets (For blade templates)
  • PHP namespace resolver (So that we don’t need to look for what namespaces provide for the classes we are using)
  • PHP Intelephense (PHP Autocomplete/intellisense ref finder, etc…)

Laravel 9 on NGINX under Debian 12 (bookworm) – Step by step

This part of the tutorial is a hands on setup to have Laravel working on nginx under Linux. this is not the only way to run Laravel, for all the options, see here

NOTE: Most if not all of the popular development tools are available for Linux and Windows, so If this setup is for development, you might want to install Debian Linux with the Gnome GUI so that you can install the development tools used in the next part of this tutorial, if you are going to be developing on a different machine or this is for production, then you shouldn’t.

STEP 1: Install Debian 11 (Bullseye) on a computer.

STEP 2: Install the basic Laravel environment with the following commands, Laravel 9 requires PHP 8, which at the time of writing is not available in Debian 11 repositories, so we will need to add the repositories from the guy who manages PHP for Debian anyway

sudo apt-get install ca-certificates apt-transport-https software-properties-common gnupg unzip curl
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/sury-php.list
wget -qO - https://packages.sury.org/php/apt.gpg | apt-key add -
apt-get update

Now, to the actual installation of the environment

apt install php8.1-fpm nginx
apt install php8.1-{dev,common,xml,tokenizer,zip,mysql,curl,mbstring,mysql,opcache,gd,intl,xsl,bcmath,imap,soap,readline,sqlite3,gmp}
apt install redis-server
apt-get install php8.1-redis
apt install mariadb-server mariadb-client

Now you need to secure redis !

Now remember to secure your mariaDB (MySQL) installation with the following command

mysql_secure_installation

Next, we need composer, the PHP dependency manager, to get it execute the following

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
chmod +x /usr/local/bin/composer
composer --version

The last line above should show you what version of composer you have just installed

Now, remember to never run composer as root, but rather as a regular user, from this point on I am assuming you are running the terminal as a regular user.

I understand that Debian puts the web root in /var/www/html, but i usually like to create a separate directory called /var/vhosts and put all my web projects in it

mkdir /var/vhosts

Now, we need to create a sample project for our learning and training experience

cd /var/vhosts
composer create-project laravel/laravel laraveltestapp
chmod -R 0777 /var/vhosts/laravelapp/storage

Next, We would need to setup nginx to serve this website (“Would like to” actually, because there are alternatives, but I’m keeping it simple), here is an almost standard template for nginx, modify the host name and project name to match your project and preferences.

NGINX vhost config file (In my case /etc/nginx/sites-available/laraveltestapp)

server {
    listen 80;
    listen [::]:80;
    server_name ltest.net www.ltest.net;
    root /var/vhosts/laraveltestapp/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
#	fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Surely for this to work, you will need to add the following two lines to the end of the /etc/hosts file

127.0.0.1 ltest.net
127.0.0.1 www.ltest.net

As soon as we have the file above, we need to create a symbolic link for it in the sites enabled directory

cd /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/laraveltestapp

Suddenly, it works through nginx, you should see the welcome page (View) here

Now, to the development environment, how to setup your development environment can be found here

Laravel – Tools and environments

The following are things that are commonly used with Laravel. broken down by category

Environment tools and solutions

  • PHP composer (Mandatory)
  • Docker – Sail (Optional)

Relevant / Compatible server side software

  • Apache2 (2.4) (Web Server)
  • Nginx (Web Server)
  • PHP (PHP8.x for Laravel 9)
  • redis (Data structure store)
  • memcache (in-memory, distributed cache)
  • MeiliSearch (Search application)
  • MailHog (email-testing tool with a fake SMTP server)
  • Selinium (browser automation)
  • MySQL/Mariadb (Database engine, most common)
  • PostgreSQL (Database Engine, very powerful)

Development environments

  • Microsoft Visual Studio Code (Free): built-in support for JavaScript, TypeScript and Node.js, extensions include PHP
  • Sublime text (Not free, works but nags)
  • Apache beans (Free)
  • IntellijIDEA (Not free, one month trial)
  • PHPStorm (Same as IntellijIDEA without the other languages support, Not Free, one month trial)

Database Management

  • MAC: Sequel Pro and sequel ace
  • ALL: PHPMyAdmin, mysql workbench (Oracle),
  • sqlyog (Windows and Linux)


Other

  • Node.js
  • NPM (Installed with node.js): npm is a package manager for the JavaScript to work with front end stuff like node.js, react.js, bootstrap, tailwind CSS,
  • Yarn (NPM alternative from Facebook)
  • GIT: track changes in source code

Laravel 9 localization

As per usual, the practical stuff (Implementation) comes first to keep this short for those who are in a hurry, giving you the bottom line first ! then the things you need to know, then the things you don’t need to know, the one exception in this post is the first paragraph after this one, so let’s dive right in

What is different in Laravel 9 ?

The only difference between Laravel 8 an 9 in localization is that in Laravel 9, we no longer store language files in resources/lang, but rather in the new lang directory

So, there are 2 methods of creating language files, which one you should use depends on how much translation of hard coded strings there is on your website, if you only have a little, you would use a method called “1- Short strings” which is the older method, and starting from Laravel 5.4 we also have the “Translation strings” method which uses JSON and is better suited for websites where hard coded strings are many

Can i use both methods at the same time ?

Yes you can, but there is no reason to that i can think of

Implementation

So, unlike everywhere else, to get you up to speed, I will start with the newer method (the one you will likely use), then go back to the older short string method

I am assuming you already created a Laravel 9 project

1- Configure the default locale and the fallback_locale of your website as well as adding the available_locales in (config/app.php), Default is the language that your website starts with, and fallback is the language Laravel should look at when it fails to find a string, there is a third fallback within your view that you will discover in Just a bit.

For the sake of example, I am using the default local of ‘ar’ and the fallback locale of ‘en’, put those into my config file, specify the two languages the website will support and get on with the next step, my config is included here for convenience

'locale' => 'ar',
'fallback_locale' => 'en',
'available_locales' => [
  'English' => 'en',
  'Arabic' => 'ar',
],

2- Create the Locale files, /lang/en.json and /lang/ar.json





3- Middleware: So, now that we have the above setup, we need middleware so that the user can specify a locale that would persist ! Obviously, you can specify this manually inside a route or something, but you would probably rather use a middleware instead of having different URLs (Unimportant note: not necessarily, it would depend on how your website functions, sometimes it is better to have a different language version for every url for SEO for example, but that requires separation of languages in your user content in the database, and is for another day)

php artisan make:middleware Localization

   INFO  Middleware [app/Http/Middleware/Localization.php] created successfully.

Now, we have new middleware file in /app/Http/Middleware/Localization.php, Localization ! but how do we use it ? Up to now this middleware does nothing, but we want it to fire up on every page request, to do that, we need to add it to /app/http/Kernel.php, so in that file, in the protected $middlewareGroups array, and the web inner array, Add the following line

\App\Http\Middleware\Localization::class,

So our middleware now fires up with every page load ! this is so that after we modify the middleware, we can make sure the page uses the locale the user has set. but before we get to making that middleware, how will the user set his/her preferred locale ? So, let us start by creating the middleware, to make it work, add the following two lines to include the relevant Facades

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Session;

And the following lines within the handle method, right above the return statement

if (Session::has('locale')) {
            App::setLocale(Session::get('locale'));
        }

Now, the last thing to do that will make it work (But not necessarily how we want it to work on our website) is to add a route to do that, here, I am using an anonymous function/closure, but feel free to use a controller if you like (Not really much code to warrant it’s own controller in my opinion)

Route::get('language/{locale}', function ($locale) {
    app()->setLocale($locale);
    session()->put('locale', $locale);
    return redirect()->back();
});

Now, to making the website use those languages

X: Using the language strings !

As you might remember form the part numbered (1) above, I told you that there is a third fallback besides the one in the config file, which is in the blade view itself !

To use any string, the syntax in the website is {{ __(‘Welcome to our website’) }}, if the JSON does not contain such a string, the litteral itself is used ! so even if this string (Welcome to our website) is nowhere to be found in any language file, it is still printed as (Welcome to our website) !

With that out of the way, once you have a few of those strings on the website, visiting the URL /language/ar will flip the website to Arabic, you can browse around the website, and for as long as your session cookie is there, it will work ! going back to /language/en will switch it to English in the same manner !

This is not really the thing we are looking for, we want the user to seamlessly switch between languages via drop-down or button right ? so here we go

Codeigniter and Laravel together

Who said you can’t mix and match between Laravel and code Igniter. well, you will face some issues, but they are not that hard to resolve.

It all starts with a cool package called EFTEC/BladeOne, which is simply blade without laravel !

to install it, you go to your CI application folder, and run the command

composer require EFTEC/BladeOne 

At this stage, we have Blade up and running, to use it, create a file under core for example, and let’s say we will call the controler /core/bladeController.php

redis for Laravel on Debian

If you are like me, running only your own projects on a server, you might want to skip authentication

the changes I generally make to the file /etc/redis/redis.conf are

1- At the very beginning, limit the RAM redis can use with the line

maxmemory 2gb

2- Change the supervisor to systemd by modifying the line

supervised no

to

supervised systemd

Now, to test the new config, from the command line, run the following commands

systemctl restart redis-server
redis-cli
ping
config get maxmemory
quit

You have just configured redis and tested your new settings.

Microsoft VS code plugins for the Laravel Developer

The following is a list of plugins I have installed to help with Laravel Development, I will add to them as I go, I will also remove the ones i don’t think were worth it from the list as well

PluginWhat forHow to usePublisher
PrettierVery popular plugin to format your code so that it looks tidyDo take a look at the plugin’s config to tweak it to your likingPrettier
PHP IntelliSenseAdvanced Autocomplete and Refactoring support for PHPFelix Becker
PHP IntelephenseCooler than PHP IntelliSenseBen Mewburn
Laravel Extra IntellisenseSelf explanatory name !
PHP Namespace ResolverImport and expand PHP namespacesMehedi Hassan
laravel-bladeLaravel blade syntax highlightingChristian Howe
Laravel SnippetsWinnie Lin
Laravel Blade SnippetsLaravel blade snippets and syntax highlight supportWinnie Lin
Laravel goto viewQuick jump to view !codingyu
Better AlignAlign code without selecting them firstwwm
Laravel Blade WrapperSpeed up wrapping code with Blade directivesCTRL + SHIFT + TlHunte
Laravel-goto-componentsTakes you to Blade components <x-… with a clickCTRL + CLICKnaoray
DotENVSyntax highlighting for .env files !mikestead
Tailwind CSS IntellisenseIf you use Tailwind (A css library), this plugin will do all the tailwind magickTailwind Labs

Laravel Tutorial: Blade part 1

The simplest Blade tutorial !

Disambiguation: This tutorial is about Blade, the template engine for Laravel…. I am covering blade on Laravel 9, but I am also taking into account that you might be maintaining code from blade 5 !

Why yet another blade tutorial ? they are all over the place !

long as this tutorial may be, it should be an easy read. no need to memorize stuff or write notes, I am trying to structure it in such a way so that you can effortlessly understand the concept, then come back for that one little syntax you have forgotten very easily.

Simply put, i think blade is a very simple framework that you can complicate if you insist, I think there is an easier way to get someone up and running with blade, a tutorial that compares the Blade way to the traditional way, does not invoke flashy abbreviations before explaining what they mean, and serves you the simplest explanation first… Also one that involves illustrations, shows the different features and explains how they differ and when to use features and why…

I’ll leave the flashy terms and history lessons near the end of the tutorial for completeness, and because they may be useful, but not before you are comfortable with Blade.

Why not a video tutorial

If this gets any attention, I will create a video from it, but I personally prefer reading and looking at illustrations.

What is blade in simple terms ?

Traditionally, when creating a website in PHP, your HTML is mostly in the same PHP files that provide the functionality ! blade is here to help you separate your HTML content from your PHP functionality…

Blade is a special folder in your Laravel project where you add those PHP files that contain your HTML*, plain old folder where you simply separate those files from the rest of your code. files in that folder enjoy extra functionality provided by blade that takes out the inconveniences of separating the HTML.

in your Laravel project, that folder is usually /resources/views, blade PHP files end in .blade.php, for example, mytheme.blade.php

* HTML And JSON if you are also writing an API…. and whatever you normally add to your HTML such as inline CSS and inline JS

Isn’t Separating my HTML into it’s own files a lot more work ?

Well, that is what blade is for, it provides tools to make this simple and easy

Traditionally, if you wanted to separate the HTML from the rest of your code, you would create PHP files with the HTML in them, and use PHP’s include function to show them… or embed the HTML inside functions that are in separate files, and send the data to those functions (or classes) and print what is returned…

That works, and blade is more or less the same thing, but as you proceed with Blade, you will see how blade resolves many inconveniences that this method comes with.

Let’s get down to it !

Setup Laravel on your system

First, I am assuming you have already setup Laravel and created a new project, if not, please take a look here (/2022/09/07/laravel-tutorial-laravel-setup/) for instructions on how to do that !

Create a couple of dummy routes

Now that you have such a setup, We will need to add a couple of routes (URL definitions), don’t concern yourself with what they are or what they mean, they are covered in the next section, they are just here to enable us to learn blade, routes is in a totally different place, all you need to learn for now that those two routes are invoked when you visit the URLs they define, and they pass the variables you see in them to the blade templates

Routes are added to the /routes/web.php file, so open that file and add the following at the end of it, now you have two URLs that work, the home page, and a /test page





First Blade File: plain HTML and nothing more

Now, let us create our first BLADE file, let us call it example.blade.php, and in that file, we will simply add an HTML page with nothing to do with blade specific features, Just that page that will display whether you use the home page (the first route from above), or the /test route that you see in the other route !

—————–

Unorganized content to be incorporated into the tutorial

If you stick to a couple of rules, it is compiled into PHP code and cached, so it is really fast !
Asset helpers
Layouts (extends, Yeild, section, show)
Partials
Components: includes, arrays vs collections {{$var->entry}}, props, &lt;x-cards>,

BLADE  is inspired by .NET’s Razor engine.

Allows you to use PHP code inside (@php directive), but you should not need to, and you should not unless you have to
(If you feel a need, you are misplacing your code)

If you come from Symfony, you can use Twig through Twig-bridge !

Syntax

1- Echo
{{ $variable }} is equivalent to <?= htmlentities( $variable ) ?>

Sometimes you may need to echo handlebar notation into the output, so you can simply use an @ before the above notation

@{{ $variable }} will output {{ $variable }} (Without the @)

or, if you want things to just print as they are, you can use the @verbatim directive !

{!! $variable !!} is equivalent to <?= $variable ?>


{{ $variable }} = <?= htmlentities( $variable ) ?> 
{!! $variable !!} = <?= $variable ?>
{{-- comment is here --}}



self explanatory blade directives

if elseif else endif (endif is the closing after all of them)

@unless and @endunless = equivilent to if(!cond)

@for, @foreach, and @while (endfor endforeach enwhile)

@forelse and @endforelse = ForElse is a ForEach loop, but with extra handling for empty array.

@forelse ($talks as $talk)
	{{ $talk->title }} ({{ $talk->length }} minutes)<br>
@empty
	No talks this day.
@endforelse

-----------------------------------------------------------
Defining Sections with @section/@show and @yield

yeilds first param is the section name, it's second is A DEFAULT VALUE

instead of yeild, if you want an entier block as a default fallback, you can use

@section('footerScripts')
<script src="app.js"></script>
@show

In this @section .... @show, if we want to append to the default value above, we should include @parent in the child template extending this, otherwise, the contents above will be overwritten !

Note that The @show is in the parent section, shows in place, while the @section and @endsection are in the child !

the section show is both defining a default and doing so in such a way that its default contents will be available to its children, through @parent

to use all of the above... assuming the template is at resources/views/layouts/master.blade.php
@extends('layouts.master') {{-- Each file should only extend one other file, and the @extends call should be the first line of the file --}}

@section('title', 'Dashboard')

@section('content')
     Welcome to your application dashboard!
@endsection

@section('footerScripts')
@parent
     <script src="dashboard.js"></script>
@endsection
-----------------------------------
partials



------------------------------------------------
1: creating a folder called images under public !

---------------------------------------------------

Method 1: @yeild

put the header and footer in one file called layout.blade.php in one peice (empty doc)

within the template, you put in 

@yield('content)

in other layout components, you use the extends directive, and make the content inside
 
 @extends(layout)
 
 @section('content')

whatever needed to appear in the theme, the content that is labeled content just like in yeild

@endsection

partials are added with include, so if you put the thing in the partials directory, the convention is that a file starts with underscore as a partial, _hero.blade.php

include('partials._hero)

Method 2: making the layout a component

---------------

in routes, read on route model binding, instead of passing $id to the inner function and route specification, we pass an object of type listing (The model listing) to the inner function, and in the route specification, the word /blah/{listing}, we  it allows us to just