Developer Blog

Tipps und Tricks für Entwickler und IT-Interessierte

Git | Arbeiten mit der GitHub Kommandozeile

Installation

Laden Sie das Tool von dieser Seite und installieren Sie es. Das Tool besteht aus einer Datei: gh

Hier gibt es einen passenden Blog-Eintrag dazu.

Stellen Sich sicher, dass sich der Installationsordner in ihrem PATH Variable befindet.

Danach einfach das Tool mal aufrufen

Authentifizierung

Anmelden

gh auth login --hostname github.com

Default Protokoll einstellen

 gh config set -h github.com git_protocol ssh

Credentials aktualisieren

gh auth status

Aktualisieren der Credentials:

gh auth refresh

Konfiguration

Editor setzen

gh config set editor editorName

Repositories

Erstellen

gh repo create <user>/<reponame>
gh repo create <user>/<reponame> --private --enable-issues=false

Clonen

gh repo clone <user>/<reponame>

Fork

gh repo clone <user>/<reponame>
gh repo clone <user>/<reponame> --clone=true --remote=true

Löschen

gh alias set delete 'api -X DELETE repos/$1'
gh auth refresh -h github.com -s delete_repo
# usage (WARNING: no confirmation!)
gh delete user/myrepo

Informationen

Liste der Repositorynamen

gh repo list --limit 1000 --json name --jq '.[].name'

List der Repository-URLs

gh repo list microsoft --json url --jq '.[].url'

Liste filtern (in PowerShell)

gh repo list microsoft --limit 3000 --json url --jq '.[].url'  |
Select-String PowerBI -NoEmphasis                              |




Suchen nach Repositorynamen

gh repo list --limit 1000 --json name --jq '.[].name | match(".*Angular.*") | .string'

Issues

gh issue list

Alle “issues” mit dem Status “all”

gh issue list --state "all"
gh issue list -s "all"
gh issue list --assignee "n8ebel"
gh issue list -a "n8ebel"

Check Issue Status

gh issue status
gh issue list --state "closed"
gh issue list -s "closed"
gh issue list --label "bug"gh issue list -l "bug"
gh issue list
gh issue list -l "enhancement"

Issues anzeigen

gh issue view "15"
gh issue list -a "n8bel" -l "bug"

Issues erstellen

gh issue create -t "Sample Issue Title" -b "Sample issue description"
gh issue create --web

Hilfreiche CLI Aliases

gh issue list --label "bug"
alias listbugs='gh issue list --label "bug"'
alias listmybugs='gh issue list -a "<username>" -l "bug"'

Pull Requests verwalten

List Pull Requests

gh pr list
gh pr list --state "all"
gh pr list  -s     "all"
gh pr list --assignee "n8ebel"
gh pr list  -a        "n8ebel"

Check Pull Request Status

gh pr list --state "closed"
gh pr list -s "closed"
gh pr list --label "bug"
gh pr list -l "bug"
gh pr list
gh pr list -l "enhancement"

Pull Request anzeigen

gh pr view "14"
gh pr list -a "n8bel" -l "bug"

Pull Request erstellen

gh pr create
gh pr create -t "Sample Issue Title" -b "Sample issue description"
gh pr create --web

Praktische Beispiele

Alle Repositories clonen, deren Namen einem bestimmte Suchmuster entspricht

gh repo list microsoft --limit 3000 --json url --jq '.[].url' |
Select-String PowerBI -NoEmphasis |




Repositories suchen und clonen

gh search repos zola+theme --limit 200 --json url | jq .[].url | cut -d'"' -f2  >list-of-repositories
exit

cat list-of-repositories | while read REPO
do
   REP=$(basename $REPO .git)
   USR=$(basename $(dirname $REPO) )

   FOLDER=${USR}_${REP}

   if [ -d $FOLDER ]; then
      echo "$FOLDER already exists"
   else
      git clone $REPO ${USR}_${REP} 2>&-
      echo "$FOLDER cloned"
   fi
done
Docker

Docker | Create an extensible build environment

TL;DR

The complete code for the post is here.

General Information

Building a Docker image mainly means creating a Dockefile and specifying all the required components to install and configure.

So a Dockerfile contains at least many operating system commands for installing and configuring software and packages.

Keeping all commands in one file (Dockerfile) can lead to a confusing structure.

In this post I describe and explain an extensible structure for a Docker project so that you can reuse components for other components.

General Structure

The basic idea behind the structure is: split all installation instructions into separate installation scripts and call them individually in the dockerfile.

In the end the structure will look something like this (with some additional collaborators to be added and described later)

RUN bash /tmp/${SCRIPT_UBUNTU}
RUN bash /tmp/${SCRIPT_ADD_USER}
RUN bash /tmp/${SCRIPT_NODEJS}
RUN bash /tmp/${SCRIPT_JULIA}
RUN bash /tmp/${SCRIPT_ANACONDA}
RUN cat ${SCRIPT_ANACONDA_USER} | su user
RUN bash /tmp/${SCRIPT_CLEANUP}

For example, preparing the Ubuntu image by installing basic commands is transfered into the script 01_ubuntu_sh

Hint: There are hardly any restrictions on the choice of names (variables and files/scripts). For the scripts, I use numbering to express order.

The script contains this code:

apt-get update                                       
apt-get install --yes apt-utils
apt-get install --yes build-essential lsb-release curl sudo vim python3-pip

echo "root:root" | chpasswd

Since we will be working with several scripts, an exchange of information is necessary. For example, one script installs a package and the other needs the installation folder.

We will therefore store information needed by multiple scripts in a separate file: the environment file environment

#--------------------------------------------------------------------------------------
USR_NAME=user
USR_HOME=/home/user

GRP_NAME=work

#--------------------------------------------------------------------------------------
ANACONDA=anaconda3
ANACONDA_HOME=/opt/$ANACONDA
ANACONDA_INSTALLER=/tmp/installer_${ANACONDA}.sh

JULIA=julia
JULIA_HOME=/opt/${JULIA}-1.7.2
JULIA_INSTALLER=/tmp/installer_${JULIA}.tgz

And each installation script must start with a preamble to use this environment file:

#--------------------------------------------------------------------------------------
# get environment variables
. environment

Preparing Dockerfile and Build Environment

When building an image, Docker needs all files and scripts to run inside the image. Since we created the installation scripts outside of the image, we need to copy them into the image (run run them). This also applies to the environment file environment.

File copying is done by the Docker ADD statement.

First we need our environment file in the image, so let’s copy this:

#======================================================================================
FROM ubuntu:latest as builder

#--------------------------------------------------------------------------------------
ADD environment environment

Each block to install one required software looks like this. To be flexible, we use variable for the script names.

ARG SCRIPT_UBUNTU=01_ubuntu.sh
ADD ${SCRIPT_UBUNTU}    /tmp/${SCRIPT_UBUNTU}
RUN bash tmp/${SCRIPT_UBUNTU}

Note: We can’t run the script directly because the run bit may not be set. So we will use bash to run the text file as a script.

As an add-on, we will be using Docker’s multi-stage builds. So here is the final code:

#--------------------------------------------------------------------------------------
# UBUNTU CORE
#--------------------------------------------------------------------------------------
FROM builder as ubuntu_core
ARG SCRIPT_UBUNTU=01_ubuntu.sh
ADD ${SCRIPT_UBUNTU}    /tmp/${SCRIPT_UBUNTU}
RUN bash 

Final results

Dockerfile

Here is the final Dockerfile:

#==========================================================================================
FROM ubuntu:latest as builder

#------------------------------------------------------------------------------------------
# 
#------------------------------------------------------------------------------------------
ADD environment environment
#------------------------------------------------------------------------------------------
# UBUNTU CORE
#------------------------------------------------------------------------------------------
FROM builder as ubuntu_core
ARG SCRIPT_UBUNTU=01_ubuntu.sh
ADD ${SCRIPT_UBUNTU}    /tmp/${SCRIPT_UBUNTU}
RUN bash                /tmp/${SCRIPT_UBUNTU}

#------------------------------------------------------------------------------------------
# LOCAL USER
#------------------------------------------------------------------------------------------
ARG SCRIPT_ADD_USER=02_add_user.sh
ADD ${SCRIPT_ADD_USER}  /tmp/${SCRIPT_ADD_USER}
RUN bash /tmp/${SCRIPT_ADD_USER}

#------------------------------------------------------------------------------------------
# NODEJS
#-----------------------------------------------------------------------------------------
FROM ubuntu_core as with_nodejs

ARG SCRIPT_NODEJS=10_nodejs.sh
ADD ${SCRIPT_NODEJS}    /tmp/${SCRIPT_NODEJS}
RUN bash                /tmp/${SCRIPT_NODEJS}

#--------------------------------------------------------------------------------------------------
# JULIA
#--------------------------------------------------------------------------------------------------
FROM with_nodejs as with_julia

ARG SCRIPT_JULIA=11_julia.sh
ADD ${SCRIPT_JULIA} /tmp/${SCRIPT_JULIA}
RUN bash /tmp/${SCRIPT_JULIA}

#---------------------------------------------------------------------------------------------
# ANACONDA3  with Julia Extensions
#---------------------------------------------------------------------------------------------
FROM with_julia as with_anaconda

ARG SCRIPT_ANACONDA=21_anaconda3.sh
ADD ${SCRIPT_ANACONDA} /tmp/${SCRIPT_ANACONDA}
RUN bash /tmp/${SCRIPT_ANACONDA}

#---------------------------------------------------------------------------------------------
#
#---------------------------------------------------------------------------------------------
FROM with_anaconda as with_anaconda_user
ARG SCRIPT_ANACONDA_USER=22_anaconda3_as_user.sh
ADD ${SCRIPT_ANACONDA_USER} /tmp/${SCRIPT_ANACONDA_USER}
#RUN cat ${SCRIPT_ANACONDA_USER} | su user

#---------------------------------------------------------------------------------------------
#
#---------------------------------------------------------------------------------------------
FROM with_anaconda_user as with_cleanup

ARG SCRIPT_CLEANUP=99_cleanup.sh
ADD ${SCRIPT_CLEANUP} /tmp/${SCRIPT_CLEANUP}
RUN bash /tmp/${SCRIPT_CLEANUP}

#=============================================================================================
USER    user
WORKDIR /home/user

#
CMD ["bash"]

Makefile

HERE := ${CURDIR}

CONTAINER := playground_docker

default:
	cat Makefile

build:
	docker build -t ${CONTAINER} .

clean:
	docker_rmi_all
	
run:
	docker run  -it --rm  -p 127.0.0.1:8888:8888 -v ${HERE}:/src:rw -v ${HERE}/notebooks:/notebooks:rw --name ${CONTAINER} ${CONTAINER}

notebook:
	docker run  -it --rm  -p 127.0.0.1:8888:8888 -v ${HERE}:/src:rw -v ${HERE}/notebooks:/notebooks:rw --name ${CONTAINER} ${CONTAINER} bash .local/bin/run_jupyter

Installation scripts

01_ubuntu.sh

#--------------------------------------------------------------------------------------------------
# get environment variables
. environment

#--------------------------------------------------------------------------------------------------
export DEBIAN_FRONTEND=noninteractive
export TZ='Europe/Berlin'

echo $TZ > /etc/timezone 

apt-get update                                       
apt-get install --yes apt-utils

#
apt-get -y install tzdata

rm /etc/localtime
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime
dpkg-reconfigure -f noninteractive tzdata

#
apt-get install --yes build-essential lsb-release curl sudo vim python3-pip

#
echo "root:password" | chpasswd

Laravel Toolbox

Laravel | Vergleich Inertia und Livewire Starter-kit

Vergleich der Dateien

TypeFileFolder
FilesKernel.phplaravel-starter-jetstream-inertia/app/Http
Filespackages.phplaravel-starter-jetstream-inertia/bootstrap/cache
Filesservices.phplaravel-starter-jetstream-inertia/bootstrap/cache
Filescomposer.jsonlaravel-starter-jetstream-inertia
Filesjetstream.phplaravel-starter-jetstream-inertia/config
Filespackage.jsonlaravel-starter-jetstream-inertia
Filesapp.csslaravel-starter-jetstream-inertia/public/css/app.css
Filesapp.jslaravel-starter-jetstream-inertia/public/js
Filesapp.jslaravel-starter-jetstream-inertia/resources/js
Filesweb.phplaravel-starter-jetstream-inertia/routes
Filestailwind.config.jslaravel-starter-jetstream-inertia
FilesApiTokenPermissionsTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesBrowserSessionsTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesCreateApiTokenTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesCreateTeamTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesDeleteAccountTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesDeleteApiTokenTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesDeleteTeamTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesInviteTeamMemberTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesLeaveTeamTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesProfileInformationTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesRemoveTeamMemberTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesTwoFactorAuthenticationSettingsTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesUpdatePasswordTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesUpdateTeamMemberRoleTest.phplaravel-starter-jetstream-inertia/tests/Feature
FilesUpdateTeamNameTest.phplaravel-starter-jetstream-inertia/tests/Feature
Filesautoload.phplaravel-starter-jetstream-inertia/vendor
Filesautoload_classmap.phplaravel-starter-jetstream-inertia/vendor/composer
Filesautoload_files.phplaravel-starter-jetstream-inertia/vendor/composer
Filesautoload_psr4.phplaravel-starter-jetstream-inertia/vendor/composer
Filesautoload_real.phplaravel-starter-jetstream-inertia/vendor/composer
Filesautoload_static.phplaravel-starter-jetstream-inertia/vendor/composer
Filesinstalled.jsonlaravel-starter-jetstream-inertia/vendor/composer
Filesinstalled.phplaravel-starter-jetstream-inertia/vendor/composer
Fileswebpack.mix.jslaravel-starter-jetstream-inertia
Only incomposer.locklaravel-starter-jetstream-inertia
Only inwebpack.config.jslaravel-starter-jetstream-inertia
Only inHandleInertiaRequests.phplaravel-starter-jetstream-inertia/app/Http/Middleware
Only in2022_01_16_142014_create_sessions_table.phplaravel-starter-jetstream-inertia/database/migrations
Only inJetstreamlaravel-starter-jetstream-inertia/resources/js
Only inLayoutslaravel-starter-jetstream-inertia/resources/js
Only inPageslaravel-starter-jetstream-inertia/resources/js
Only inapp.blade.phplaravel-starter-jetstream-inertia/resources/views
Only inlaravel.loglaravel-starter-jetstream-inertia/storage/logs
Only ininertiajslaravel-starter-jetstream-inertia/vendor
Only intightencolaravel-starter-jetstream-inertia/vendor
Only inViewlaravel-starter-jetstream-livewire/app
Only in2022_01_16_142135_create_sessions_table.phplaravel-starter-jetstream-livewire/database/migrations
Only inapilaravel-starter-jetstream-livewire/resources/views
Only inauthlaravel-starter-jetstream-livewire/resources/views
Only indashboard.blade.phplaravel-starter-jetstream-livewire/resources/views
Only inlayoutslaravel-starter-jetstream-livewire/resources/views
Only innavigation-menu.blade.phplaravel-starter-jetstream-livewire/resources/views
Only inpolicy.blade.phplaravel-starter-jetstream-livewire/resources/views
Only inprofilelaravel-starter-jetstream-livewire/resources/views
Only inteamslaravel-starter-jetstream-livewire/resources/views
Only interms.blade.phplaravel-starter-jetstream-livewire/resources/views
Only inwelcome.blade.phplaravel-starter-jetstream-livewire/resources/views
Only inlivewirelaravel-starter-jetstream-livewire/vendor

Änderungen

app/Http/Kernel.php

Changes

<             \App\Http\Middleware\HandleInertiaRequests::class,

Only inapp/Http/Middleware: HandleInertiaRequests.php

Only inlaravel-starter-jetstream-livewire/app: View

bootstrap/cache/packages.php

Changes

<   'inertiajs/inertia-laravel' => 
<   array (
<     'providers' => 
<     array (
<       0 => 'Inertia\\ServiceProvider',
<     ),
<   ),

Changes

<   'nesbot/carbon' => 
---
>   'livewire/livewire' =>

Changes

<       0 => 'Carbon\\Laravel\\ServiceProvider',
---
>       0 => 'Livewire\\LivewireServiceProvider',
>     ),
>     'aliases' => 
>     array (
>       'Livewire' => 'Livewire\\Livewire',

Changes

<   'nunomaduro/collision' => 
---
>   'nesbot/carbon' =>

Changes

<       0 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',
---
>       0 => 'Carbon\\Laravel\\ServiceProvider',

Changes

<   'tightenco/ziggy' => 
---
>   'nunomaduro/collision' =>

Changes

<       0 => 'Tightenco\\Ziggy\\ZiggyServiceProvider',
---
>       0 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider',

bootstrap/cache/services.php

Changes

<     24 => 'Inertia\\ServiceProvider',
<     25 => 'Jenssegers\\Agent\\AgentServiceProvider',
<     26 => 'Laravel\\Fortify\\FortifyServiceProvider',
<     27 => 'Laravel\\Jetstream\\JetstreamServiceProvider',
<     28 => 'Laravel\\Sail\\SailServiceProvider',
<     29 => 'Laravel\\Sanctum\\SanctumServiceProvider',
<     30 => 'Laravel\\Tinker\\TinkerServiceProvider',
---
>     24 => 'Jenssegers\\Agent\\AgentServiceProvider',
>     25 => 'Laravel\\Fortify\\FortifyServiceProvider',
>     26 => 'Laravel\\Jetstream\\JetstreamServiceProvider',
>     27 => 'Laravel\\Sail\\SailServiceProvider',
>     28 => 'Laravel\\Sanctum\\SanctumServiceProvider',
>     29 => 'Laravel\\Tinker\\TinkerServiceProvider',
>     30 => 'Livewire\\LivewireServiceProvider',

Changes

<     33 => 'Tightenco\\Ziggy\\ZiggyServiceProvider',
<     34 => 'App\\Providers\\AppServiceProvider',
<     35 => 'App\\Providers\\AuthServiceProvider',
<     36 => 'App\\Providers\\EventServiceProvider',
<     37 => 'App\\Providers\\RouteServiceProvider',
<     38 => 'App\\Providers\\FortifyServiceProvider',
<     39 => 'App\\Providers\\JetstreamServiceProvider',
---
>     33 => 'App\\Providers\\AppServiceProvider',
>     34 => 'App\\Providers\\AuthServiceProvider',
>     35 => 'App\\Providers\\EventServiceProvider',
>     36 => 'App\\Providers\\RouteServiceProvider',
>     37 => 'App\\Providers\\FortifyServiceProvider',
>     38 => 'App\\Providers\\JetstreamServiceProvider',

Changes

<     12 => 'Inertia\\ServiceProvider',
<     13 => 'Jenssegers\\Agent\\AgentServiceProvider',
<     14 => 'Laravel\\Fortify\\FortifyServiceProvider',
<     15 => 'Laravel\\Jetstream\\JetstreamServiceProvider',
<     16 => 'Laravel\\Sanctum\\SanctumServiceProvider',
---
>     12 => 'Jenssegers\\Agent\\AgentServiceProvider',
>     13 => 'Laravel\\Fortify\\FortifyServiceProvider',
>     14 => 'Laravel\\Jetstream\\JetstreamServiceProvider',
>     15 => 'Laravel\\Sanctum\\SanctumServiceProvider',
>     16 => 'Livewire\\LivewireServiceProvider',

Changes

<     19 => 'Tightenco\\Ziggy\\ZiggyServiceProvider',
<     20 => 'App\\Providers\\AppServiceProvider',
<     21 => 'App\\Providers\\AuthServiceProvider',
<     22 => 'App\\Providers\\EventServiceProvider',
<     23 => 'App\\Providers\\RouteServiceProvider',
<     24 => 'App\\Providers\\FortifyServiceProvider',
<     25 => 'App\\Providers\\JetstreamServiceProvider',
---
>     19 => 'App\\Providers\\AppServiceProvider',
>     20 => 'App\\Providers\\AuthServiceProvider',
>     21 => 'App\\Providers\\EventServiceProvider',
>     22 => 'App\\Providers\\RouteServiceProvider',
>     23 => 'App\\Providers\\FortifyServiceProvider',
>     24 => 'App\\Providers\\JetstreamServiceProvider',

composer.json

Changes

<         "inertiajs/inertia-laravel": "^0.5.2",

Changes

<         "tightenco/ziggy": "^1.0"
---
>         "livewire/livewire": "^2.5"

Only in laravel-starter-jetstream-inertia: composer.lock

config/jetstream.php

Changes

<     'stack' => 'inertia',
---
>     'stack' => 'livewire',

Only in database/migrations: 2022_01_16_142014_create_sessions_table.php

Only in

package.json

Changes

<         "@inertiajs/inertia": "^0.10.0",
<         "@inertiajs/inertia-vue3": "^0.5.1",
<         "@inertiajs/progress": "^0.2.6",

Changes

<         "@vue/compiler-sfc": "^3.0.5",
---
>         "alpinejs": "^3.0.6",

Changes

<         "postcss-import": "^12.0.1",
---
>         "postcss-import": "^14.0.1",

Changes

<         "vue": "^3.0.5",
<         "vue-loader": "^16.1.2",

Only in laravel-starter-jetstream-livewire: pnpm-lock.yaml

Only in resources/js: Jetstream

Only in resources/js: Layouts

Only in resources/js: Pages

resources/js/app.js

Changes

< import { createApp, h } from 'vue';
< import { createInertiaApp } from '@inertiajs/inertia-vue3';
< import { InertiaProgress } from '@inertiajs/progress';
---
> import Alpine from 'alpinejs';

Changes

< const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';
---
> window.Alpine = Alpine;

Changes

< createInertiaApp({
<     title: (title) => `${title} - ${appName}`,
<     resolve: (name) => require(`./Pages/${name}.vue`),
<     setup({ el, app, props, plugin }) {
<         return createApp({ render: () => h(app, props) })
<             .use(plugin)
<             .mixin({ methods: { route } })
<             .mount(el);
<     },
< });
< 
< InertiaProgress.init({ color: '#4B5563' });
---
> Alpine.start();

Only in

Only in resources/views: app.blade.php

Only in

Only in

Only in

Only inlaravel-starter-jetstream-livewire/resources/views: navigation-menu.blade.php

Only inlaravel-starter-jetstream-livewire/resources/views: policy.blade.php

Only inlaravel-starter-jetstream-livewire/resources/views: profile

Only inlaravel-starter-jetstream-livewire/resources/views: teams

Only inlaravel-starter-jetstream-livewire/resources/views: terms.blade.php

Only inlaravel-starter-jetstream-livewire/resources/views: welcome.blade.php

routes/web.php

Changes

< use Illuminate\Foundation\Application;

Changes

< use Inertia\Inertia;

Changes

<     return Inertia::render('Welcome', [
<         'canLogin' => Route::has('login'),
<         'canRegister' => Route::has('register'),
<         'laravelVersion' => Application::VERSION,
<         'phpVersion' => PHP_VERSION,
<     ]);
---
>     return view('welcome');

Changes

<     return Inertia::render('Dashboard');
---
>     return view('dashboard');

Only instorage/logs: laravel.log

tailwind.config.js

Changes

<         './resources/js/**/*.vue',

tests/Feature/ApiTokenPermissionsTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\ApiTokenManager;
> use Livewire\Livewire;

Changes

<         $response = $this->put('/user/api-tokens/'.$token->id, [
<             'name' => $token->name,
<             'permissions' => [
<                 'delete',
<                 'missing-permission',
<             ],
<         ]);
---
>         Livewire::test(ApiTokenManager::class)
>                     ->set(['managingPermissionsFor' => $token])
>                     ->set(['updateApiTokenForm' => [
>                         'permissions' => [
>                             'delete',
>                             'missing-permission',
>                         ],
>                     ]])
>                     ->call('updateApiToken');
## tests/Feature/BrowserSessionsTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\LogoutOtherBrowserSessionsForm;
> use Livewire\Livewire;

Changes

<         $response = $this->delete('/user/other-browser-sessions', [
<             'password' => 'password',
<         ]);
< 
<         $response->assertSessionHasNoErrors();
---
>         Livewire::test(LogoutOtherBrowserSessionsForm::class)
>                 ->set('password', 'password')
>                 ->call('logoutOtherBrowserSessions');
## tests/Feature/CreateApiTokenTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\ApiTokenManager;
> use Livewire\Livewire;

Changes

<         $response = $this->post('/user/api-tokens', [
<             'name' => 'Test Token',
<             'permissions' => [
<                 'read',
<                 'update',
<             ],
<         ]);
---
>         Livewire::test(ApiTokenManager::class)
>                     ->set(['createApiTokenForm' => [
>                         'name' => 'Test Token',
>                         'permissions' => [
>                             'read',
>                             'update',
>                         ],
>                     ]])
>                     ->call('createApiToken');
## tests/Feature/CreateTeamTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\CreateTeamForm;
> use Livewire\Livewire;

Changes

<         $response = $this->post('/teams', [
<             'name' => 'Test Team',
<         ]);
---
>         Livewire::test(CreateTeamForm::class)
>                     ->set(['state' => ['name' => 'Test Team']])
>                     ->call('createTeam');
## tests/Feature/DeleteAccountTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\DeleteUserForm;
> use Livewire\Livewire;

Changes

<         $response = $this->delete('/user', [
<             'password' => 'password',
<         ]);
---
>         $component = Livewire::test(DeleteUserForm::class)
>                         ->set('password', 'password')
>                         ->call('deleteUser');

Changes

<         $response = $this->delete('/user', [
<             'password' => 'wrong-password',
<         ]);
---
>         Livewire::test(DeleteUserForm::class)
>                         ->set('password', 'wrong-password')
>                         ->call('deleteUser')
>                         ->assertHasErrors(['password']);
## tests/Feature/DeleteApiTokenTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\ApiTokenManager;
> use Livewire\Livewire;

Changes

<         $response = $this->delete('/user/api-tokens/'.$token->id);
---
>         Livewire::test(ApiTokenManager::class)
>                     ->set(['apiTokenIdBeingDeleted' => $token->id])
>                     ->call('deleteApiToken');
## tests/Feature/DeleteTeamTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\DeleteTeamForm;
> use Livewire\Livewire;

Changes

<         $response = $this->delete('/teams/'.$team->id);
---
>         $component = Livewire::test(DeleteTeamForm::class, ['team' => $team->fresh()])
>                                 ->call('deleteTeam');

Changes

<         $response = $this->delete('/teams/'.$user->currentTeam->id);
---
>         $component = Livewire::test(DeleteTeamForm::class, ['team' => $user->currentTeam])
>                                 ->call('deleteTeam')
>                                 ->assertHasErrors(['team']);
## tests/Feature/InviteTeamMemberTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\TeamMemberManager;

Changes

> use Livewire\Livewire;

Changes

<         $response = $this->post('/teams/'.$user->currentTeam->id.'/members', [
<             'email' => 'test@example.com',
<             'role' => 'admin',
<         ]);
---
>         $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
>                         ->set('addTeamMemberForm', [
>                             'email' => 'test@example.com',
>                             'role' => 'admin',
>                         ])->call('addTeamMember');

Changes

<         $invitation = $user->currentTeam->teamInvitations()->create([
<             'email' => 'test@example.com',
<             'role' => 'admin',
<         ]);
---
>         // Add the team member...
>         $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
>                         ->set('addTeamMemberForm', [
>                             'email' => 'test@example.com',
>                             'role' => 'admin',
>                         ])->call('addTeamMember');

Changes

<         $response = $this->delete('/team-invitations/'.$invitation->id);
---
>         $invitationId = $user->currentTeam->fresh()->teamInvitations->first()->id;
> 
>         // Cancel the team invitation...
>         $component->call('cancelTeamInvitation', $invitationId);

tests/Feature/LeaveTeamTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\TeamMemberManager;
> use Livewire\Livewire;

Changes

<         $response = $this->delete('/teams/'.$user->currentTeam->id.'/members/'.$otherUser->id);
---
>         $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
>                         ->call('leaveTeam');

Changes

<         $response = $this->delete('/teams/'.$user->currentTeam->id.'/members/'.$user->id);
< 
<         $response->assertSessionHasErrorsIn('removeTeamMember', ['team']);
---
>         $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
>                         ->call('leaveTeam')
>                         ->assertHasErrors(['team']);
## tests/Feature/ProfileInformationTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\UpdateProfileInformationForm;
> use Livewire\Livewire;

Changes

>     public function test_current_profile_information_is_available()
>     {
>         $this->actingAs($user = User::factory()->create());
> 
>         $component = Livewire::test(UpdateProfileInformationForm::class);
> 
>         $this->assertEquals($user->name, $component->state['name']);
>         $this->assertEquals($user->email, $component->state['email']);
>     }
> 

Changes

<         $response = $this->put('/user/profile-information', [
<             'name' => 'Test Name',
<             'email' => 'test@example.com',
<         ]);
---
>         Livewire::test(UpdateProfileInformationForm::class)
>                 ->set('state', ['name' => 'Test Name', 'email' => 'test@example.com'])
>                 ->call('updateProfileInformation');
## tests/Feature/RemoveTeamMemberTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\TeamMemberManager;
> use Livewire\Livewire;

Changes

<         $response = $this->delete('/teams/'.$user->currentTeam->id.'/members/'.$otherUser->id);
---
>         $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
>                         ->set('teamMemberIdBeingRemoved', $otherUser->id)
>                         ->call('removeTeamMember');

Changes

<         $response = $this->delete('/teams/'.$user->currentTeam->id.'/members/'.$user->id);
< 
<         $response->assertStatus(403);
---
>         $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
>                         ->set('teamMemberIdBeingRemoved', $user->id)
>                         ->call('removeTeamMember')
>                         ->assertStatus(403);
## tests/Feature/TwoFactorAuthenticationSettingsTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\TwoFactorAuthenticationForm;
> use Livewire\Livewire;

Changes

<         $response = $this->post('/user/two-factor-authentication');
---
>         Livewire::test(TwoFactorAuthenticationForm::class)
>                 ->call('enableTwoFactorAuthentication');

Changes

<         $this->assertNotNull($user->fresh()->two_factor_secret);
<         $this->assertCount(8, $user->fresh()->recoveryCodes());
---
>         $user = $user->fresh();
> 
>         $this->assertNotNull($user->two_factor_secret);
>         $this->assertCount(8, $user->recoveryCodes());

Changes

<         $this->post('/user/two-factor-authentication');
<         $this->post('/user/two-factor-recovery-codes');
---
>         $component = Livewire::test(TwoFactorAuthenticationForm::class)
>                 ->call('enableTwoFactorAuthentication')
>                 ->call('regenerateRecoveryCodes');

Changes

<         $this->post('/user/two-factor-recovery-codes');
---
>         $component->call('regenerateRecoveryCodes');

Changes

<         $this->post('/user/two-factor-authentication');
---
>         $component = Livewire::test(TwoFactorAuthenticationForm::class)
>                 ->call('enableTwoFactorAuthentication');

Changes

<         $this->delete('/user/two-factor-authentication');
---
>         $component->call('disableTwoFactorAuthentication');
## tests/Feature/UpdatePasswordTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\UpdatePasswordForm;
> use Livewire\Livewire;

Changes

<         $response = $this->put('/user/password', [
<             'current_password' => 'password',
<             'password' => 'new-password',
<             'password_confirmation' => 'new-password',
<         ]);
---
>         Livewire::test(UpdatePasswordForm::class)
>                 ->set('state', [
>                     'current_password' => 'password',
>                     'password' => 'new-password',
>                     'password_confirmation' => 'new-password',
>                 ])
>                 ->call('updatePassword');

Changes

<         $response = $this->put('/user/password', [
<             'current_password' => 'wrong-password',
<             'password' => 'new-password',
<             'password_confirmation' => 'new-password',
<         ]);
< 
<         $response->assertSessionHasErrors();
---
>         Livewire::test(UpdatePasswordForm::class)
>                 ->set('state', [
>                     'current_password' => 'wrong-password',
>                     'password' => 'new-password',
>                     'password_confirmation' => 'new-password',
>                 ])
>                 ->call('updatePassword')
>                 ->assertHasErrors(['current_password']);

Changes

<         $response = $this->put('/user/password', [
<             'current_password' => 'password',
<             'password' => 'new-password',
<             'password_confirmation' => 'wrong-password',
<         ]);
< 
<         $response->assertSessionHasErrors();
---
>         Livewire::test(UpdatePasswordForm::class)
>                 ->set('state', [
>                     'current_password' => 'password',
>                     'password' => 'new-password',
>                     'password_confirmation' => 'wrong-password',
>                 ])
>                 ->call('updatePassword')
>                 ->assertHasErrors(['password']);
## tests/Feature/UpdateTeamMemberRoleTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\TeamMemberManager;
> use Livewire\Livewire;

Changes

<         $response = $this->put('/teams/'.$user->currentTeam->id.'/members/'.$otherUser->id, [
<             'role' => 'editor',
<         ]);
---
>         $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
>                         ->set('managingRoleFor', $otherUser)
>                         ->set('currentRole', 'editor')
>                         ->call('updateRole');

Changes

<         $response = $this->put('/teams/'.$user->currentTeam->id.'/members/'.$otherUser->id, [
<             'role' => 'editor',
<         ]);
---
>         $component = Livewire::test(TeamMemberManager::class, ['team' => $user->currentTeam])
>                         ->set('managingRoleFor', $otherUser)
>                         ->set('currentRole', 'editor')
>                         ->call('updateRole')
>                         ->assertStatus(403);
## tests/Feature/UpdateTeamNameTest.php

Changes

> use Laravel\Jetstream\Http\Livewire\UpdateTeamNameForm;
> use Livewire\Livewire;

Changes

<         $response = $this->put('/teams/'.$user->currentTeam->id, [
<             'name' => 'Test Team',
<         ]);
---
>         Livewire::test(UpdateTeamNameForm::class, ['team' => $user->currentTeam])
>                     ->set(['state' => ['name' => 'Test Team']])
>                     ->call('updateTeamName');

vendor/autoload.php

Changes

< return ComposerAutoloaderInit1a366ea8c9013f37377c59393191f427::getLoader();
---
> return ComposerAutoloaderInitf2da6e83b085fd96649a1eced6ba9cbb::getLoader();
## vendor/composer/autoload_classmap.php

Changes

<     'Inertia\\Console\\CreateMiddleware' => $vendorDir . '/inertiajs/inertia-laravel/src/Console/CreateMiddleware.php',
<     'Inertia\\Controller' => $vendorDir . '/inertiajs/inertia-laravel/src/Controller.php',
<     'Inertia\\Directive' => $vendorDir . '/inertiajs/inertia-laravel/src/Directive.php',
<     'Inertia\\Inertia' => $vendorDir . '/inertiajs/inertia-laravel/src/Inertia.php',
<     'Inertia\\LazyProp' => $vendorDir . '/inertiajs/inertia-laravel/src/LazyProp.php',
<     'Inertia\\Middleware' => $vendorDir . '/inertiajs/inertia-laravel/src/Middleware.php',
<     'Inertia\\Response' => $vendorDir . '/inertiajs/inertia-laravel/src/Response.php',
<     'Inertia\\ResponseFactory' => $vendorDir . '/inertiajs/inertia-laravel/src/ResponseFactory.php',
<     'Inertia\\ServiceProvider' => $vendorDir . '/inertiajs/inertia-laravel/src/ServiceProvider.php',
<     'Inertia\\Ssr\\Gateway' => $vendorDir . '/inertiajs/inertia-laravel/src/Ssr/Gateway.php',
<     'Inertia\\Ssr\\HttpGateway' => $vendorDir . '/inertiajs/inertia-laravel/src/Ssr/HttpGateway.php',
<     'Inertia\\Ssr\\Response' => $vendorDir . '/inertiajs/inertia-laravel/src/Ssr/Response.php',
<     'Inertia\\Testing\\Assert' => $vendorDir . '/inertiajs/inertia-laravel/src/Testing/Assert.php',
<     'Inertia\\Testing\\AssertableInertia' => $vendorDir . '/inertiajs/inertia-laravel/src/Testing/AssertableInertia.php',
<     'Inertia\\Testing\\Concerns\\Debugging' => $vendorDir . '/inertiajs/inertia-laravel/src/Testing/Concerns/Debugging.php',
<     'Inertia\\Testing\\Concerns\\Has' => $vendorDir . '/inertiajs/inertia-laravel/src/Testing/Concerns/Has.php',
<     'Inertia\\Testing\\Concerns\\Interaction' => $vendorDir . '/inertiajs/inertia-laravel/src/Testing/Concerns/Interaction.php',
<     'Inertia\\Testing\\Concerns\\Matching' => $vendorDir . '/inertiajs/inertia-laravel/src/Testing/Concerns/Matching.php',
<     'Inertia\\Testing\\Concerns\\PageObject' => $vendorDir . '/inertiajs/inertia-laravel/src/Testing/Concerns/PageObject.php',
<     'Inertia\\Testing\\TestResponseMacros' => $vendorDir . '/inertiajs/inertia-laravel/src/Testing/TestResponseMacros.php',

Changes

>     'Livewire\\Castable' => $vendorDir . '/livewire/livewire/src/Castable.php',
>     'Livewire\\Commands\\ComponentParser' => $vendorDir . '/livewire/livewire/src/Commands/ComponentParser.php',
>     'Livewire\\Commands\\ComponentParserFromExistingComponent' => $vendorDir . '/livewire/livewire/src/Commands/ComponentParserFromExistingComponent.php',
>     'Livewire\\Commands\\CopyCommand' => $vendorDir . '/livewire/livewire/src/Commands/CopyCommand.php',
>     'Livewire\\Commands\\CpCommand' => $vendorDir . '/livewire/livewire/src/Commands/CpCommand.php',
>     'Livewire\\Commands\\DeleteCommand' => $vendorDir . '/livewire/livewire/src/Commands/DeleteCommand.php',
>     'Livewire\\Commands\\DiscoverCommand' => $vendorDir . '/livewire/livewire/src/Commands/DiscoverCommand.php',
>     'Livewire\\Commands\\FileManipulationCommand' => $vendorDir . '/livewire/livewire/src/Commands/FileManipulationCommand.php',
>     'Livewire\\Commands\\MakeCommand' => $vendorDir . '/livewire/livewire/src/Commands/MakeCommand.php',
>     'Livewire\\Commands\\MakeLivewireCommand' => $vendorDir . '/livewire/livewire/src/Commands/MakeLivewireCommand.php',
>     'Livewire\\Commands\\MoveCommand' => $vendorDir . '/livewire/livewire/src/Commands/MoveCommand.php',
>     'Livewire\\Commands\\MvCommand' => $vendorDir . '/livewire/livewire/src/Commands/MvCommand.php',
>     'Livewire\\Commands\\PublishCommand' => $vendorDir . '/livewire/livewire/src/Commands/PublishCommand.php',
>     'Livewire\\Commands\\RmCommand' => $vendorDir . '/livewire/livewire/src/Commands/RmCommand.php',
>     'Livewire\\Commands\\S3CleanupCommand' => $vendorDir . '/livewire/livewire/src/Commands/S3CleanupCommand.php',
>     'Livewire\\Commands\\StubParser' => $vendorDir . '/livewire/livewire/src/Commands/StubParser.php',
>     'Livewire\\Commands\\StubsCommand' => $vendorDir . '/livewire/livewire/src/Commands/StubsCommand.php',
>     'Livewire\\Commands\\TouchCommand' => $vendorDir . '/livewire/livewire/src/Commands/TouchCommand.php',
>     'Livewire\\CompilerEngineForIgnition' => $vendorDir . '/livewire/livewire/src/CompilerEngineForIgnition.php',
>     'Livewire\\Component' => $vendorDir . '/livewire/livewire/src/Component.php',
>     'Livewire\\ComponentChecksumManager' => $vendorDir . '/livewire/livewire/src/ComponentChecksumManager.php',
>     'Livewire\\ComponentConcerns\\HandlesActions' => $vendorDir . '/livewire/livewire/src/ComponentConcerns/HandlesActions.php',
>     'Livewire\\ComponentConcerns\\InteractsWithProperties' => $vendorDir . '/livewire/livewire/src/ComponentConcerns/InteractsWithProperties.php',
>     'Livewire\\ComponentConcerns\\PerformsRedirects' => $vendorDir . '/livewire/livewire/src/ComponentConcerns/PerformsRedirects.php',
>     'Livewire\\ComponentConcerns\\ReceivesEvents' => $vendorDir . '/livewire/livewire/src/ComponentConcerns/ReceivesEvents.php',
>     'Livewire\\ComponentConcerns\\RendersLivewireComponents' => $vendorDir . '/livewire/livewire/src/ComponentConcerns/RendersLivewireComponents.php',
>     'Livewire\\ComponentConcerns\\TracksRenderedChildren' => $vendorDir . '/livewire/livewire/src/ComponentConcerns/TracksRenderedChildren.php',
>     'Livewire\\ComponentConcerns\\ValidatesInput' => $vendorDir . '/livewire/livewire/src/ComponentConcerns/ValidatesInput.php',
>     'Livewire\\Connection\\ConnectionHandler' => $vendorDir . '/livewire/livewire/src/Connection/ConnectionHandler.php',
>     'Livewire\\Controllers\\CanPretendToBeAFile' => $vendorDir . '/livewire/livewire/src/Controllers/CanPretendToBeAFile.php',
>     'Livewire\\Controllers\\FilePreviewHandler' => $vendorDir . '/livewire/livewire/src/Controllers/FilePreviewHandler.php',
>     'Livewire\\Controllers\\FileUploadHandler' => $vendorDir . '/livewire/livewire/src/Controllers/FileUploadHandler.php',
>     'Livewire\\Controllers\\HttpConnectionHandler' => $vendorDir . '/livewire/livewire/src/Controllers/HttpConnectionHandler.php',
>     'Livewire\\Controllers\\LivewireJavaScriptAssets' => $vendorDir . '/livewire/livewire/src/Controllers/LivewireJavaScriptAssets.php',
>     'Livewire\\CreateBladeView' => $vendorDir . '/livewire/livewire/src/CreateBladeView.php',
>     'Livewire\\DisableBrowserCache' => $vendorDir . '/livewire/livewire/src/DisableBrowserCache.php',
>     'Livewire\\Event' => $vendorDir . '/livewire/livewire/src/Event.php',
>     'Livewire\\Exceptions\\BypassViewHandler' => $vendorDir . '/livewire/livewire/src/Exceptions/BypassViewHandler.php',
>     'Livewire\\Exceptions\\CannotBindToModelDataWithoutValidationRuleException' => $vendorDir . '/livewire/livewire/src/Exceptions/CannotBindToModelDataWithoutValidationRuleException.php',
>     'Livewire\\Exceptions\\CannotUseReservedLivewireComponentProperties' => $vendorDir . '/livewire/livewire/src/Exceptions/CannotUseReservedLivewireComponentProperties.php',
>     'Livewire\\Exceptions\\ComponentAttributeMissingOnDynamicComponentException' => $vendorDir . '/livewire/livewire/src/Exceptions/ComponentAttributeMissingOnDynamicComponentException.php',
>     'Livewire\\Exceptions\\ComponentNotFoundException' => $vendorDir . '/livewire/livewire/src/Exceptions/ComponentNotFoundException.php',
>     'Livewire\\Exceptions\\CorruptComponentPayloadException' => $vendorDir . '/livewire/livewire/src/Exceptions/CorruptComponentPayloadException.php',
>     'Livewire\\Exceptions\\DirectlyCallingLifecycleHooksNotAllowedException' => $vendorDir . '/livewire/livewire/src/Exceptions/DirectlyCallingLifecycleHooksNotAllowedException.php',
>     'Livewire\\Exceptions\\LivewirePageExpiredBecauseNewDeploymentHasSignificantEnoughChanges' => $vendorDir . '/livewire/livewire/src/Exceptions/LivewirePageExpiredBecauseNewDeploymentHasSignificantEnoughChanges.php',
>     'Livewire\\Exceptions\\MethodNotFoundException' => $vendorDir . '/livewire/livewire/src/Exceptions/MethodNotFoundException.php',
>     'Livewire\\Exceptions\\MissingFileUploadsTraitException' => $vendorDir . '/livewire/livewire/src/Exceptions/MissingFileUploadsTraitException.php',
>     'Livewire\\Exceptions\\MissingRulesException' => $vendorDir . '/livewire/livewire/src/Exceptions/MissingRulesException.php',
>     'Livewire\\Exceptions\\NonPublicComponentMethodCall' => $vendorDir . '/livewire/livewire/src/Exceptions/NonPublicComponentMethodCall.php',
>     'Livewire\\Exceptions\\PropertyNotFoundException' => $vendorDir . '/livewire/livewire/src/Exceptions/PropertyNotFoundException.php',
>     'Livewire\\Exceptions\\PublicPropertyNotFoundException' => $vendorDir . '/livewire/livewire/src/Exceptions/PublicPropertyNotFoundException.php',
>     'Livewire\\Exceptions\\PublicPropertyTypeNotAllowedException' => $vendorDir . '/livewire/livewire/src/Exceptions/PublicPropertyTypeNotAllowedException.php',
>     'Livewire\\Exceptions\\RootTagMissingFromViewException' => $vendorDir . '/livewire/livewire/src/Exceptions/RootTagMissingFromViewException.php',
>     'Livewire\\Exceptions\\S3DoesntSupportMultipleFileUploads' => $vendorDir . '/livewire/livewire/src/Exceptions/S3DoesntSupportMultipleFileUploads.php',
>     'Livewire\\Features\\OptimizeRenderedDom' => $vendorDir . '/livewire/livewire/src/Features/OptimizeRenderedDom.php',
>     'Livewire\\Features\\Placeholder' => $vendorDir . '/livewire/livewire/src/Features/Placeholder.php',
>     'Livewire\\Features\\SupportActionReturns' => $vendorDir . '/livewire/livewire/src/Features/SupportActionReturns.php',
>     'Livewire\\Features\\SupportBootMethod' => $vendorDir . '/livewire/livewire/src/Features/SupportBootMethod.php',
>     'Livewire\\Features\\SupportBrowserHistory' => $vendorDir . '/livewire/livewire/src/Features/SupportBrowserHistory.php',
>     'Livewire\\Features\\SupportChildren' => $vendorDir . '/livewire/livewire/src/Features/SupportChildren.php',
>     'Livewire\\Features\\SupportCollections' => $vendorDir . '/livewire/livewire/src/Features/SupportCollections.php',
>     'Livewire\\Features\\SupportComponentTraits' => $vendorDir . '/livewire/livewire/src/Features/SupportComponentTraits.php',
>     'Livewire\\Features\\SupportDateTimes' => $vendorDir . '/livewire/livewire/src/Features/SupportDateTimes.php',
>     'Livewire\\Features\\SupportEvents' => $vendorDir . '/livewire/livewire/src/Features/SupportEvents.php',
>     'Livewire\\Features\\SupportFileDownloads' => $vendorDir . '/livewire/livewire/src/Features/SupportFileDownloads.php',
>     'Livewire\\Features\\SupportFileUploads' => $vendorDir . '/livewire/livewire/src/Features/SupportFileUploads.php',
>     'Livewire\\Features\\SupportLocales' => $vendorDir . '/livewire/livewire/src/Features/SupportLocales.php',
>     'Livewire\\Features\\SupportPostDeploymentInvalidation' => $vendorDir . '/livewire/livewire/src/Features/SupportPostDeploymentInvalidation.php',
>     'Livewire\\Features\\SupportRedirects' => $vendorDir . '/livewire/livewire/src/Features/SupportRedirects.php',
>     'Livewire\\Features\\SupportRootElementTracking' => $vendorDir . '/livewire/livewire/src/Features/SupportRootElementTracking.php',
>     'Livewire\\Features\\SupportStacks' => $vendorDir . '/livewire/livewire/src/Features/SupportStacks.php',
>     'Livewire\\Features\\SupportValidation' => $vendorDir . '/livewire/livewire/src/Features/SupportValidation.php',
>     'Livewire\\FileUploadConfiguration' => $vendorDir . '/livewire/livewire/src/FileUploadConfiguration.php',
>     'Livewire\\GenerateSignedUploadUrl' => $vendorDir . '/livewire/livewire/src/GenerateSignedUploadUrl.php',
>     'Livewire\\HydrationMiddleware\\AddAttributesToRootTagOfHtml' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/AddAttributesToRootTagOfHtml.php',
>     'Livewire\\HydrationMiddleware\\CallHydrationHooks' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/CallHydrationHooks.php',
>     'Livewire\\HydrationMiddleware\\CallPropertyHydrationHooks' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/CallPropertyHydrationHooks.php',
>     'Livewire\\HydrationMiddleware\\HashDataPropertiesForDirtyDetection' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/HashDataPropertiesForDirtyDetection.php',
>     'Livewire\\HydrationMiddleware\\HydratePublicProperties' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/HydratePublicProperties.php',
>     'Livewire\\HydrationMiddleware\\HydrationMiddleware' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/HydrationMiddleware.php',
>     'Livewire\\HydrationMiddleware\\NormalizeComponentPropertiesForJavaScript' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/NormalizeComponentPropertiesForJavaScript.php',
>     'Livewire\\HydrationMiddleware\\NormalizeDataForJavaScript' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/NormalizeDataForJavaScript.php',
>     'Livewire\\HydrationMiddleware\\NormalizeServerMemoSansDataForJavaScript' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/NormalizeServerMemoSansDataForJavaScript.php',
>     'Livewire\\HydrationMiddleware\\PerformActionCalls' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/PerformActionCalls.php',
>     'Livewire\\HydrationMiddleware\\PerformDataBindingUpdates' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/PerformDataBindingUpdates.php',
>     'Livewire\\HydrationMiddleware\\PerformEventEmissions' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/PerformEventEmissions.php',
>     'Livewire\\HydrationMiddleware\\RenderView' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/RenderView.php',
>     'Livewire\\HydrationMiddleware\\SecureHydrationWithChecksum' => $vendorDir . '/livewire/livewire/src/HydrationMiddleware/SecureHydrationWithChecksum.php',
>     'Livewire\\ImplicitRouteBinding' => $vendorDir . '/livewire/livewire/src/ImplicitRouteBinding.php',
>     'Livewire\\ImplicitlyBoundMethod' => $vendorDir . '/livewire/livewire/src/ImplicitlyBoundMethod.php',
>     'Livewire\\LifecycleManager' => $vendorDir . '/livewire/livewire/src/LifecycleManager.php',
>     'Livewire\\Livewire' => $vendorDir . '/livewire/livewire/src/Livewire.php',
>     'Livewire\\LivewireBladeDirectives' => $vendorDir . '/livewire/livewire/src/LivewireBladeDirectives.php',
>     'Livewire\\LivewireComponentsFinder' => $vendorDir . '/livewire/livewire/src/LivewireComponentsFinder.php',
>     'Livewire\\LivewireManager' => $vendorDir . '/livewire/livewire/src/LivewireManager.php',
>     'Livewire\\LivewireServiceProvider' => $vendorDir . '/livewire/livewire/src/LivewireServiceProvider.php',
>     'Livewire\\LivewireTagCompiler' => $vendorDir . '/livewire/livewire/src/LivewireTagCompiler.php',
>     'Livewire\\LivewireViewCompilerEngine' => $vendorDir . '/livewire/livewire/src/LivewireViewCompilerEngine.php',
>     'Livewire\\Macros\\DuskBrowserMacros' => $vendorDir . '/livewire/livewire/src/Macros/DuskBrowserMacros.php',
>     'Livewire\\Macros\\ViewMacros' => $vendorDir . '/livewire/livewire/src/Macros/ViewMacros.php',
>     'Livewire\\ObjectPrybar' => $vendorDir . '/livewire/livewire/src/ObjectPrybar.php',
>     'Livewire\\Redirector' => $vendorDir . '/livewire/livewire/src/Redirector.php',
>     'Livewire\\Request' => $vendorDir . '/livewire/livewire/src/Request.php',
>     'Livewire\\Response' => $vendorDir . '/livewire/livewire/src/Response.php',
>     'Livewire\\TemporaryUploadedFile' => $vendorDir . '/livewire/livewire/src/TemporaryUploadedFile.php',
>     'Livewire\\Testing\\Concerns\\HasFunLittleUtilities' => $vendorDir . '/livewire/livewire/src/Testing/Concerns/HasFunLittleUtilities.php',
>     'Livewire\\Testing\\Concerns\\MakesAssertions' => $vendorDir . '/livewire/livewire/src/Testing/Concerns/MakesAssertions.php',
>     'Livewire\\Testing\\Concerns\\MakesCallsToComponent' => $vendorDir . '/livewire/livewire/src/Testing/Concerns/MakesCallsToComponent.php',
>     'Livewire\\Testing\\MakesHttpRequestsWrapper' => $vendorDir . '/livewire/livewire/src/Testing/MakesHttpRequestsWrapper.php',
>     'Livewire\\Testing\\TestableLivewire' => $vendorDir . '/livewire/livewire/src/Testing/TestableLivewire.php',
>     'Livewire\\WireDirective' => $vendorDir . '/livewire/livewire/src/WireDirective.php',
>     'Livewire\\Wireable' => $vendorDir . '/livewire/livewire/src/Wireable.php',
>     'Livewire\\WithFileUploads' => $vendorDir . '/livewire/livewire/src/WithFileUploads.php',
>     'Livewire\\WithPagination' => $vendorDir . '/livewire/livewire/src/WithPagination.php',

Changes

<     'Tightenco\\Ziggy\\BladeRouteGenerator' => $vendorDir . '/tightenco/ziggy/src/BladeRouteGenerator.php',
<     'Tightenco\\Ziggy\\CommandRouteGenerator' => $vendorDir . '/tightenco/ziggy/src/CommandRouteGenerator.php',
<     'Tightenco\\Ziggy\\Ziggy' => $vendorDir . '/tightenco/ziggy/src/Ziggy.php',
<     'Tightenco\\Ziggy\\ZiggyServiceProvider' => $vendorDir . '/tightenco/ziggy/src/ZiggyServiceProvider.php',

vendor/composer/autoload_files.php

Changes

<     '98caa11a197f6516a8e48aa4abb5ccc6' => $vendorDir . '/inertiajs/inertia-laravel/helpers.php',
---
>     '40275907c8566c390185147049ef6e5d' => $vendorDir . '/livewire/livewire/src/helpers.php',

vendor/composer/autoload_psr4.php

Changes

<     'Tightenco\\Ziggy\\' => array($vendorDir . '/tightenco/ziggy/src'),

Changes

>     'Livewire\\' => array($vendorDir . '/livewire/livewire/src'),

Changes

<     'Inertia\\' => array($vendorDir . '/inertiajs/inertia-laravel/src'),

vendor/composer/autoload_real.php

Changes

< class ComposerAutoloaderInit1a366ea8c9013f37377c59393191f427
---
> class ComposerAutoloaderInitf2da6e83b085fd96649a1eced6ba9cbb

Changes

<         spl_autoload_register(array('ComposerAutoloaderInit1a366ea8c9013f37377c59393191f427', 'loadClassLoader'), true, true);
---
>         spl_autoload_register(array('ComposerAutoloaderInitf2da6e83b085fd96649a1eced6ba9cbb', 'loadClassLoader'), true, true);

Changes

<         spl_autoload_unregister(array('ComposerAutoloaderInit1a366ea8c9013f37377c59393191f427', 'loadClassLoader'));
---
>         spl_autoload_unregister(array('ComposerAutoloaderInitf2da6e83b085fd96649a1eced6ba9cbb', 'loadClassLoader'));

Changes

<             call_user_func(\Composer\Autoload\ComposerStaticInit1a366ea8c9013f37377c59393191f427::getInitializer($loader));
---
>             call_user_func(\Composer\Autoload\ComposerStaticInitf2da6e83b085fd96649a1eced6ba9cbb::getInitializer($loader));

Changes

<             $includeFiles = Composer\Autoload\ComposerStaticInit1a366ea8c9013f37377c59393191f427::$files;
---
>             $includeFiles = Composer\Autoload\ComposerStaticInitf2da6e83b085fd96649a1eced6ba9cbb::$files;

Changes

<             composerRequire1a366ea8c9013f37377c59393191f427($fileIdentifier, $file);
---
>             composerRequiref2da6e83b085fd96649a1eced6ba9cbb($fileIdentifier, $file);

Changes

< function composerRequire1a366ea8c9013f37377c59393191f427($fileIdentifier, $file)
---
> function composerRequiref2da6e83b085fd96649a1eced6ba9cbb($fileIdentifier, $file)

vendor/composer/autoload_static.php

Changes

< class ComposerStaticInit1a366ea8c9013f37377c59393191f427
---
> class ComposerStaticInitf2da6e83b085fd96649a1eced6ba9cbb

Changes

<         '98caa11a197f6516a8e48aa4abb5ccc6' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/helpers.php',
---
>         '40275907c8566c390185147049ef6e5d' => __DIR__ . '/..' . '/livewire/livewire/src/helpers.php',

Changes

<             'Tightenco\\Ziggy\\' => 16,

Changes

>             'Livewire\\' => 9,

Changes

<             'Inertia\\' => 8,

Changes

<         'Tightenco\\Ziggy\\' => 
<         array (
<             0 => __DIR__ . '/..' . '/tightenco/ziggy/src',
<         ),

Changes

>         'Livewire\\' => 
>         array (
>             0 => __DIR__ . '/..' . '/livewire/livewire/src',
>         ),

Changes

<         'Inertia\\' => 
<         array (
<             0 => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src',
<         ),

Changes

<         'Inertia\\Console\\CreateMiddleware' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Console/CreateMiddleware.php',
<         'Inertia\\Controller' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Controller.php',
<         'Inertia\\Directive' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Directive.php',
<         'Inertia\\Inertia' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Inertia.php',
<         'Inertia\\LazyProp' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/LazyProp.php',
<         'Inertia\\Middleware' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Middleware.php',
<         'Inertia\\Response' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Response.php',
<         'Inertia\\ResponseFactory' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/ResponseFactory.php',
<         'Inertia\\ServiceProvider' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/ServiceProvider.php',
<         'Inertia\\Ssr\\Gateway' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Ssr/Gateway.php',
<         'Inertia\\Ssr\\HttpGateway' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Ssr/HttpGateway.php',
<         'Inertia\\Ssr\\Response' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Ssr/Response.php',
<         'Inertia\\Testing\\Assert' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Testing/Assert.php',
<         'Inertia\\Testing\\AssertableInertia' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Testing/AssertableInertia.php',
<         'Inertia\\Testing\\Concerns\\Debugging' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Testing/Concerns/Debugging.php',
<         'Inertia\\Testing\\Concerns\\Has' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Testing/Concerns/Has.php',
<         'Inertia\\Testing\\Concerns\\Interaction' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Testing/Concerns/Interaction.php',
<         'Inertia\\Testing\\Concerns\\Matching' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Testing/Concerns/Matching.php',
<         'Inertia\\Testing\\Concerns\\PageObject' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Testing/Concerns/PageObject.php',
<         'Inertia\\Testing\\TestResponseMacros' => __DIR__ . '/..' . '/inertiajs/inertia-laravel/src/Testing/TestResponseMacros.php',

Changes

>         'Livewire\\Castable' => __DIR__ . '/..' . '/livewire/livewire/src/Castable.php',
>         'Livewire\\Commands\\ComponentParser' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/ComponentParser.php',
>         'Livewire\\Commands\\ComponentParserFromExistingComponent' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/ComponentParserFromExistingComponent.php',
>         'Livewire\\Commands\\CopyCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/CopyCommand.php',
>         'Livewire\\Commands\\CpCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/CpCommand.php',
>         'Livewire\\Commands\\DeleteCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/DeleteCommand.php',
>         'Livewire\\Commands\\DiscoverCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/DiscoverCommand.php',
>         'Livewire\\Commands\\FileManipulationCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/FileManipulationCommand.php',
>         'Livewire\\Commands\\MakeCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/MakeCommand.php',
>         'Livewire\\Commands\\MakeLivewireCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/MakeLivewireCommand.php',
>         'Livewire\\Commands\\MoveCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/MoveCommand.php',
>         'Livewire\\Commands\\MvCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/MvCommand.php',
>         'Livewire\\Commands\\PublishCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/PublishCommand.php',
>         'Livewire\\Commands\\RmCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/RmCommand.php',
>         'Livewire\\Commands\\S3CleanupCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/S3CleanupCommand.php',
>         'Livewire\\Commands\\StubParser' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/StubParser.php',
>         'Livewire\\Commands\\StubsCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/StubsCommand.php',
>         'Livewire\\Commands\\TouchCommand' => __DIR__ . '/..' . '/livewire/livewire/src/Commands/TouchCommand.php',
>         'Livewire\\CompilerEngineForIgnition' => __DIR__ . '/..' . '/livewire/livewire/src/CompilerEngineForIgnition.php',
>         'Livewire\\Component' => __DIR__ . '/..' . '/livewire/livewire/src/Component.php',
>         'Livewire\\ComponentChecksumManager' => __DIR__ . '/..' . '/livewire/livewire/src/ComponentChecksumManager.php',
>         'Livewire\\ComponentConcerns\\HandlesActions' => __DIR__ . '/..' . '/livewire/livewire/src/ComponentConcerns/HandlesActions.php',
>         'Livewire\\ComponentConcerns\\InteractsWithProperties' => __DIR__ . '/..' . '/livewire/livewire/src/ComponentConcerns/InteractsWithProperties.php',
>         'Livewire\\ComponentConcerns\\PerformsRedirects' => __DIR__ . '/..' . '/livewire/livewire/src/ComponentConcerns/PerformsRedirects.php',
>         'Livewire\\ComponentConcerns\\ReceivesEvents' => __DIR__ . '/..' . '/livewire/livewire/src/ComponentConcerns/ReceivesEvents.php',
>         'Livewire\\ComponentConcerns\\RendersLivewireComponents' => __DIR__ . '/..' . '/livewire/livewire/src/ComponentConcerns/RendersLivewireComponents.php',
>         'Livewire\\ComponentConcerns\\TracksRenderedChildren' => __DIR__ . '/..' . '/livewire/livewire/src/ComponentConcerns/TracksRenderedChildren.php',
>         'Livewire\\ComponentConcerns\\ValidatesInput' => __DIR__ . '/..' . '/livewire/livewire/src/ComponentConcerns/ValidatesInput.php',
>         'Livewire\\Connection\\ConnectionHandler' => __DIR__ . '/..' . '/livewire/livewire/src/Connection/ConnectionHandler.php',
>         'Livewire\\Controllers\\CanPretendToBeAFile' => __DIR__ . '/..' . '/livewire/livewire/src/Controllers/CanPretendToBeAFile.php',
>         'Livewire\\Controllers\\FilePreviewHandler' => __DIR__ . '/..' . '/livewire/livewire/src/Controllers/FilePreviewHandler.php',
>         'Livewire\\Controllers\\FileUploadHandler' => __DIR__ . '/..' . '/livewire/livewire/src/Controllers/FileUploadHandler.php',
>         'Livewire\\Controllers\\HttpConnectionHandler' => __DIR__ . '/..' . '/livewire/livewire/src/Controllers/HttpConnectionHandler.php',
>         'Livewire\\Controllers\\LivewireJavaScriptAssets' => __DIR__ . '/..' . '/livewire/livewire/src/Controllers/LivewireJavaScriptAssets.php',
>         'Livewire\\CreateBladeView' => __DIR__ . '/..' . '/livewire/livewire/src/CreateBladeView.php',
>         'Livewire\\DisableBrowserCache' => __DIR__ . '/..' . '/livewire/livewire/src/DisableBrowserCache.php',
>         'Livewire\\Event' => __DIR__ . '/..' . '/livewire/livewire/src/Event.php',
>         'Livewire\\Exceptions\\BypassViewHandler' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/BypassViewHandler.php',
>         'Livewire\\Exceptions\\CannotBindToModelDataWithoutValidationRuleException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/CannotBindToModelDataWithoutValidationRuleException.php',
>         'Livewire\\Exceptions\\CannotUseReservedLivewireComponentProperties' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/CannotUseReservedLivewireComponentProperties.php',
>         'Livewire\\Exceptions\\ComponentAttributeMissingOnDynamicComponentException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/ComponentAttributeMissingOnDynamicComponentException.php',
>         'Livewire\\Exceptions\\ComponentNotFoundException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/ComponentNotFoundException.php',
>         'Livewire\\Exceptions\\CorruptComponentPayloadException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/CorruptComponentPayloadException.php',
>         'Livewire\\Exceptions\\DirectlyCallingLifecycleHooksNotAllowedException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/DirectlyCallingLifecycleHooksNotAllowedException.php',
>         'Livewire\\Exceptions\\LivewirePageExpiredBecauseNewDeploymentHasSignificantEnoughChanges' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/LivewirePageExpiredBecauseNewDeploymentHasSignificantEnoughChanges.php',
>         'Livewire\\Exceptions\\MethodNotFoundException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/MethodNotFoundException.php',
>         'Livewire\\Exceptions\\MissingFileUploadsTraitException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/MissingFileUploadsTraitException.php',
>         'Livewire\\Exceptions\\MissingRulesException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/MissingRulesException.php',
>         'Livewire\\Exceptions\\NonPublicComponentMethodCall' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/NonPublicComponentMethodCall.php',
>         'Livewire\\Exceptions\\PropertyNotFoundException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/PropertyNotFoundException.php',
>         'Livewire\\Exceptions\\PublicPropertyNotFoundException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/PublicPropertyNotFoundException.php',
>         'Livewire\\Exceptions\\PublicPropertyTypeNotAllowedException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/PublicPropertyTypeNotAllowedException.php',
>         'Livewire\\Exceptions\\RootTagMissingFromViewException' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/RootTagMissingFromViewException.php',
>         'Livewire\\Exceptions\\S3DoesntSupportMultipleFileUploads' => __DIR__ . '/..' . '/livewire/livewire/src/Exceptions/S3DoesntSupportMultipleFileUploads.php',
>         'Livewire\\Features\\OptimizeRenderedDom' => __DIR__ . '/..' . '/livewire/livewire/src/Features/OptimizeRenderedDom.php',
>         'Livewire\\Features\\Placeholder' => __DIR__ . '/..' . '/livewire/livewire/src/Features/Placeholder.php',
>         'Livewire\\Features\\SupportActionReturns' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportActionReturns.php',
>         'Livewire\\Features\\SupportBootMethod' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportBootMethod.php',
>         'Livewire\\Features\\SupportBrowserHistory' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportBrowserHistory.php',
>         'Livewire\\Features\\SupportChildren' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportChildren.php',
>         'Livewire\\Features\\SupportCollections' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportCollections.php',
>         'Livewire\\Features\\SupportComponentTraits' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportComponentTraits.php',
>         'Livewire\\Features\\SupportDateTimes' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportDateTimes.php',
>         'Livewire\\Features\\SupportEvents' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportEvents.php',
>         'Livewire\\Features\\SupportFileDownloads' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportFileDownloads.php',
>         'Livewire\\Features\\SupportFileUploads' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportFileUploads.php',
>         'Livewire\\Features\\SupportLocales' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportLocales.php',
>         'Livewire\\Features\\SupportPostDeploymentInvalidation' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportPostDeploymentInvalidation.php',
>         'Livewire\\Features\\SupportRedirects' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportRedirects.php',
>         'Livewire\\Features\\SupportRootElementTracking' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportRootElementTracking.php',
>         'Livewire\\Features\\SupportStacks' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportStacks.php',
>         'Livewire\\Features\\SupportValidation' => __DIR__ . '/..' . '/livewire/livewire/src/Features/SupportValidation.php',
>         'Livewire\\FileUploadConfiguration' => __DIR__ . '/..' . '/livewire/livewire/src/FileUploadConfiguration.php',
>         'Livewire\\GenerateSignedUploadUrl' => __DIR__ . '/..' . '/livewire/livewire/src/GenerateSignedUploadUrl.php',
>         'Livewire\\HydrationMiddleware\\AddAttributesToRootTagOfHtml' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/AddAttributesToRootTagOfHtml.php',
>         'Livewire\\HydrationMiddleware\\CallHydrationHooks' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/CallHydrationHooks.php',
>         'Livewire\\HydrationMiddleware\\CallPropertyHydrationHooks' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/CallPropertyHydrationHooks.php',
>         'Livewire\\HydrationMiddleware\\HashDataPropertiesForDirtyDetection' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/HashDataPropertiesForDirtyDetection.php',
>         'Livewire\\HydrationMiddleware\\HydratePublicProperties' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/HydratePublicProperties.php',
>         'Livewire\\HydrationMiddleware\\HydrationMiddleware' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/HydrationMiddleware.php',
>         'Livewire\\HydrationMiddleware\\NormalizeComponentPropertiesForJavaScript' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/NormalizeComponentPropertiesForJavaScript.php',
>         'Livewire\\HydrationMiddleware\\NormalizeDataForJavaScript' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/NormalizeDataForJavaScript.php',
>         'Livewire\\HydrationMiddleware\\NormalizeServerMemoSansDataForJavaScript' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/NormalizeServerMemoSansDataForJavaScript.php',
>         'Livewire\\HydrationMiddleware\\PerformActionCalls' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/PerformActionCalls.php',
>         'Livewire\\HydrationMiddleware\\PerformDataBindingUpdates' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/PerformDataBindingUpdates.php',
>         'Livewire\\HydrationMiddleware\\PerformEventEmissions' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/PerformEventEmissions.php',
>         'Livewire\\HydrationMiddleware\\RenderView' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/RenderView.php',
>         'Livewire\\HydrationMiddleware\\SecureHydrationWithChecksum' => __DIR__ . '/..' . '/livewire/livewire/src/HydrationMiddleware/SecureHydrationWithChecksum.php',
>         'Livewire\\ImplicitRouteBinding' => __DIR__ . '/..' . '/livewire/livewire/src/ImplicitRouteBinding.php',
>         'Livewire\\ImplicitlyBoundMethod' => __DIR__ . '/..' . '/livewire/livewire/src/ImplicitlyBoundMethod.php',
>         'Livewire\\LifecycleManager' => __DIR__ . '/..' . '/livewire/livewire/src/LifecycleManager.php',
>         'Livewire\\Livewire' => __DIR__ . '/..' . '/livewire/livewire/src/Livewire.php',
>         'Livewire\\LivewireBladeDirectives' => __DIR__ . '/..' . '/livewire/livewire/src/LivewireBladeDirectives.php',
>         'Livewire\\LivewireComponentsFinder' => __DIR__ . '/..' . '/livewire/livewire/src/LivewireComponentsFinder.php',
>         'Livewire\\LivewireManager' => __DIR__ . '/..' . '/livewire/livewire/src/LivewireManager.php',
>         'Livewire\\LivewireServiceProvider' => __DIR__ . '/..' . '/livewire/livewire/src/LivewireServiceProvider.php',
>         'Livewire\\LivewireTagCompiler' => __DIR__ . '/..' . '/livewire/livewire/src/LivewireTagCompiler.php',
>         'Livewire\\LivewireViewCompilerEngine' => __DIR__ . '/..' . '/livewire/livewire/src/LivewireViewCompilerEngine.php',
>         'Livewire\\Macros\\DuskBrowserMacros' => __DIR__ . '/..' . '/livewire/livewire/src/Macros/DuskBrowserMacros.php',
>         'Livewire\\Macros\\ViewMacros' => __DIR__ . '/..' . '/livewire/livewire/src/Macros/ViewMacros.php',
>         'Livewire\\ObjectPrybar' => __DIR__ . '/..' . '/livewire/livewire/src/ObjectPrybar.php',
>         'Livewire\\Redirector' => __DIR__ . '/..' . '/livewire/livewire/src/Redirector.php',
>         'Livewire\\Request' => __DIR__ . '/..' . '/livewire/livewire/src/Request.php',
>         'Livewire\\Response' => __DIR__ . '/..' . '/livewire/livewire/src/Response.php',
>         'Livewire\\TemporaryUploadedFile' => __DIR__ . '/..' . '/livewire/livewire/src/TemporaryUploadedFile.php',
>         'Livewire\\Testing\\Concerns\\HasFunLittleUtilities' => __DIR__ . '/..' . '/livewire/livewire/src/Testing/Concerns/HasFunLittleUtilities.php',
>         'Livewire\\Testing\\Concerns\\MakesAssertions' => __DIR__ . '/..' . '/livewire/livewire/src/Testing/Concerns/MakesAssertions.php',
>         'Livewire\\Testing\\Concerns\\MakesCallsToComponent' => __DIR__ . '/..' . '/livewire/livewire/src/Testing/Concerns/MakesCallsToComponent.php',
>         'Livewire\\Testing\\MakesHttpRequestsWrapper' => __DIR__ . '/..' . '/livewire/livewire/src/Testing/MakesHttpRequestsWrapper.php',
>         'Livewire\\Testing\\TestableLivewire' => __DIR__ . '/..' . '/livewire/livewire/src/Testing/TestableLivewire.php',
>         'Livewire\\WireDirective' => __DIR__ . '/..' . '/livewire/livewire/src/WireDirective.php',
>         'Livewire\\Wireable' => __DIR__ . '/..' . '/livewire/livewire/src/Wireable.php',
>         'Livewire\\WithFileUploads' => __DIR__ . '/..' . '/livewire/livewire/src/WithFileUploads.php',
>         'Livewire\\WithPagination' => __DIR__ . '/..' . '/livewire/livewire/src/WithPagination.php',

Changes

<         'Tightenco\\Ziggy\\BladeRouteGenerator' => __DIR__ . '/..' . '/tightenco/ziggy/src/BladeRouteGenerator.php',
<         'Tightenco\\Ziggy\\CommandRouteGenerator' => __DIR__ . '/..' . '/tightenco/ziggy/src/CommandRouteGenerator.php',
<         'Tightenco\\Ziggy\\Ziggy' => __DIR__ . '/..' . '/tightenco/ziggy/src/Ziggy.php',
<         'Tightenco\\Ziggy\\ZiggyServiceProvider' => __DIR__ . '/..' . '/tightenco/ziggy/src/ZiggyServiceProvider.php',

Changes

<             $loader->prefixLengthsPsr4 = ComposerStaticInit1a366ea8c9013f37377c59393191f427::$prefixLengthsPsr4;
<             $loader->prefixDirsPsr4 = ComposerStaticInit1a366ea8c9013f37377c59393191f427::$prefixDirsPsr4;
<             $loader->prefixesPsr0 = ComposerStaticInit1a366ea8c9013f37377c59393191f427::$prefixesPsr0;
<             $loader->classMap = ComposerStaticInit1a366ea8c9013f37377c59393191f427::$classMap;
---
>             $loader->prefixLengthsPsr4 = ComposerStaticInitf2da6e83b085fd96649a1eced6ba9cbb::$prefixLengthsPsr4;
>             $loader->prefixDirsPsr4 = ComposerStaticInitf2da6e83b085fd96649a1eced6ba9cbb::$prefixDirsPsr4;
>             $loader->prefixesPsr0 = ComposerStaticInitf2da6e83b085fd96649a1eced6ba9cbb::$prefixesPsr0;
>             $loader->classMap = ComposerStaticInitf2da6e83b085fd96649a1eced6ba9cbb::$classMap;
## vendor/composer/installed.json

Changes

<             "name": "inertiajs/inertia-laravel",
<             "version": "v0.5.2",
<             "version_normalized": "0.5.2.0",
<             "source": {
<                 "type": "git",
<                 "url": "https://github.com/inertiajs/inertia-laravel.git",
<                 "reference": "9c8c4201435aa0c11cb832242cf4c1b01bd8ef32"
<             },
<             "dist": {
<                 "type": "zip",
<                 "url": "https://api.github.com/repos/inertiajs/inertia-laravel/zipball/9c8c4201435aa0c11cb832242cf4c1b01bd8ef32",
<                 "reference": "9c8c4201435aa0c11cb832242cf4c1b01bd8ef32",
<                 "shasum": ""
<             },
<             "require": {
<                 "ext-json": "*",
<                 "laravel/framework": "^6.0|^7.0|^8.74|^9.0",
<                 "php": "^7.2|~8.0.0|~8.1.0"
<             },
<             "require-dev": {
<                 "mockery/mockery": "^1.3.3",
<                 "orchestra/testbench": "^4.0|^5.0|^6.4|^7.0",
<                 "phpunit/phpunit": "^8.0|^9.5.8",
<                 "roave/security-advisories": "dev-master"
<             },
<             "time": "2022-01-12T16:18:26+00:00",
<             "type": "library",
<             "extra": {
<                 "laravel": {
<                     "providers": [
<                         "Inertia\\ServiceProvider"
<                     ]
<                 }
<             },
<             "installation-source": "dist",
<             "autoload": {
<                 "psr-4": {
<                     "Inertia\\": "src"
<                 },
<                 "files": [
<                     "./helpers.php"
<                 ]
<             },
<             "notification-url": "https://packagist.org/downloads/",
<             "license": [
<                 "MIT"
<             ],
<             "authors": [
<                 {
<                     "name": "Jonathan Reinink",
<                     "email": "jonathan@reinink.ca",
<                     "homepage": "https://reinink.ca"
<                 }
<             ],
<             "description": "The Laravel adapter for Inertia.js.",
<             "keywords": [
<                 "inertia",
<                 "laravel"
<             ],
<             "support": {
<                 "issues": "https://github.com/inertiajs/inertia-laravel/issues",
<                 "source": "https://github.com/inertiajs/inertia-laravel/tree/v0.5.2"
<             },
<             "funding": [
<                 {
<                     "url": "https://github.com/reinink",
<                     "type": "github"
<                 }
<             ],
<             "install-path": "../inertiajs/inertia-laravel"
<         },
<         {

Changes

>             "name": "livewire/livewire",
>             "version": "v2.9.0",
>             "version_normalized": "2.9.0.0",
>             "source": {
>                 "type": "git",
>                 "url": "https://github.com/livewire/livewire.git",
>                 "reference": "e117c78f9a4b19edb294b5b576138fd1f896925a"
>             },
>             "dist": {
>                 "type": "zip",
>                 "url": "https://api.github.com/repos/livewire/livewire/zipball/e117c78f9a4b19edb294b5b576138fd1f896925a",
>                 "reference": "e117c78f9a4b19edb294b5b576138fd1f896925a",
>                 "shasum": ""
>             },
>             "require": {
>                 "illuminate/database": "^7.0|^8.0",
>                 "illuminate/support": "^7.0|^8.0",
>                 "illuminate/validation": "^7.0|^8.0",
>                 "php": "^7.2.5|^8.0",
>                 "symfony/http-kernel": "^5.0"
>             },
>             "require-dev": {
>                 "calebporzio/sushi": "^2.1",
>                 "laravel/framework": "^7.0|^8.0",
>                 "mockery/mockery": "^1.3.1",
>                 "orchestra/testbench": "^5.0|^6.0",
>                 "orchestra/testbench-dusk": "^5.2|^6.0",
>                 "phpunit/phpunit": "^8.4|^9.0",
>                 "psy/psysh": "@stable"
>             },
>             "time": "2022-01-13T20:07:05+00:00",
>             "type": "library",
>             "extra": {
>                 "laravel": {
>                     "providers": [
>                         "Livewire\\LivewireServiceProvider"
>                     ],
>                     "aliases": {
>                         "Livewire": "Livewire\\Livewire"
>                     }
>                 }
>             },
>             "installation-source": "dist",
>             "autoload": {
>                 "files": [
>                     "src/helpers.php"
>                 ],
>                 "psr-4": {
>                     "Livewire\\": "src/"
>                 }
>             },
>             "notification-url": "https://packagist.org/downloads/",
>             "license": [
>                 "MIT"
>             ],
>             "authors": [
>                 {
>                     "name": "Caleb Porzio",
>                     "email": "calebporzio@gmail.com"
>                 }
>             ],
>             "description": "A front-end framework for Laravel.",
>             "support": {
>                 "issues": "https://github.com/livewire/livewire/issues",
>                 "source": "https://github.com/livewire/livewire/tree/v2.9.0"
>             },
>             "funding": [
>                 {
>                     "url": "https://github.com/livewire",
>                     "type": "github"
>                 }
>             ],
>             "install-path": "../livewire/livewire"
>         },
>         {

Changes

<             "name": "tightenco/ziggy",
<             "version": "v1.4.2",
<             "version_normalized": "1.4.2.0",
<             "source": {
<                 "type": "git",
<                 "url": "https://github.com/tighten/ziggy.git",
<                 "reference": "620c135281062b9f6b53a75b07f99a4339267277"
<             },
<             "dist": {
<                 "type": "zip",
<                 "url": "https://api.github.com/repos/tighten/ziggy/zipball/620c135281062b9f6b53a75b07f99a4339267277",
<                 "reference": "620c135281062b9f6b53a75b07f99a4339267277",
<                 "shasum": ""
<             },
<             "require": {
<                 "laravel/framework": ">=5.4@dev"
<             },
<             "require-dev": {
<                 "orchestra/testbench": "^6.0",
<                 "phpunit/phpunit": "^9.2"
<             },
<             "time": "2021-10-01T13:55:26+00:00",
<             "type": "library",
<             "extra": {
<                 "laravel": {
<                     "providers": [
<                         "Tightenco\\Ziggy\\ZiggyServiceProvider"
<                     ]
<                 }
<             },
<             "installation-source": "dist",
<             "autoload": {
<                 "psr-4": {
<                     "Tightenco\\Ziggy\\": "src/"
<                 }
<             },
<             "notification-url": "https://packagist.org/downloads/",
<             "license": [
<                 "MIT"
<             ],
<             "authors": [
<                 {
<                     "name": "Daniel Coulbourne",
<                     "email": "daniel@tighten.co"
<                 },
<                 {
<                     "name": "Jake Bathman",
<                     "email": "jake@tighten.co"
<                 },
<                 {
<                     "name": "Jacob Baker-Kretzmar",
<                     "email": "jacob@tighten.co"
<                 }
<             ],
<             "description": "Generates a Blade directive exporting all of your named Laravel routes. Also provides a nice route() helper function in JavaScript.",
<             "homepage": "https://github.com/tighten/ziggy",
<             "keywords": [
<                 "Ziggy",
<                 "javascript",
<                 "laravel",
<                 "routes"
<             ],
<             "support": {
<                 "issues": "https://github.com/tighten/ziggy/issues",
<                 "source": "https://github.com/tighten/ziggy/tree/v1.4.2"
<             },
<             "install-path": "../tightenco/ziggy"
<         },
<         {
## vendor/composer/installed.php

Changes

<         'inertiajs/inertia-laravel' => array(
<             'pretty_version' => 'v0.5.2',
<             'version' => '0.5.2.0',
<             'type' => 'library',
<             'install_path' => __DIR__ . '/../inertiajs/inertia-laravel',
<             'aliases' => array(),
<             'reference' => '9c8c4201435aa0c11cb832242cf4c1b01bd8ef32',
<             'dev_requirement' => false,
<         ),

Changes

>         'livewire/livewire' => array(
>             'pretty_version' => 'v2.9.0',
>             'version' => '2.9.0.0',
>             'type' => 'library',
>             'install_path' => __DIR__ . '/../livewire/livewire',
>             'aliases' => array(),
>             'reference' => 'e117c78f9a4b19edb294b5b576138fd1f896925a',
>             'dev_requirement' => false,
>         ),

Changes

<         'tightenco/ziggy' => array(
<             'pretty_version' => 'v1.4.2',
<             'version' => '1.4.2.0',
<             'type' => 'library',
<             'install_path' => __DIR__ . '/../tightenco/ziggy',
<             'aliases' => array(),
<             'reference' => '620c135281062b9f6b53a75b07f99a4339267277',
<             'dev_requirement' => false,
<         ),

## Only invendor: inertiajs

## Only inlaravel-starter-jetstream-livewire/vendor: livewire

## Only invendor: tightenco

## Only inlaravel-starter-jetstream-inertia: webpack.config.js

webpack.mix.js

Changes

< mix.js('resources/js/app.js', 'public/js').vue()
---
> mix.js('resources/js/app.js', 'public/js')

Changes

<     ])
<     .webpackConfig(require('./webpack.config'));
---
>     ]);
Google Cloud

Google Cloud Platform | Tipps und Tricks

Tipps und Tricks im Internet

https://cloud.google.com/sdk/docs/cheatsheet

https://medium.com/google-cloud/7-gcloud-tricks-you-probably-didnt-know-7f64a16869e7

https://github.com/dennyzhang/cheatsheet-gcp-A4

https://gist.github.com/pydevops/cffbd3c694d599c6ca18342d3625af97

Big Query – SQL

SELECT – exclude special fields

select * except(title, comment) from publicdata.samples.wikipedia limit 10

You could use select-except or select-replace. Maybe you have to change the sql dialect.

Authentication

JWT Token

Try https://jwt.io to decode/check the token

Laravel Toolbox

Laravel | Tipps und Tricks

Starter

Create Laravel Starter with basic functionalities

laravel new --jet --stack livewire --teams app

Views

Extend the file resources/views/navigation-menu.blade.php

<!-- Navigation Links -->
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
   <x-jet-nav-link href="{{ route('dashboard') }}"
                   :active="request()->routeIs('dashboard')">
      { __('Dashboard') }}
   </x-jet-nav-link>
</div>

<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
   <x-jet-nav-link href="{{ route('particles') }}"
                   :active="request()->routeIs('particles')">
      {{ __('Particles') }}
   </x-jet-nav-link>
</div>

Display Laravel and PHP Version

<div>
    Laravel v{{ Illuminate\Foundation\Application::VERSION }}
    (PHP v{{ PHP_VERSION }})
</div>

Create new View and Component

php artisan make:component NewComponent

Creates

app/View/Components/NewComponent.php

and

resources/views/components/new-component.blade.php

Command Line

Create new command make:view

Original source is here

php artisan make:command MakeViewCommand

Create the following file

app/Console/Commands/MakeViewCommand.php

Edit the file and overwrite code with the following

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use File;

class MakeViewCommand extends Command
{
    protected $signature = 'make:view {view}';
    protected $description = 'Create a new blade template.';
    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $view = $this->argument('view');
        $path = $this->viewPath($view);

        $this->createDir($path);

        if (File::exists($path))
        {
            $this->error("File {$path} already exists!");
            return;
        }

        File::put($path, $path);

        $this->info("File {$path} created.");
    }

    public function viewPath($view)
    {
        $view = str_replace('.', '/', $view) . '.blade.php';

        return "resources/views/{$view}";
    }

    public function createDir($path)
    {
        $dir = dirname($path);

        if (!file_exists($dir))
        {
            mkdir($dir, 0777, true);
        }
    }

}

Database

SQLite

Create an empty SQLite Database

sqlite3 database.sqlite "create table t(f int); drop table t;"

https://laravel-news.com/
https://laravel-news.com/learning-laravel-in-2021
https://laravel.com/docs/8.x

https://laravel-livewire.com/screencasts/installation

https://www.larashout.com/

Tutorial

https://www.tutsmake.com/category/laravel-tutorial/
https://www.tutsmake.com/laravel-interview-questions-answers-for-1235-year-experience/

https://learn2torials.com/category/laravel

https://kinsta.com/blog/laravel-tutorial/#6-best-free-laravel-tutorial-sites

Database

https://eloquentbyexample.com

https://laravel.com/docs/8.x/eloquent#introduction

Blade

https://www.a-coding-project.de/ratgeber/laravel/blade

Blog erstellen

https://www.flowkl.com/tutorial/web-development/simple-blog-application-in-laravel-7/

https://www.section.io/engineering-education/laravel-beginners-guide-blogpost/

https://medium.com/@dinyangetoh/how-to-build-a-blog-with-laravel-9f735d1f3116

https://medium.com/@dinyangetoh/how-to-build-a-blog-with-laravel-9f735d1f3116

Laravel | Tipps und Tricks | Bootstrap verwenden

Create and Prepare your Laravel Project

Create Laravel App

Installing a fresh Laravel project by running the following steps:

Create a new applaravel new --stack livewire --jet --teams app
In the file .env and change DB Connection to sqliteDB_CONNECTION=sqlite
Create an empty file database/database.sqlite
Start DB Migrationphp artisan migrate
Start Laravelphp artisan serve

Create Page for Bootstrap Demo

Create a file resources/views/using-bootstrap.blade.php with the following content:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel: Using Bootstrap from Local</title>
</head>

<body class="antialiased">
   <main>
      <div class="container py-4">
         <header class="pb-3 mb-4 border-bottom">
            <a href="/" 
               class="d-flex align-items-center text-dark text-decoration-none">
               <title>Bootstrap</title>
               <span class="fs-4">Bootstrap example</span>
            </a>
         </header>

         <div class="p-5 mb-4 bg-light rounded-3">
            <div class="container-fluid py-5">
               <h1 class="display-5 fw-bold">
                  Using Bootstrap in Laravel Projects
               </h1>
               <p class="col-md-8 fs-4">
                  It's very easy to add the Bootstrap Framework 
                  to your Laravel Project.
               </p>
               <button class="btn btn-primary btn-lg" type="button">
                  See how...
               </button>
            </div>
         </div>
      </div>
   </main>
</body>
</html>

Add the link /using-bootstrap to your App by adding this to route/web.php

Route::get('/', function () {
    return view('welcome');
});

Route::get('/using-bootstrap', function () {
    return view('using-bootstrap');
});

If you open http://127.0.0.1:8000/using-bootstrap in the Browser, you the demo page but with no bootstrap styling.

Adding Bootstrap to your Project

You have three possibilities to add Bootstrap into your Larval Project

Methode 1: Adding Bootstrap by a Link to CDN

Using CDN (Content delivery network) is quite easy and simple for beginners. CDN is a network of servers providing the source files for almost every library used in front-end development.

We need the references for bootstrap.min.css and bootstrap.bundle.min.js

You add Bootstrap by inserting the following code snippets in your main Laravel Page.

We will use the file resources/views/using-bootstrap.blade.php

<link            
    href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
    rel="stylesheet"
    integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
    crossorigin="anonymous"
>
<script  src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
    crossorigin="anonymous">
</script>

The final file looks like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Boostrap 5</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <div class="alert alert-success mt-5" role="alert">
            Boostrap 5 is working!
        </div>    
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
</body>
</html>

Methode 2: Adding Bootstrap Public Folder

Download Bootstrap 5 file and put the files into the folder app/public/assets/vendor/bootstrap/5.2.0

Add the following code snippets to your Laravel Page:

<link href="{{ asset('assets/vendor/bootstrap/5.2.0/css/bootstrap.min.css') }}" rel="stylesheet">
<script src="{{ asset('assets/vendor/bootstrap/5.2.0/js/bootstrap.min.js') }}"></script>

The final files look like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Boostrap 5</title>
    <link rel="stylesheet" href={{ asset('css/bootstrap.min.css') }}>
</head>
<body>
    <div class="container">
        <div class="alert alert-success mt-5" role="alert">
            Boostrap 5 is working!
        </div>    
    </div>
    <script src="{{ asset('js/bootstrap.min.js') }}"></script>
</body>
</html>

Methode 3: Adding Bootstrap 5 using Laravel Mix

In Laravel, all Frontend Modules are handles with Laravel Mix. This is an elegant wrapper around Webpack, a Package manager for installing and managing node modules.

To use Mix, you need to install NodeJS and NPM.

After this, install all required modules of your starter project

npm install

If you can see node_modules folder, this means npm is working.

Now we need to install bootstrap and the required modules

npm install bootstrap --save-dev 
npm install @popperjs/core --save-dev

You will find the new packages in package.json

    "devDependencies": {
        "@popperjs/core": "^2.11.5",
        "@tailwindcss/forms": "^0.4.0",
        "@tailwindcss/typography": "^0.5.0",
        "alpinejs": "^3.0.6",
        "axios": "^0.25",
        "bootstrap": "^5.1.3",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.1.14",
        "postcss-import": "^14.0.1",
        "tailwindcss": "^3.0.0"
    }

Next, add the following line to resources/css/app.css:

@import "bootstrap";

Add the following line to the file resources/js/bootstrap.js:

window._ = require("lodash");
import "bootstrap";

Run the following command to build the frontend files (css and js)

npm run development

You done. See the result here: http://127.0.0.1:8000/using-bootstrap

Using Bootstrap

With the Bootstrap Framework installed, now we can style our Pages. An overview of what you can do could be found in the Documentation or using the Examples.

We will work with the Examples, so download all examples to the folder resources/views/bootstrap

With the Commandline and PowerShell, you could do this: Change to the folder and download the Archive with the examples

❯ Set-Location resources\views
❯ Invoke-WebRequest https://github.com/twbs/bootstrap/releases/download/v5.2.0-beta1/bootstrap-5.2.0-beta1-examples.zip -O bootstrap.zip

Extract the archive, don’t forget the trailing dot ‘.’

❯ Expand-Archive .\bootstrap.zip .

Rename the created folder

❯ Rename-Item .\bootstrap-5.2.0-beta1-examples\ bootstrap
❯ Remove-Item bootstrap.zip

Now, we have all examples in the folder resources/views/bootstrap and we are ready to play with them:

Modify the album example to use with Laravel

Modify the /using-bootstrap (resources/views/using-bootstrap.blade.php) page

Add a sample text and a link to out Album Page

<div class="p-5 mb-4 bg-light rounded-3">
    <div class="container-fluid py-5">
    ... Keep the original content
    </div>

    <div class="container-fluid py-5">
        <p class="col-md-8 fs-4">
            Just start with an <a href="bootstrap/album">example</a>
        </p>
    </div>
</div>

Modify routes/web.php to include a link to /bootstrap/album

Add the following lines to route/web.php

Route::get('/bootstrap/album', function () {
    return view('bootstrap/album');
});

Modify the Album Page

Rename and move the file resources/views/bootstrap/album/index.html to resources/views/bootstrap/album.blade.php.

Please note: We also changed the folder of the file. All examples’ files will be placed directly under the folder resources/views/bootstrap

You can do this for all files with the following PowerShell Script:

Get-ChildItem . index.html -recurse                        | `





Addon: Script to modify all examples files

Remove-Item _web.php

Remove-Item _links.php
Add-Content _links.php "<div class='list-group w-auto'>"

function Add-Link($header, $link) {

Add-Content _links.php ('<a href="' + $link + '" class="list-group-item list-group-item-action d-flex gap-3 py-3" aria-current="true">')
Add-Content _links.php '<img src="https://github.com/twbs.png" alt="twbs" width="32" height="32" class="rounded-circle flex-shrink-0">'
Add-Content _links.php '<div class="d-flex gap-2 w-100 justify-content-between">'
Add-Content _links.php ('<div><h6 class="mb-0">' + $header + '</h6></div>')
Add-Content _links.php '<p class="mb-0 opacity-75">Another examples></p>'
Add-Content _links.php '</div>'
Add-Content _links.php '<small class="opacity-50 text-nowrap">&nbsp;</small>'
Add-Content _links.php '</a>'

}

 $LINK_OLD_JS="../assets/dist/js/bootstrap.bundle.min.js"
$LINK_OLD_CSS="../assets/dist/css/bootstrap.min.css"
 
 $LINK_NEW_JS="{{ asset('js/app.js')   }}"
$LINK_NEW_CSS="{{ asset('css/app.css') }}"


Get-ChildItem . index.html -recurse                        `
| 
| 
    (Get-Content $_\index.html)         `
    | 
    | 
    | Set-Content  $_".blade.php"

    Add-Content _web.php "Route::get('/bootstrap/$_', function () { return view('bootstrap/$_'); });"

    Write-Host "Add links to example $_"
    Add-Link $_ "bootstrap/$_"
}

Add-Content _links.php "</div>"

FAQ

Errors and Problems

Build Modules with npm run dev shows up a warning

To see more information about the warning, add the following to the file webpack.mix.js after the first mix.js( ...

mix.webpackConfig({
    stats: {
        children: true,
    },
});

Then, run npm run dev again.

Angular I18N

Angular | Working with I18N

In this post, you will learn how to get started with Angular I18n using ngx-translate, the internationalization (i18n) library for Angular. We will cover the following topics:

  • setup new angular app
  • install required dependencies
  • add bootstrap as ui framework
  • create app with demo page and translation services

This will be the final result (click to show video). Source code for this post is on GitHub.

Setup new Angular app

➜ ng new app
➜ cd app

Add required modules

➜ npm install @ngx-translate/core @ngx-translate/http-loader rxjs --save

Add Bootstrap as UI framework

We need the libraries for Bootstrap and flag icons. Download the required files into your asset/vendor/bootstrap/5.3.1 folder:

Flags Icons need a CSS file with the corresponding images for the flags, so we use the archive from GitHub.

Download and extract the archive into the folder assets/vendor/flag-icons

Current folder structure

This is our current folder structure:

Setup Application

We choose the following structure for the HTML architecture.

  • index.html contains the required css and js files.
    Also, the <app-root> component, which loads our app
  • app.component.html contains the main structure of every page.
    This includes header, navigation, place for main content and footer
  • The main content is inserted via the <router-outlet>

index.html

We will add the corresponding file in the main index.html in our project.

<!doctype html>
<html lang="en" class="h-100">

<head>
  <meta charset="utf-8">
  <title>I18N</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">

  <link rel="stylesheet" href="/assets/vendor/bootstrap.min.css">
  <link rel="stylesheet" href="/assets/vendor/flag-icons.min.css">

  <link rel="stylesheet" href="/assets/vendor/bootstrap/5.1.3/css/bootstrap.min.css">
  <link rel="stylesheet" href="/assets/vendor/flag-icons/css/flag-icons.min.css">

  <link rel="stylesheet" href="/assets/css/default.css">

</head>

<body class="d-flex flex-column h-100">
  <app-root class="h-100"></app-root>

  <script src="assets/vendor/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
</body>

</html>

app.component.html

We borrow the main structure from the bootstrap example ‘Sticky Footer with Navbar‘ with some changes in the navigation bar.

<header>
    <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-primary">
        <div class="container-fluid">
            <a class="navbar-brand" href="#">
                <img src="assets/img/logo-angular.png" height="40px" width="auto">
            </a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" 
                data-bs-target="#navbarCollapse"
                aria-controls="navbarCollapse" 
                aria-expanded="false"     
                aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarCollapse">
                <ul class="navbar-nav me-auto mb-2 mb-md-0">
                    <li class="nav-item">
                        <a class="nav-link active" aria-current="page" href="#">Home</a>
                    </li>
                </ul>

                <div class="btn-group dropstart">
                    <button class="btn btn-primary dropdown-toggle" type="button" 
                        id="dropdownFlags"
                        data-bs-toggle="dropdown" aria-expanded="false">
                        <span class="flag-icon flag-icon-{{currentlang}}"></span>
                    </button>
                    <ul class="dropdown-menu">
                        <li *ngFor="let lang of languages" [value]="lang" 
                            (click)="useLanguage(lang)">
                            <a class="dropdown-item"
                                [ngClass]="{'active': currentlang == lang}">
                                <span class="flag-icon flag-icon-{{lang}}"></span>
                                &nbsp;
                                {{lang | uppercase}}
                            </a>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </nav>
</header>
<main class="flex-shrink-0">
    <div class="container">
        <router-outlet></router-outlet>
    </div>
</main>
<footer class="footer mt-auto py-3 bg-dark">
    <div class="container">
        <span class="text-muted">(C) Ralph Göstenmeier</span>
    </div>
</footer>

app.component.ts

import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

import defaultLanguage from '../assets/i18n/de.json';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
})
export class AppComponent {
    title = 'I18N';

    languages = ['us', 'de', 'fr', 'sp'];
    currentlang = 'us';

    constructor(private translate: TranslateService) {
        this.currentlang = 'de';
        translate.setTranslation(this.currentlang, defaultLanguage);
        translate.setDefaultLang(this.currentlang);
    }

    ngOnInit(): void {}

    useLanguage(language: string): void {
        this.currentlang = language;
        this.translate.use(language.toLowerCase());
    }
}

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClient, HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

import { HomePageComponent } from './pages/home/component';
import { DemoPageComponent } from './pages/demo/component';

@NgModule({
    declarations: [AppComponent, HomePageComponent, DemoPageComponent],
    imports: [
        BrowserModule,
        AppRoutingModule,
        HttpClientModule,
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: HttpLoaderFactory,
                deps: [HttpClient],
            },
        }),
    ],
    providers: [],
    bootstrap: [AppComponent],
})
export class AppModule {}

// required for AOT compilation
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
    return new TranslateHttpLoader(http);
}

How the app works

The translation is done with the ngx-translate component.

Translation works with different JSON files (for each language a separate file), containing the required translation for each text to be displayed. Each text is addressed with a name within the JSON file.

So, the base structure of each JSON file is the following:

Translation files

assets/i18n/de.json

{
  "i18n-demo-header": "I18N Demo",
  "header": "I18N Funktionalität in Angular"
}

assets/i18n/us.json

{
  "i18n-demo-header": "I18N Example",
  "header": "I18N Functionality in Angular"
}

These translations could be used in a html file by using the translate pipe:

<h1>{{'header' | translate }}</h1>

More information and examples are here.

Changing the language is done with the help of the TranslateService

Inject your app with the TranslateService (in app.component.ts)

constructor(private translate: TranslateService) {
    translate.setDefaultLang('de');
}

Change Language

useLanguage(language: string): void {
    this.translate.use(language.toLowerCase());
}

Integrate in our UI

To easy switching the language, we have to do a few steps

Add a dropdown menu to our navigation bar.

And switching the language is done by calling useLanguage within each menu item:

<div class="btn-group dropstart">
    <button class="btn btn-primary dropdown-toggle" type="button"
        id="dropdownFlags"
        data-bs-toggle="dropdown" aria-expanded="false"><span
        class="flag-icon flag-icon-{{currentlang}}"></span>
    </button>
    <ul class="dropdown-menu">
        <li *ngFor="let lang of languages" [value]="lang"
            (click)="useLanguage(lang)">
            <a class="dropdown-item" 
                [ngClass]="{'active': currentlang == lang}">
                <span class="flag-icon flag-icon-{{lang}}"></span>
                &nbsp;
                {{lang | uppercase}}
            </a>
        </li>
    </ul>
</div>

Setup a list for all menu items:

<ul class="dropdown-menu">
<li *ngFor="let lang of languages" [value]="lang" (click)="useLanguage(lang)">

Rust | Modern Alternatives of Command-Line Tools

Continue Reading

https://github.com/TaKO8Ki/awesome-alternatives-in-rust

Tools

bat

bat is a cat clone with syntax highlighting and Git integration that works on Windows, MacOS and Linux. It provides syntax highlighting for many file extensions by default.

exa

exa is a modern replacement for ls, the default command-line program in Unix/Linux for listing directory contents. exa supports icons with the --icons flag.

just

A command runner and partial replacement for make

Just create a justfile with the desired commands and your set.

When running with PowerShell, add the following at the start of your justfile:

set windows-shell := ["pwsh.exe", "-NoLogo", "-NoProfile", "-Command"]

fd

fd is a fast and user-friendly alternative to find, the built-in command-line program in Unix/Linux for walking a file hierarchy. fd provides opinionated defaults for the most common use cases. To find a specific file by name, you write fd PATTERN instead of find -iname ‘*PATTERN*’fd is also extremely fast and it comes with a ton of options like ignoring hidden directories, files and patterns from .gitignore by default.

procs

procs is a modern replacement for ps, the default command-line program in Unix/Linux for getting information about processes. It provides convenient, human-readable (and colored) output format by default.

sd

sd is an intuitive find & replace command-line tool, it is an alternative to sed, the built-in command-line program in Unix/Linux for parsing and transforming text (). sd has simpler syntax for replacing all occurrences and it uses the convenient regex syntax that you already know from JavaScript and Python. sd is also 2x-11x faster than sed.

sed is a programmable text editor, with search and replace being a common use case. In that light, sd is more like tr, but on steroids. (thanks /u/oleid for the suggestion).

dust

dust is a more intuitive version of du, the built-in command-line program in Unix/Linux for displaying disk usage statistics. By default dust sorts the directories by size.

startship

The minimal, blazing-fast, and infinitely customizable prompt for any shell.

ripgrep

ripgrep is an extremely fast alternative to grep, the built-in command-line program in Unix/Linux for searching files by pattern. ripgrep is a line-oriented search tool that recursively searches your current directory for a regex pattern. By default, ripgrep respects .gitignore and automatically skips hidden files, directories and binary files.

rip

rip is an improved version of the rm command. It is faster, safer, and user-friendly. rip sends deleted files to a temp location so they can be recovered using rip -u. I really like the simplicity and the revert feature, as I don’t have to worry about accidentally deleting something using rm. While rip can be aliased to replace rm, the creators advise not doing that as you might get used to it and do rm on other systems where you cannot revert the delete.

toeki

tokei is a program that displays statistics about your code. It shows the number of files, total lines within those files and code, comments, and blanks grouped by language.

hyperfine

hyperfine is a command-line benchmarking tool. Among many features, it provides statistical analysis across multiple runs, support for arbitrary shell commands, constant feedback about the benchmark progress and current estimates and more.

ytop

ytop is an alternative to top, the built-in command-line program in Unix/Linux for displaying information about processes.

tealdeer

tealdeer is a very fast implementation of tldr, a command-line program for displaying simplified, example based and community-driven man pages.

bandwhich

bandwhich is a CLI utility for displaying current network utilization by process, connection and remote IP or hostname.

grex

grex is a command-line tool and library for generating regular expressions from user-provided test cases.

rmesg

rmesg is a dmesg implementation in Rust (and available as a library for Rust programs to consume kernel message logs.)

zoxide

zoxide is a blazing fast autojumper, intended to completely replace the cd command. It allows you to change directories without typing out the entire path name.

delta

delta is a viewer for git and diff output. It allows you to make extensive changes to the layout and styling of diffs, as well as allowing you to stay arbitrarily close to the default git/diff output.

tp-note

Tp-Note is a template tool that enhances the clipboard with a save and edit as a note file function. After creating a new note file, Tp-Note launches the user’s favorite file editor (for editing) and web browser (for viewing).

nushell

nushell is a new type of shell, written in Rust. Its goal is to create a modern shell alternative that’s still based on the Unix philosophy but adapted to the current era. It supports piping and filtering in a way similar to awk and sed with a column view so that you can combine operations like in SQL. (thanks /u/matu3ba for the suggestion).

xcp

xcp is a partial clone of the cp command. It is faster and more user-friendly with progress bars, parallel copying, .gitignore support, and so on. I like its simplicity and developer experience, especially the progress bars. I have aliased cp to xcp so I can use it everywhere.

zoxide

zoxide is a smarter cd replacement. It remembers the directories you visit, and you can jump to them without providing a full path. You can provide partial paths or even a word from the path. When there are similar paths, zoxide offers an interactive selection using fzf. It is super fast and works with all major shells. I like how it works, and I have aliased cd to z so I can use it everywhere.

atuin

Magical shell history

bottom

Yet another cross-platform graphical process/system monitor.

broot

A new way to see and navigate directory trees.

choose

A human-friendly and fast alternative to cut and (sometimes) awk.

counts

A tool for ad hoc profiling.

delta

A syntax-highlighting pager for git, diff, and grep output.

difftastic

A syntax-aware diff.

dog

A command-line DNS client.

dua

View disk space usage and delete unwanted data, fast.

eza

A modern version of ls.

fclones

Efficient duplicate file finder.

felix

TUI file manager with vim-like key mapping.

ffsend

Easily and securely share files from the command line (Firefox Send client).

frum

A modern Ruby version manager written in Rust.

fselect

Find files with SQL-like queries.

git-cliff

Highly customizable changelog generator.

gptman

A GPT manager that allows you to copy partitions from one disk to another and more.

himalaya

Command-line interface for email management.

htmlq

Like jq, but for HTML. Uses CSS selectors to extract bits of content from HTML files.

inlyne

GPU powered terminal markdown viewer.

jless

Command-line JSON viewer for exploring and searching JSON.

jql

A JSON query language CLI tool.

legdur

Compute hashes of large sets of files and compare with snapshots.

lemmeknow

Identify or analyze mysterious text and hard-coded strings.

lfs

A Linux utility to get information on filesystems; like df but better.

lsd

Next generation ls command.

macchina

Fast, minimal, and customizable system information frontend.

mdBook

Create books from markdown files (like GitBook).

mdcat

Fancy cat for Markdown.

miniserve

Serve files and directories over HTTP (replacement for Python’s SimpleHTTPServer).

monolith

Save complete web pages as a single HTML file.

ouch

Painless compression and decompression for your terminal.

pastel

Generate, analyze, convert, and manipulate colors on the command line.

pipr

A tool to interactively write shell pipelines.

qsv

CSVs sliced, diced & analyzed (fork of xsv).

rargs

xargs plus awk with pattern matching.

ripsecrets

Find secret keys in your code before committing them to git.

rnr

Command-line tool to batch rename files and directories.

skim

Command-line fuzzy finder.

teehee

Modal terminal hex editor.

tin-summer

Find build artifacts that are taking up disk space.

topgrade

Upgrade all of your tools.

watchexec

Execute commands in response to file modifications.

xh

Friendly and fast tool for sending HTTP requests.

xsv

Fast CSV command line toolkit (last updated in 2018).


Django | How To – Templates konfigurieren

Allgemein / Vorbereitung

Um in einem Django-Projekt mit mehreren Anwendungen die HTML-Templates zu konfigurieren sind mehrere Schritte notwendig.

Ausgangsbasis ist die nachfolgende Verzeichnisstruktur (ein Projekt mit 2 Anwendungen).

Basisprojekt einrichten

➜ pipenv --python 3.10
➜ pipenv shell
➜ pip install django
➜ djangop-admin startproject project
➜ cd project
➜ mkdir apps
➜ mkdir apps\core
➜ django-admin startapp core apps\core
➜ mkdir apps\frontend
➜ django-admin startapp frontend apps\frontend

Dies ergibt die folgende Verzeichnisstruktur:

Hinweis: der Befehl startproject erstellt einen Ordner project, indem er einen weiteren Ordner project erstellt. Der erste Ordner dient dazu, sowohl das Django-Projekt, als auch die erstellten Anwendungen an einer gemeinsame Stelle zu speichern.

Der zweite Ordner project ist das Django-Projekt, in dem sich alle für das Projekt notwendigen Dateien befinden.

Wird in den nachfolgenden Beschreibungen vom dem Ordner project gesprochen, so ist immer der zweite gemeint (project/project)

➜ python manage.py migrate
➜ python manage.py createsuperuser --email admin@localhost --username admin
Password:
Password (again):
Superuser created successfully.

Anwendungen hinzufügen

Im nächsten Schritt werden die beiden erstellten Anwendungen (Core und Frontend) dem Django-Projekt hinzugefügt. Da sie in einem Unterverzeichnis (apps) liegen, muss ihre Konfiguration angepasst werden.

In dere Datei apps.py der jeweiligen Anwendung (apps/core/apps.py und apps/frontend/apps.py) wirr der Name angepasst:

Hinweis: Ohne diese Anpassung würde beim Start des Servers eine Fehlermeldung angezeigt

django.core.exceptions.ImproperlyConfigured: Cannot import 'frontend'. Check that 'apps.frontend.apps.FrontendConfig.name' is correct.

Im Anschluss daran werden die beiden Anwendungen dem Projekt hinzugefügt. Dies erfolgt in der Datei project/settings.py:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'apps.core',
    'apps.frontend'
]

Einfache Views erstellen

Ein Template ist die Basis eines Views.

Daher richten wir für jede Anwendung einen einfachen View ein: in apps/core/views.py und apps/frontend/views.py:

from django.shortcuts import render
from django.views import generic

class IndexView(generic.TemplateView):
    """
    IndexView:
    """
    module = 'indexView'
    template_name = 'core/index.html'

URLs für die Anwendungen hinzufügen

Im letzten Vorbereitungsschritt konfigurieren wir die URLs für unsere Anwendungen bzw die beiden eingerichteten Views:

from django.contrib import admin
from django.urls import path

import apps.core.views as core
import apps.frontend.views as frontend

urlpatterns = [
    path('admin/', admin.site.urls),
    path('frontend/', frontend.IndexView.as_view(), name='index'),
    path('core', core.IndexView.as_view(), name='index'),

]

Als Ergebnis sollten wir bei beiden URLs einen Fehler sehen.

Dies was zu erwarten, da wir die notwendigen Templates ja erst jetzt einrichten werden:

Template hinzufügen

Erstellen eines Templates für die Anwendung core: apps/core/templates/core/index.html

Der Verzeichnispfad des Templates setzt sich auch mehreren Teilen zusammen

apps/coreDas Startverzeichnis der Anwendung
templatesDer Default-Name des Verzeichnisses, in dem Django nach Templates sucht
coreDer Namespace als Unterscheidung, wenn es Templates mit gleichem Namen gibt
index.htmlDer Name des Templates

Erstellen Sie die Daten apps/core/templates/core/index.html und öffnen Sie dann den Browser:

http://localhost:8000/core

Zum Vergleich öffen wir die URL für unsere zweite Anwendung: frontend

http://localhost:8000/frontend

Im unteren Teil der Fehlermeldung findet sich aber eine hilfreiche Information:

Als erstes wir uns mitgeteilt, das ein gewünschtes Template in der nachfolgenden Reihenfolge gesucht wird. Es werden als (wir oben bereits erwähnt) mehrere Verzeichnisse durchsucht, um ein passendes Template zu finden.

Template-loader postmortem
Django tried loading these templates, in this order:

Using engine django:

Als erstes werden Verzeichnisse der Django-Installation durchsucht. Hierunter liegen z. B. die Templates für die Administration oder die Anmeldung.

django.template.loaders.app_directories.Loader: 
...\lib\site-packages\django\contrib\admin\templates\frontend\index.html (Source does not exist)

django.template.loaders.app_directories.Loader: 
...\lib\site-packages\django\contrib\auth\templates\frontend\index.html (Source does not exist)

Im Anschluss werden dann die Verzeichnisse unserer Anwendungen durchsucht.

django.template.loaders.app_directories.Loader: ...\project\apps\core\templates\frontend\index.html (Source does not exist)

django.template.loaders.app_directories.Loader: ...\project\apps\frontend\templates\frontend\index.html (Source does not exist)

Um nun ein gewünschtes Template zu finden, werden zwei Informationen benötigt:

  • der Name des Template
  • das Verzeichnis

Name des Templates

Der Name des Templates wird im View angegeben: apps/core/views.py:

class IndexView(generic.TemplateView):
    module = 'indexView'
    template_name = 'core/index.html'

Verzeichnis

Das Verzeichnis selbst wird über die Suchreihenfolge der zu verwendenden Template-Verzeichnisse ermittelt. Das erste Verzeichnis, dass das gewünschte Template beinhaltet, wird verwendet.

Ermitteln des Verzeichnisses

Im Falle unserer Anwendung frontend werden die nachfolgenden Verzeichnisse durchsucht, ob sie das Template core/index.html beinhalten:

UmgebungVerzeichnisTemplate gefunden
DJANGOlib\site-packages\django\contrib\admin\templates
DJANGOlib\site-packages\django\contrib\auth\templates
PROJEKTproject\apps\core\templatescore/index.html
PROJEKTproject\apps\frontend\templates

Template hinzufügen

Erstellen eines Templates für die Anwendung frontend: apps/frontend/templates/frontend/index.html

Weiteres Beispiel: Suchen des passenden Templates

Richten sie einen Neuen View in der Anwendung frontend ein: apps/frontend/views.py

class BaseView(generic.TemplateView):
    module = 'baseView'
    template_name = 'base.html' 

Erstellen Sie eine URL für diesen View in project/urls.py

urlpatterns = [
    path('admin/',      admin.site.urls),
    path('core',        core.IndexView.as_view(),      name='index'),
    path('frontend/',   frontend.IndexView.as_view(),  name='index'),
    path('base/',       frontend.BaseView.as_view(),   name='base'),
]

Öffnen Sie den Browser um diese URL anzuzeigen;

http://localhost:8000/base

Wie zu erwarten war, wird das Template nicht gefunden:

In keinem der bekannten Verzeichnisse gibt es ein Template base.html.

Gemeinsame Templates für alle Anwendungen

Um Templates einzurichten, die von mehreren Anwendungen verwendet werden, empfiehlt es sich, ein Verzeichnis templates auf der gleichen Ebene, wie die Anwendungen, einzurichten

In der Datei project/settings.py wird dieses Verzeichnis dem Django-Projekt hinzugefügt.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        ....

Öffnen Sie den Browser um diese URL anzuzeigen;

http://localhost:8000/base

Das zusätzliche Verzeichnis wird nun auch durchsucht:

Template-loader postmortem
Django tried loading these templates, in this order:

Using engine django:
django.template.loaders.filesystem.Loader: ...\project\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\.venv\lib\site-packages\django\contrib\admin\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\.venv\lib\site-packages\django\contrib\auth\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\project\apps\core\templates\base.html (Source does not exist)
django.template.loaders.app_directories.Loader: ...\project\apps\frontend\templates\base.html (Source does not exist)

Erstellen Sie nun in diesem Verzeichnis (templates) das Template base.html

Öffnen Sie den Browser um diese URL anzuzeigen;

http://localhost:8000/base