first commit
This commit is contained in:
24
.env
Normal file
24
.env
Normal file
@@ -0,0 +1,24 @@
|
||||
# In all environments, the following files are loaded if they exist,
|
||||
# the latter taking precedence over the former:
|
||||
#
|
||||
# * .env contains default values for the environment variables needed by the app
|
||||
# * .env.local uncommitted file with local overrides
|
||||
# * .env.$APP_ENV committed environment-specific defaults
|
||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
||||
#
|
||||
# Real environment variables win over .env files.
|
||||
#
|
||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||
# https://symfony.com/doc/current/configuration/secrets.html
|
||||
#
|
||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=dev
|
||||
APP_SECRET=b0d53a61c5f01a98f6a4cabc3398e307
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> symfony/mailer ###
|
||||
# MAILER_DSN=null://null
|
||||
###< symfony/mailer ###
|
||||
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
###> symfony/framework-bundle ###
|
||||
/.env.local
|
||||
/.env.local.php
|
||||
/.env.*.local
|
||||
/config/secrets/prod/prod.decrypt.private.php
|
||||
/public/bundles/
|
||||
/var/
|
||||
/vendor/
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> pentatrion/vite-bundle ###
|
||||
/node_modules/
|
||||
/public/build/
|
||||
###< pentatrion/vite-bundle ###
|
||||
|
||||
3
assets/app.css
Normal file
3
assets/app.css
Normal file
@@ -0,0 +1,3 @@
|
||||
body {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
3
assets/app.js
Normal file
3
assets/app.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import "./app.css";
|
||||
|
||||
console.log("Happy coding !!");
|
||||
9
assets/js/main.js
Executable file
9
assets/js/main.js
Executable file
@@ -0,0 +1,9 @@
|
||||
import "../scss/style.scss";
|
||||
|
||||
import "./simple-lightbox.js";
|
||||
|
||||
(function () {
|
||||
var $gallery = new SimpleLightbox(".gallery a", {});
|
||||
})();
|
||||
|
||||
// import "./pagination.js"
|
||||
3093
assets/js/simple-lightbox.js
Normal file
3093
assets/js/simple-lightbox.js
Normal file
File diff suppressed because it is too large
Load Diff
8
assets/scss/album/basic.scss
Executable file
8
assets/scss/album/basic.scss
Executable file
@@ -0,0 +1,8 @@
|
||||
@import "./details.scss";
|
||||
@import "./child.scss";
|
||||
|
||||
.my_album {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
grid-gap: 50px;
|
||||
}
|
||||
20
assets/scss/album/child.scss
Normal file
20
assets/scss/album/child.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
$ImageWidth: 260px;
|
||||
$ImageHeight: 180px;
|
||||
|
||||
$BDRadius: 15px;
|
||||
|
||||
|
||||
|
||||
.my_album_child {
|
||||
|
||||
|
||||
img {
|
||||
display: block;
|
||||
border-radius: $BDRadius;
|
||||
width: $ImageWidth;
|
||||
height: $ImageHeight;
|
||||
object-fit: cover;
|
||||
box-shadow: $BorderShadow;
|
||||
}
|
||||
|
||||
}
|
||||
0
assets/scss/album/details.scss
Normal file
0
assets/scss/album/details.scss
Normal file
12
assets/scss/breadcrumbs.scss
Executable file
12
assets/scss/breadcrumbs.scss
Executable file
@@ -0,0 +1,12 @@
|
||||
.my_breadcrumbs {
|
||||
padding-top: 3rem;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
margin: 0 auto;
|
||||
max-width: 1200px;
|
||||
|
||||
.my_border {
|
||||
box-shadow: $BorderShadow;
|
||||
border-radius: $BDRadius;
|
||||
}
|
||||
}
|
||||
10
assets/scss/container.scss
Executable file
10
assets/scss/container.scss
Executable file
@@ -0,0 +1,10 @@
|
||||
@import "./gallery/basic.scss";
|
||||
@import "./album/basic.scss";
|
||||
|
||||
.my_container {
|
||||
padding-top: 2rem;
|
||||
padding-bottom: 3rem;
|
||||
|
||||
margin: 0 auto;
|
||||
max-width: 1200px;
|
||||
}
|
||||
7
assets/scss/gallery/basic.scss
Executable file
7
assets/scss/gallery/basic.scss
Executable file
@@ -0,0 +1,7 @@
|
||||
@import "./card.scss";
|
||||
|
||||
.my_gallery {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
grid-gap: 50px;
|
||||
}
|
||||
21
assets/scss/gallery/card.scss
Executable file
21
assets/scss/gallery/card.scss
Executable file
@@ -0,0 +1,21 @@
|
||||
@import "./child.scss";
|
||||
@import "./simple-lightbox.scss";
|
||||
|
||||
.my_card {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
height: 0;
|
||||
padding-bottom: 200px;
|
||||
--offset-multiplier: 4px;
|
||||
transition: transform 0.6s ease;
|
||||
--translate: 0;
|
||||
transform: translate(var(--translate), var(--translate));
|
||||
filter: brightness(70%);
|
||||
}
|
||||
|
||||
.my_card:hover {
|
||||
--offset-multiplier: 6px;
|
||||
--translate: calc(-1px * (var(--cards) - 1));
|
||||
transition: transform 0.3s ease;
|
||||
filter: none;
|
||||
}
|
||||
71
assets/scss/gallery/child.scss
Executable file
71
assets/scss/gallery/child.scss
Executable file
@@ -0,0 +1,71 @@
|
||||
$ImageWidth: 260px;
|
||||
$ImageHeight: 180px;
|
||||
|
||||
$BDRadius: 15px;
|
||||
$BorderShadow: 0px 4px 8px rgba(0, 0, 0, 0.1),
|
||||
0px -4px 8px rgba(255, 255, 255, 0.8);
|
||||
|
||||
.my_gallery_child {
|
||||
position: absolute;
|
||||
width: $ImageWidth;
|
||||
height: $ImageHeight;
|
||||
color: white;
|
||||
box-sizing: border-box;
|
||||
background-size: cover;
|
||||
border-radius: $BDRadius;
|
||||
transition: inherit;
|
||||
--translate: calc(var(--offset) * var(--offset-multiplier));
|
||||
transform: translate(var(--translate), var(--translate));
|
||||
|
||||
.child-title {
|
||||
text-decoration: none;
|
||||
filter: none;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
border-radius: $BDRadius;
|
||||
width: $ImageWidth;
|
||||
height: $ImageHeight;
|
||||
object-fit: cover;
|
||||
box-shadow: $BorderShadow;
|
||||
}
|
||||
}
|
||||
|
||||
.my_gallery_child:nth-child(1) {
|
||||
display: flex;
|
||||
padding-top: 0.5rem;
|
||||
justify-items: left;
|
||||
font-size: 30px;
|
||||
|
||||
div:hover {
|
||||
filter: none;
|
||||
}
|
||||
|
||||
--offset: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
.my_gallery_child:nth-child(2) {
|
||||
box-shadow: $BorderShadow;
|
||||
|
||||
--offset: 1;
|
||||
z-index: 3;
|
||||
}
|
||||
.my_gallery_child:nth-child(3) {
|
||||
box-shadow: $BorderShadow;
|
||||
|
||||
--offset: 2;
|
||||
z-index: 2;
|
||||
}
|
||||
.my_gallery_child:nth-child(4) {
|
||||
box-shadow: $BorderShadow;
|
||||
|
||||
--offset: 3;
|
||||
z-index: 1;
|
||||
}
|
||||
.my_gallery_child:nth-child(5) {
|
||||
box-shadow: $BorderShadow;
|
||||
|
||||
--offset: 4;
|
||||
z-index: 0;
|
||||
}
|
||||
326
assets/scss/gallery/simple-lightbox.scss
Normal file
326
assets/scss/gallery/simple-lightbox.scss
Normal file
@@ -0,0 +1,326 @@
|
||||
// You can customize Simplelightbox with the following variables:
|
||||
|
||||
$sl-font-family: Arial, Baskerville, monospace !default;
|
||||
$sl-overlay-background: #fff !default;
|
||||
$sl-navigation-color: #000 !default;
|
||||
$sl-caption-color: #fff !default;
|
||||
$sl-caption-background: rgba(0, 0, 0, 0.8) !default;
|
||||
|
||||
$sl-counter-fontsize: 1rem !default;
|
||||
$sl-caption-fontsize: 1rem !default;
|
||||
$sl-close-fontsize: 3rem !default;
|
||||
|
||||
$sl-breakpoint-medium: 35.5em !default; // 568px, when 1em == 16px
|
||||
$sl-breakpoint-large: 50em !default; // 800px, when 1em == 16px
|
||||
|
||||
$sl-arrow-fontsize-small: 2rem !default;
|
||||
$sl-arrow-fontsize-medium: 3rem !default;
|
||||
$sl-arrow-fontsize-large: 3rem !default;
|
||||
$sl-img-border-small: 0 none !default;
|
||||
$sl-img-border-medium: 0 none !default;
|
||||
$sl-img-border-large: 0 none !default;
|
||||
$sl-iframe-border-small: 0 none !default;
|
||||
$sl-iframe-border-medium: 0 none !default;
|
||||
$sl-iframe-border-large: 0 none !default;
|
||||
|
||||
$add-vendor-prefixes: true !default;
|
||||
|
||||
body.hidden-scroll {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.sl-overlay {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
background: $sl-overlay-background;
|
||||
display: none;
|
||||
z-index: 1035;
|
||||
}
|
||||
|
||||
.sl-wrapper {
|
||||
z-index: 1040;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: fixed;
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
button {
|
||||
border: 0 none;
|
||||
background: transparent;
|
||||
font-size: 28px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.sl-close {
|
||||
display: none;
|
||||
position: fixed;
|
||||
right: 30px;
|
||||
top: 30px;
|
||||
z-index: 10060;
|
||||
margin-top: -14px;
|
||||
margin-right: -14px;
|
||||
height: 44px;
|
||||
width: 44px;
|
||||
line-height: 44px;
|
||||
font-family: $sl-font-family;
|
||||
color: $sl-navigation-color;
|
||||
font-size: $sl-close-fontsize;
|
||||
}
|
||||
|
||||
.sl-counter {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 30px;
|
||||
left: 30px;
|
||||
z-index: 1060;
|
||||
color: $sl-navigation-color;
|
||||
font-size: $sl-counter-fontsize;
|
||||
}
|
||||
|
||||
.sl-navigation {
|
||||
width: 100%;
|
||||
display: none;
|
||||
button {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
margin-top: -22px;
|
||||
height: 44px;
|
||||
width: 22px;
|
||||
line-height: 44px;
|
||||
text-align: center;
|
||||
display: block;
|
||||
z-index: 10060;
|
||||
font-family: $sl-font-family;
|
||||
color: $sl-navigation-color;
|
||||
&.sl-next {
|
||||
right: 5px;
|
||||
font-size: $sl-arrow-fontsize-small;
|
||||
}
|
||||
|
||||
&.sl-prev {
|
||||
left: 5px;
|
||||
font-size: $sl-arrow-fontsize-small;
|
||||
}
|
||||
|
||||
@media (min-width: $sl-breakpoint-medium) {
|
||||
width: 44px;
|
||||
|
||||
&.sl-next {
|
||||
right: 10px;
|
||||
font-size: $sl-arrow-fontsize-medium;
|
||||
}
|
||||
|
||||
&.sl-prev {
|
||||
left: 10px;
|
||||
font-size: $sl-arrow-fontsize-medium;
|
||||
}
|
||||
}
|
||||
@media (min-width: $sl-breakpoint-large) {
|
||||
width: 44px;
|
||||
|
||||
&.sl-next {
|
||||
right: 20px;
|
||||
font-size: $sl-arrow-fontsize-large;
|
||||
}
|
||||
|
||||
&.sl-prev {
|
||||
left: 20px;
|
||||
font-size: $sl-arrow-fontsize-large;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.sl-dir-rtl {
|
||||
.sl-navigation {
|
||||
direction: ltr;
|
||||
}
|
||||
}
|
||||
|
||||
.sl-image {
|
||||
position: fixed;
|
||||
@if $add-vendor-prefixes {
|
||||
-ms-touch-action: none;
|
||||
}
|
||||
touch-action: none;
|
||||
z-index: 10000;
|
||||
img {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
border: $sl-img-border-small;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1),
|
||||
0px -4px 8px rgba(255, 255, 255, 0.8);
|
||||
@media (min-width: $sl-breakpoint-medium) {
|
||||
border: $sl-img-border-medium;
|
||||
}
|
||||
@media (min-width: $sl-breakpoint-large) {
|
||||
border: $sl-img-border-large;
|
||||
}
|
||||
}
|
||||
iframe {
|
||||
background: #000;
|
||||
border: $sl-iframe-border-small;
|
||||
@media (min-width: $sl-breakpoint-medium) {
|
||||
border: $sl-iframe-border-medium;
|
||||
}
|
||||
@media (min-width: $sl-breakpoint-large) {
|
||||
border: $sl-iframe-border-large;
|
||||
}
|
||||
}
|
||||
.sl-caption {
|
||||
display: none;
|
||||
padding: 10px;
|
||||
color: $sl-caption-color;
|
||||
background: $sl-caption-background;
|
||||
font-size: $sl-caption-fontsize;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
&.pos-top {
|
||||
bottom: auto;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&.pos-outside {
|
||||
bottom: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.sl-download {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
right: 5px;
|
||||
color: $sl-navigation-color;
|
||||
z-index: 1060;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sl-spinner {
|
||||
display: none;
|
||||
border: 5px solid #333;
|
||||
border-radius: 40px;
|
||||
height: 40px;
|
||||
left: 50%;
|
||||
margin: -20px 0 0 -20px;
|
||||
opacity: 0;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
width: 40px;
|
||||
z-index: 1007;
|
||||
@if $add-vendor-prefixes {
|
||||
-webkit-animation: pulsate 1s ease-out infinite;
|
||||
-moz-animation: pulsate 1s ease-out infinite;
|
||||
-ms-animation: pulsate 1s ease-out infinite;
|
||||
-o-animation: pulsate 1s ease-out infinite;
|
||||
}
|
||||
animation: pulsate 1s ease-out infinite;
|
||||
}
|
||||
|
||||
.sl-scrollbar-measure {
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.sl-transition {
|
||||
@if $add-vendor-prefixes {
|
||||
transition: -moz-transform ease 200ms;
|
||||
transition: -ms-transform ease 200ms;
|
||||
transition: -o-transform ease 200ms;
|
||||
transition: -webkit-transform ease 200ms;
|
||||
}
|
||||
transition: transform ease 200ms;
|
||||
}
|
||||
|
||||
@-webkit-keyframes pulsate {
|
||||
0% {
|
||||
transform: scale(0.1);
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.2);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulsate {
|
||||
0% {
|
||||
transform: scale(0.1);
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.2);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@if $add-vendor-prefixes {
|
||||
@-moz-keyframes pulsate {
|
||||
0% {
|
||||
transform: scale(0.1);
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.2);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-o-keyframes pulsate {
|
||||
0% {
|
||||
transform: scale(0.1);
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.2);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-ms-keyframes pulsate {
|
||||
0% {
|
||||
transform: scale(0.1);
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.2);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
assets/scss/navigation.scss
Executable file
12
assets/scss/navigation.scss
Executable file
@@ -0,0 +1,12 @@
|
||||
.my_navigation {
|
||||
padding-top: 3rem;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
margin: 0 auto;
|
||||
max-width: 1200px;
|
||||
|
||||
.my_border {
|
||||
box-shadow: $BorderShadow;
|
||||
border-radius: $BDRadius;
|
||||
}
|
||||
}
|
||||
96
assets/scss/pagination.scss
Normal file
96
assets/scss/pagination.scss
Normal file
@@ -0,0 +1,96 @@
|
||||
@media (min-width: 580px) {
|
||||
.images {
|
||||
grid-template-columns: 25% 25% 25% 25%;
|
||||
}
|
||||
}
|
||||
img {
|
||||
height: auto;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.template {
|
||||
transition: all 0.8s cubic-bezier(0.455, 0.03, 0.515, 0.955);
|
||||
opacity: 0;
|
||||
position: relative;
|
||||
background: #707070;
|
||||
}
|
||||
|
||||
.template p {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
color: #fff;
|
||||
text-transform: uppercase;
|
||||
font-size: 13px;
|
||||
letter-spacing: 1px;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.5));
|
||||
padding: 25px 10px 10px 10px;
|
||||
}
|
||||
|
||||
.template.animate {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#gallery-pagination {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
#btnNext,
|
||||
#btnPrevious {
|
||||
background: transparent;
|
||||
color: #609ea5;
|
||||
padding: 8px 28px;
|
||||
border: 0;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#gallery-pagination #page {
|
||||
margin-left: 15px;
|
||||
margin-right: 15px;
|
||||
color: #707070;
|
||||
font-style: italic;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute !important;
|
||||
overflow: hidden;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#gallery-dots {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.gallery-dot {
|
||||
background: #609ea5;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
width: 50px;
|
||||
height: 8px;
|
||||
margin: 5px;
|
||||
opacity: 0.4;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gallery-dot.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#gallery-pagination {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3fr 1fr;
|
||||
align-items: start;
|
||||
}
|
||||
20
assets/scss/style.scss
Executable file
20
assets/scss/style.scss
Executable file
@@ -0,0 +1,20 @@
|
||||
@import "tailwindcss/base";
|
||||
@import "tailwindcss/components";
|
||||
@import "tailwindcss/utilities";
|
||||
|
||||
$BDRadius: 15px;
|
||||
$BorderShadow: 0px 4px 8px rgba(0, 0, 0, 0.1),
|
||||
0px -4px 8px rgba(255, 255, 255, 0.8);
|
||||
|
||||
@import "./navigation.scss";
|
||||
@import "./breadcrumbs.scss";
|
||||
@import "./container.scss";
|
||||
@import "gallery/basic.scss";
|
||||
@import "album/basic.scss";
|
||||
@import "./pagination.scss";
|
||||
|
||||
body {
|
||||
margin-right: 40px;
|
||||
margin-left: 40px;
|
||||
align-items: center;
|
||||
}
|
||||
17
bin/console
Executable file
17
bin/console
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
|
||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
||||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
|
||||
}
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
|
||||
return new Application($kernel);
|
||||
};
|
||||
75
composer.json
Normal file
75
composer.json
Normal file
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"type": "project",
|
||||
"license": "proprietary",
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"pentatrion/vite-bundle": "^2.3",
|
||||
"symfony/asset": "6.1.*",
|
||||
"symfony/console": "6.1.*",
|
||||
"symfony/dependency-injection": "6.1.*",
|
||||
"symfony/dotenv": "6.1.*",
|
||||
"symfony/finder": "6.1.*",
|
||||
"symfony/flex": "^2",
|
||||
"symfony/framework-bundle": "6.1.*",
|
||||
"symfony/mailer": "6.1.*",
|
||||
"symfony/maker-bundle": "^1.47",
|
||||
"symfony/runtime": "6.1.*",
|
||||
"symfony/twig-bundle": "6.1.*",
|
||||
"symfony/yaml": "6.1.*",
|
||||
"twig/extra-bundle": "^3.4",
|
||||
"twig/twig": "^2.12|^3.0"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"symfony/flex": true,
|
||||
"symfony/runtime": true
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": {
|
||||
"*": "dist"
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"App\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"replace": {
|
||||
"symfony/polyfill-ctype": "*",
|
||||
"symfony/polyfill-iconv": "*",
|
||||
"symfony/polyfill-php72": "*",
|
||||
"symfony/polyfill-php73": "*",
|
||||
"symfony/polyfill-php74": "*",
|
||||
"symfony/polyfill-php80": "*",
|
||||
"symfony/polyfill-php81": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
},
|
||||
"post-install-cmd": [
|
||||
"@auto-scripts"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@auto-scripts"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "6.1.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
3741
composer.lock
generated
Normal file
3741
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
9
config/bundles.php
Normal file
9
config/bundles.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
|
||||
Pentatrion\ViteBundle\PentatrionViteBundle::class => ['all' => true],
|
||||
];
|
||||
19
config/packages/cache.yaml
Normal file
19
config/packages/cache.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
framework:
|
||||
cache:
|
||||
# Unique name of your app: used to compute stable namespaces for cache keys.
|
||||
#prefix_seed: your_vendor_name/app_name
|
||||
|
||||
# The "app" cache stores to the filesystem by default.
|
||||
# The data in this cache should persist between deploys.
|
||||
# Other options include:
|
||||
|
||||
# Redis
|
||||
#app: cache.adapter.redis
|
||||
#default_redis_provider: redis://localhost
|
||||
|
||||
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
|
||||
#app: cache.adapter.apcu
|
||||
|
||||
# Namespaced pools use the above "app" backend by default
|
||||
#pools:
|
||||
#my.dedicated.cache: null
|
||||
24
config/packages/framework.yaml
Normal file
24
config/packages/framework.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
#csrf_protection: true
|
||||
http_method_override: false
|
||||
|
||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
||||
# Remove or comment this section to explicitly disable session support.
|
||||
session:
|
||||
handler_id: null
|
||||
cookie_secure: auto
|
||||
cookie_samesite: lax
|
||||
storage_factory_id: session.storage.factory.native
|
||||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
php_errors:
|
||||
log: true
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_factory_id: session.storage.factory.mock_file
|
||||
3
config/packages/mailer.yaml
Normal file
3
config/packages/mailer.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
framework:
|
||||
mailer:
|
||||
dsn: '%env(MAILER_DSN)%'
|
||||
14
config/packages/pentatrion_vite.yaml
Normal file
14
config/packages/pentatrion_vite.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
# config/packages/pentatrion_vite.yaml
|
||||
pentatrion_vite:
|
||||
# Base public path when served in development or production
|
||||
base: /build/
|
||||
# path to the web root relative to the Symfony project root directory
|
||||
public_dir: /public
|
||||
|
||||
script_attributes:
|
||||
# you can define your attributes that you want to apply
|
||||
# for all your script tags
|
||||
|
||||
link_attributes:
|
||||
# you can define your attributes that you want to apply
|
||||
# for all your link tags
|
||||
12
config/packages/routing.yaml
Normal file
12
config/packages/routing.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
framework:
|
||||
router:
|
||||
utf8: true
|
||||
|
||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||
#default_uri: http://localhost
|
||||
|
||||
when@prod:
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: null
|
||||
5
config/preload.php
Normal file
5
config/preload.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
|
||||
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
|
||||
}
|
||||
3
config/routes.yaml
Normal file
3
config/routes.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
controllers:
|
||||
resource: ../src/Controller/
|
||||
type: attribute
|
||||
3
config/routes/dev/pentatrion_vite.yaml
Normal file
3
config/routes/dev/pentatrion_vite.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
_pentatrion_vite:
|
||||
prefix: /build
|
||||
resource: "@PentatrionViteBundle/Resources/config/routing.yaml"
|
||||
4
config/routes/framework.yaml
Normal file
4
config/routes/framework.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
when@dev:
|
||||
_errors:
|
||||
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
|
||||
prefix: /_error
|
||||
24
config/services.yaml
Normal file
24
config/services.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
# This file is the entry point to configure your own services.
|
||||
# Files in the packages/ subdirectory configure your dependencies.
|
||||
|
||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||
parameters:
|
||||
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
_defaults:
|
||||
autowire: true # Automatically injects dependencies in your services.
|
||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||
|
||||
# makes classes in src/ available to be used as services
|
||||
# this creates a service per class whose id is the fully-qualified class name
|
||||
App\:
|
||||
resource: '../src/'
|
||||
exclude:
|
||||
- '../src/DependencyInjection/'
|
||||
- '../src/Entity/'
|
||||
- '../src/Kernel.php'
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
# please note that last definitions always *replace* previous ones
|
||||
2323
package-lock.json
generated
Normal file
2323
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
package.json
Normal file
17
package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build"
|
||||
},
|
||||
"license": "UNLICENSED",
|
||||
"devDependencies": {
|
||||
"vite": "^3.0",
|
||||
"vite-plugin-symfony": "^0.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"autoprefixer": "^10.4.13",
|
||||
"daisyui": "^2.41.0",
|
||||
"tailwindcss": "^3.2.4"
|
||||
}
|
||||
}
|
||||
3
postcss.config.js
Normal file
3
postcss.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
plugins: [require("tailwindcss"), require("autoprefixer")],
|
||||
};
|
||||
9
public/index.php
Normal file
9
public/index.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
};
|
||||
79
src/Controller/AlbumController.php
Normal file
79
src/Controller/AlbumController.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/album', name: 'album.')]
|
||||
|
||||
class AlbumController extends AbstractController
|
||||
{
|
||||
|
||||
#[Route('/{album_id}', name: 'index')]
|
||||
public function album(Request $child)
|
||||
{
|
||||
|
||||
/* $LoggerBuilder = new ContainerBuilder();
|
||||
$LoggerBuilder->register('logger.service', 'LoggerService');
|
||||
$LoggerService = $LoggerBuilder->get('logger.service'); */
|
||||
|
||||
$album_id = $child->attributes->get('album_id');
|
||||
|
||||
$imagepath = $_SERVER['DOCUMENT_ROOT'] . '/images/gallery/';
|
||||
|
||||
$JSON = file_get_contents($imagepath . '01_JSON' . '/' . $album_id . '.json');
|
||||
|
||||
$items = json_decode($JSON, true);
|
||||
|
||||
$img_count = count($items[$album_id]);
|
||||
$per_page = 10;
|
||||
$max_pages = ceil($img_count / $per_page);
|
||||
|
||||
// $LoggerService->logData($_SERVER["REMOTE_ADDR"] . ' - ' . 'Album ' . $album_id . ' wurde aufgerufen');
|
||||
|
||||
|
||||
|
||||
return $this->render('album/album.html.twig', [
|
||||
'album' => $album_id,
|
||||
'items' => $items,
|
||||
'img_count' => $img_count,
|
||||
'per_page' => $per_page,
|
||||
'max_pages' => $max_pages
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/{album_id}/{image_id}', name: 'details')]
|
||||
public function details(Request $child)
|
||||
{
|
||||
|
||||
/* $LoggerBuilder = new ContainerBuilder();
|
||||
$LoggerBuilder->register('logger.service', 'LoggerService');
|
||||
$LoggerService = $LoggerBuilder->get('logger.service'); */
|
||||
|
||||
$album_id = $child->attributes->get('album_id');
|
||||
$image_id = $child->attributes->get('image_id');
|
||||
|
||||
$imagepath = $_SERVER['DOCUMENT_ROOT'] . '/images/gallery/';
|
||||
|
||||
$JSON = file_get_contents($imagepath . '01_JSON' . '/' . $album_id . '.json');
|
||||
|
||||
$items = json_decode($JSON, true);
|
||||
|
||||
$details_items = $items[$album_id][$image_id];
|
||||
$details_tags = $items[$album_id][$image_id]['Tags'];
|
||||
|
||||
// $LoggerService->logData($_SERVER["REMOTE_ADDR"] . ' - ' . 'Bild ' . $image_id . ' aus Album ' . $album_id . ' wurde aufgerufen');
|
||||
|
||||
return $this->render('album/details.html.twig', [
|
||||
|
||||
'album' => $album_id,
|
||||
'image' => $image_id,
|
||||
'items' => $details_items,
|
||||
'tags' => $details_tags
|
||||
]);
|
||||
}
|
||||
}
|
||||
77
src/Controller/GalleryController.php
Normal file
77
src/Controller/GalleryController.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/', name: 'gallery.')]
|
||||
|
||||
class GalleryController extends AbstractController
|
||||
{
|
||||
#[Route('/', name: 'base')]
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
// $logger->logData($_SERVER["REMOTE_ADDR"].' - '.$_SERVER["HTTP_USER_AGENT"]);
|
||||
|
||||
$imagepath = './images/gallery/';
|
||||
|
||||
/* $LoggerBuilder = new ContainerBuilder();
|
||||
$LoggerBuilder->register('logger.service', 'LoggerService');
|
||||
$LoggerService = $LoggerBuilder->get('logger.service'); */
|
||||
|
||||
$JSONBuilder = new ContainerBuilder();
|
||||
$JSONBuilder->register('json.service', 'JSONService');
|
||||
$JSONService = $JSONBuilder->get('json.service');
|
||||
|
||||
/* $DBBuilder = new ContainerBuilder();
|
||||
$DBBuilder->register('db.service', 'DBService');
|
||||
$DBService = $DBBuilder->get('db.service'); */
|
||||
|
||||
/* $MailerBuilder = new ContainerBuilder();
|
||||
$MailerBuilder->register('mailer.service', 'MailerService');
|
||||
$MailerService = $MailerBuilder->get('mailer.service'); */
|
||||
|
||||
/*
|
||||
$containerBuilder
|
||||
->register('newsletter_manager', 'NewsletterManager')
|
||||
->addMethodCall('setMailer', [new Reference('mailer')]);
|
||||
|
||||
$newsletterManager = $containerBuilder->get('newsletter_manager');
|
||||
|
||||
$MailerBuilder = new ContainerBuilder();
|
||||
$MailerBuilder->register('mailer.service', 'MailerService');
|
||||
$MailerService = $MailerBuilder->get('mailer.service');
|
||||
*/
|
||||
|
||||
// $LoggerService->logData($_SERVER["REMOTE_ADDR"] . ' - ' . $_SERVER["HTTP_USER_AGENT"]);
|
||||
|
||||
if (!file_exists($imagepath . '01_JSON/' . '01_All.json')) {
|
||||
$JSONService->dirToArray($imagepath);
|
||||
$JSONService->MergeJSON($imagepath);
|
||||
}
|
||||
|
||||
$JSON_File = $imagepath . '01_JSON' . '/' . '01_All' . '.json';
|
||||
|
||||
$JSON = file_get_contents($JSON_File);
|
||||
$items = json_decode($JSON, true);
|
||||
|
||||
$img_count = count($items);
|
||||
$per_page = 10;
|
||||
$max_pages = ceil($img_count / $per_page);
|
||||
|
||||
// $show = array_slice($items, $per_page * intval($_GET['page']) - 1, $per_page);
|
||||
|
||||
return $this->render('gallery/gallery.html.twig', [
|
||||
'items' => $items,
|
||||
'img_count' => $img_count,
|
||||
'per_page' => $per_page,
|
||||
'max_pages' => $max_pages
|
||||
]);
|
||||
}
|
||||
}
|
||||
11
src/Kernel.php
Normal file
11
src/Kernel.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
||||
|
||||
class Kernel extends BaseKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
}
|
||||
88
src/Service/JSONService.php
Normal file
88
src/Service/JSONService.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
class JSONService
|
||||
{
|
||||
|
||||
function dirToArray($dir_albums) {
|
||||
|
||||
$result = array();
|
||||
$cdir = scandir($dir_albums);
|
||||
$imagepath = $dir_albums;
|
||||
|
||||
$filename = $imagepath.'01_JSON'.'/'.'Aarburg'.'.json';
|
||||
|
||||
foreach ($cdir as $key => $value) {
|
||||
if (!in_array($value,array(".","..","01_JSON"))) {
|
||||
|
||||
if (is_dir($dir_albums . $value)) {
|
||||
$filename = $imagepath.'01_JSON'.'/'.$value.'.json';
|
||||
|
||||
$result[$value][$value] = $this->dirToArray($dir_albums . $value);
|
||||
|
||||
$json_encoded = json_encode($result[$value]);
|
||||
file_put_contents($filename, $json_encoded);
|
||||
}
|
||||
else {
|
||||
$value_image = $imagepath.'/'.$value;
|
||||
getimagesize($value_image, $infos);
|
||||
$exif = exif_read_data($value_image, 0, true);
|
||||
|
||||
$tags = iptcparse($infos['APP13']);
|
||||
|
||||
if(!isset(($tags['2#025']))) {
|
||||
$tags['2#025'] = null;
|
||||
}
|
||||
|
||||
$metadata = array(
|
||||
|
||||
'ApertureFNumber' => $exif['COMPUTED']['ApertureFNumber'],
|
||||
'FocalLength' => substr($exif['EXIF']['FocalLength'], 0, -2),
|
||||
'ExposureTime' => $exif['EXIF']['ExposureTime'],
|
||||
'ISOSpeedRatings' => $exif['EXIF']['ISOSpeedRatings'],
|
||||
'DateTimeOriginal' => date('d.m.Y H:i:s', strtotime($exif['EXIF']['DateTimeOriginal'])),
|
||||
'Lens' => $exif['EXIF']['UndefinedTag:0xA434'],
|
||||
'Tags' => $tags['2#025']
|
||||
|
||||
/* 'Height' => $exif['COMPUTED']['Height'],
|
||||
'Width' => $exif['COMPUTED']['Width'],
|
||||
'Model' => $exif['IFD0']['Model'],
|
||||
'Artist' => $exif['IFD0']['Artist'], */
|
||||
);
|
||||
|
||||
$result[$value] = $metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function MergeJSON($dir_json) {
|
||||
|
||||
$JSONFiles = new Finder();
|
||||
|
||||
$JSONFiles
|
||||
->name('*.json')
|
||||
->files()->in($dir_json);
|
||||
|
||||
foreach ($JSONFiles as $file) {
|
||||
$file->getContents();
|
||||
}
|
||||
|
||||
$valle = array();
|
||||
|
||||
foreach($JSONFiles as $vurl) {
|
||||
if (file_exists($vurl)) {
|
||||
$vres = json_decode(file_get_contents($vurl), true);
|
||||
$valle = array_merge($valle,$vres);
|
||||
}
|
||||
}
|
||||
|
||||
$savedata2 = json_encode($valle);
|
||||
$savefile2 = $dir_json.'/01_JSON/'.'01_All.json';
|
||||
|
||||
file_put_contents($savefile2, $savedata2, LOCK_EX);
|
||||
}
|
||||
}
|
||||
0
src/Service/LogService.php
Normal file
0
src/Service/LogService.php
Normal file
21
src/Service/MailerService.php
Normal file
21
src/Service/MailerService.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Mailer\MailerInterface;
|
||||
use Symfony\Component\Mime\Email;
|
||||
|
||||
class MailerService
|
||||
{
|
||||
public static function sendMail(MailerInterface $mailer)
|
||||
{
|
||||
|
||||
$email = new Email();
|
||||
|
||||
$email
|
||||
->from('michael.schwab@outlook.com')
|
||||
->to('michael.schwab@gmx.ch')
|
||||
->subject('Site update just happened!')
|
||||
->text('Someone just updated the site. We told them:');
|
||||
|
||||
$mailer->send($email);
|
||||
}
|
||||
}
|
||||
38
src/Twig/ViteExtension.php
Normal file
38
src/Twig/ViteExtension.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Twig;
|
||||
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
class ViteExtension extends AbstractExtension
|
||||
{
|
||||
public function getFilters(): array
|
||||
{
|
||||
return [
|
||||
// If your filter generates SAFE HTML, you should add a third
|
||||
// parameter: ['is_safe' => ['html']]
|
||||
// Reference: https://twig.symfony.com/doc/2.x/advanced.html#automatic-escaping
|
||||
new TwigFilter('filter_name', [$this, 'doSomething']),
|
||||
];
|
||||
}
|
||||
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
new TwigFunction('vite_entry_script_tags', [$this, 'renderViteScriptTags'], ['is_safe' => ['html']]),
|
||||
new TwigFunction('vite_entry_link_tags', [$this, 'renderViteLinkTags'], ['is_safe' => ['html']]),
|
||||
];
|
||||
}
|
||||
|
||||
public function renderViteScriptTags(string $entryName, array $options = []): string
|
||||
{
|
||||
return $this->entrypointRenderer->renderScripts($entryName, $options);
|
||||
}
|
||||
|
||||
public function renderViteLinkTags(string $entryName, array $options = []): string
|
||||
{
|
||||
return $this->entrypointRenderer->renderLinks($entryName, $options);
|
||||
}
|
||||
}
|
||||
107
symfony.lock
Normal file
107
symfony.lock
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"pentatrion/vite-bundle": {
|
||||
"version": "2.3",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes-contrib",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "33d48a1c831b2d29641175c8320e66a9f1c9911f"
|
||||
},
|
||||
"files": [
|
||||
"config/routes/dev/pentatrion_vite.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/console": {
|
||||
"version": "6.1",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.3",
|
||||
"ref": "da0c8be8157600ad34f10ff0c9cc91232522e047"
|
||||
},
|
||||
"files": [
|
||||
"bin/console"
|
||||
]
|
||||
},
|
||||
"symfony/flex": {
|
||||
"version": "2.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
|
||||
},
|
||||
"files": [
|
||||
".env"
|
||||
]
|
||||
},
|
||||
"symfony/framework-bundle": {
|
||||
"version": "6.1",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.4",
|
||||
"ref": "3cd216a4d007b78d8554d44a5b1c0a446dab24fb"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/cache.yaml",
|
||||
"config/packages/framework.yaml",
|
||||
"config/preload.php",
|
||||
"config/routes/framework.yaml",
|
||||
"config/services.yaml",
|
||||
"public/index.php",
|
||||
"src/Controller/.gitignore",
|
||||
"src/Kernel.php"
|
||||
]
|
||||
},
|
||||
"symfony/mailer": {
|
||||
"version": "6.1",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "4.3",
|
||||
"ref": "97a61eabb351d7f6cb7702039bcfe07fe9d7e03c"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/mailer.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/maker-bundle": {
|
||||
"version": "1.48",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
||||
}
|
||||
},
|
||||
"symfony/routing": {
|
||||
"version": "6.1",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.1",
|
||||
"ref": "a44010c0d06989bd4f154aa07d2542d47caf5b83"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/routing.yaml",
|
||||
"config/routes.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/twig-bundle": {
|
||||
"version": "6.1",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.4",
|
||||
"ref": "bb2178c57eee79e6be0b297aa96fc0c0def81387"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/twig.yaml",
|
||||
"templates/base.html.twig"
|
||||
]
|
||||
},
|
||||
"twig/extra-bundle": {
|
||||
"version": "v3.4.0"
|
||||
}
|
||||
}
|
||||
15
tailwind.config.js
Normal file
15
tailwind.config.js
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
content: [
|
||||
'./templates/**/*.{twig,html,js}',
|
||||
'./public/**/*.html'
|
||||
],
|
||||
future: {
|
||||
// removeDeprecatedGapUtilities: true,
|
||||
// purgeLayersByDefault: true,
|
||||
},
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
variants: {},
|
||||
plugins: [require("daisyui")],
|
||||
}
|
||||
20
templates/about/index.html.twig
Normal file
20
templates/about/index.html.twig
Normal file
@@ -0,0 +1,20 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Hello AboutController!{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<style>
|
||||
.example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
|
||||
.example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
|
||||
</style>
|
||||
|
||||
<div class="example-wrapper">
|
||||
<h1>Hello {{ controller_name }}! ✅</h1>
|
||||
|
||||
This friendly message is coming from:
|
||||
<ul>
|
||||
<li>Your controller at <code><a href="{{ 'C:/xampp/htdocs/portfolio/src/Controller/AboutController.php'|file_link(0) }}">src/Controller/AboutController.php</a></code></li>
|
||||
<li>Your template at <code><a href="{{ 'C:/xampp/htdocs/portfolio/templates/about/index.html.twig'|file_link(0) }}">templates/about/index.html.twig</a></code></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
35
templates/album/album.html.twig
Normal file
35
templates/album/album.html.twig
Normal file
@@ -0,0 +1,35 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Home -
|
||||
{{ album }}
|
||||
{% endblock %}
|
||||
|
||||
{% block album %}
|
||||
|
||||
<div class="my_album">
|
||||
{% for album_1, albums_1 in items %}
|
||||
{% for album_2, albums_2 in albums_1 %}
|
||||
<div class="my_album_child card bg-base-50 shadow-xl">
|
||||
<figure class="px-2 pt-2">
|
||||
<img class="rounded-xl" src="{{ asset('images/gallery') }}/{{ album_1 }}/{{ album_2 }}"/>
|
||||
</figure>
|
||||
<div class="p-6">
|
||||
|
||||
<div class="flex flex-row">
|
||||
<div class="basis-1/2 justify-items-start gallery">
|
||||
<a href="{{ asset('images/gallery') }}/{{ album_1 }}/{{ album_2 }}">
|
||||
<button type="button" class="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out">DiaShow</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="basis-1/2 justify-items-end">
|
||||
<a href="{{ path ('album.details',{album_id: album_1, image_id:album_2}) }}">
|
||||
<button type="button" class="inline-block px-6 py-2.5 bg-blue-600 text-white font-medium text-xs leading-tight uppercase rounded shadow-md hover:bg-blue-700 hover:shadow-lg focus:bg-blue-700 focus:shadow-lg focus:outline-none focus:ring-0 active:bg-blue-800 active:shadow-lg transition duration-150 ease-in-out">Details</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
63
templates/album/details.html.twig
Normal file
63
templates/album/details.html.twig
Normal file
@@ -0,0 +1,63 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Home -
|
||||
{{ album }}
|
||||
-
|
||||
{{ image }}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
<div class="card bg-base-50 shadow-xl">
|
||||
<figure class="px-2 pt-2">
|
||||
<img class="rounded-xl" src="{{ asset('images/gallery') }}/{{ album }}/{{ image }}"/>
|
||||
</figure>
|
||||
|
||||
<div class="card-body items-left text-left">
|
||||
<p>
|
||||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-title">Blende</div>
|
||||
<div class="stat-value text-lg">{{ items.ApertureFNumber }}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Brennweite</div>
|
||||
<div class="stat-value text-lg">{{ items.FocalLength }}
|
||||
mm</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Verschlusszeit</div>
|
||||
<div class="stat-value text-lg">{{ items.ExposureTime }}
|
||||
sek.</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">ISO Wert</div>
|
||||
<div class="stat-value text-lg">{{ items.ISOSpeedRatings }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-title">Objektiv</div>
|
||||
<div class="stat-value text-lg">{{ items.Lens }}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Aufnahmedatum</div>
|
||||
<div class="stat-value text-lg">{{ items.DateTimeOriginal }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats shadow">
|
||||
<div class="stat">
|
||||
<div class="stat-title">Tags</div>
|
||||
<div class="stat-value text-lg">
|
||||
{% if items.Tags is not null %}
|
||||
{% for tag_1, tags_1 in tags %}
|
||||
#{{ tags_1 }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
46
templates/base.html.twig
Normal file
46
templates/base.html.twig
Normal file
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
|
||||
|
||||
<title>
|
||||
{% block title %}{% endblock %}
|
||||
</title>
|
||||
{{ vite_entry_link_tags('app') }}
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
<!-- ANCHOR Body -->
|
||||
<body>
|
||||
{% block body %}
|
||||
|
||||
{# {% block navigation %}
|
||||
<div class="my_navigation">{% include 'navigation.html.twig' %}</div>
|
||||
{% endblock %} #}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="my_breadcrumbs">{% include 'breadcrumbs.html.twig' %}</div>
|
||||
{% endblock %}
|
||||
|
||||
<div class="my_container">
|
||||
{% block gallery %}{% endblock %}
|
||||
{% block album %}{% endblock %}
|
||||
{% block details %}{% endblock %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{# {% block pagination %}
|
||||
<div class="my_pagination">{% include 'pagination.html.twig' %}</div>
|
||||
{% endblock %} #}
|
||||
|
||||
<!-- ANCHOR JS -->
|
||||
<script src="https://kit.fontawesome.com/ea07098c7f.js" crossorigin="anonymous"></script>
|
||||
|
||||
|
||||
{{ vite_entry_script_tags('app') }}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
24
templates/breadcrumbs.html.twig
Normal file
24
templates/breadcrumbs.html.twig
Normal file
@@ -0,0 +1,24 @@
|
||||
{% block breadcrumbs %}
|
||||
<div class="text-xl breadcrumbs">
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="{{ path ('gallery.base') }}">Home</a>
|
||||
</li>
|
||||
|
||||
{% if album is defined %}
|
||||
<li>
|
||||
<a href="{{ path ('album.index',{album_id: album}) }}">{{ album }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if image is defined %}
|
||||
<li>
|
||||
{{ image }}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
35
templates/gallery/gallery.html.twig
Normal file
35
templates/gallery/gallery.html.twig
Normal file
@@ -0,0 +1,35 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Gallerien
|
||||
{% endblock %}
|
||||
|
||||
{% block gallery %}
|
||||
|
||||
<div class="my_gallery">
|
||||
{% for album_1, albums_1 in items %}
|
||||
{% for album_2, albums_2 in albums_1 %}
|
||||
{% if loop.index == 1 %}
|
||||
|
||||
<a href="{{ path ('album.index',{album_id: album_1}) }}/?page=1">
|
||||
<div class="my_card card" style="--cards:5">
|
||||
<div class="my_gallery_child rounded-xl">
|
||||
<div class="my_gallery_child-title">
|
||||
<button class="btn btn-warning">{{ album_1 }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my_gallery_child rounded-xl">
|
||||
<img src="{{ asset('images/gallery') }}/{{ album_1 }}/{{ album_2 }}" alt="{{ album_1 }}" class="object-cover">
|
||||
</div>
|
||||
<div class="my_gallery_child"></div>
|
||||
<div class="my_gallery_child"></div>
|
||||
<div class="my_gallery_child"></div>
|
||||
<div class="my_gallery_child"></div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
60
templates/navigation.html.twig
Normal file
60
templates/navigation.html.twig
Normal file
@@ -0,0 +1,60 @@
|
||||
<div class="my_border navbar bg-base-100">
|
||||
<div class="navbar-start">
|
||||
<div class="dropdown">
|
||||
<label tabindex="0" class="btn btn-ghost lg:hidden">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewbox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16"/></svg>
|
||||
</label>
|
||||
<ul tabindex="0" class="menu menu-compact dropdown-content mt-3 p-2 shadow bg-base-100 rounded-box w-52">
|
||||
<li>
|
||||
<a>Item 1</a>
|
||||
</li>
|
||||
<li tabindex="0">
|
||||
<a class="justify-between">
|
||||
Parent
|
||||
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24"><path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"/></svg>
|
||||
</a>
|
||||
<ul class="p-2 bg-base-100">
|
||||
<li>
|
||||
<a>Submenu 1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>Submenu 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a>Item 3</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="{{ path ('gallery.base') }}" class="btn btn-ghost normal-case text-xl">mschwab.net</a>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="navbar-center hidden lg:flex">
|
||||
<ul class="menu menu-horizontal p-0">
|
||||
<li>
|
||||
<a href="{{ path ('gallery.base') }}">Home</a>
|
||||
</li>
|
||||
<li tabindex="0">
|
||||
<a>
|
||||
Gallery
|
||||
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewbox="0 0 24 24"><path d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"/></svg>
|
||||
</a>
|
||||
<ul class="p-2">
|
||||
<li>
|
||||
<a>Submenu 1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a>Submenu 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a>About</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
26
vite.config.js
Normal file
26
vite.config.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { resolve } from "path";
|
||||
import { defineConfig } from "vite";
|
||||
import symfonyPlugin from "vite-plugin-symfony";
|
||||
|
||||
/* if you're using React */
|
||||
// import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
/* react(), // if you're using React */
|
||||
symfonyPlugin(),
|
||||
],
|
||||
build: {
|
||||
manifest: true,
|
||||
emptyOutDir: true,
|
||||
assetsDir: "",
|
||||
cssCodeSplit: true,
|
||||
format: "cjs",
|
||||
outDir: "./public/build/",
|
||||
rollupOptions: {
|
||||
input: {
|
||||
app: "./assets/js/main.js",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user