Feat: Integriert Asset Mapper, Importmap und Twig Extra Bundle; aktualisiert Frontend-Assets, Fonts und Styles

This commit is contained in:
2026-06-13 16:35:01 +02:00
parent dde45bd90b
commit dd4b5d98d5
23 changed files with 1193 additions and 378 deletions
+5
View File
@@ -40,3 +40,8 @@ desktop.ini
npm-debug.log
yarn-error.log
###< symfony/webpack-encore-bundle ###
###> symfony/asset-mapper ###
/public/assets/
/assets/vendor/
###< symfony/asset-mapper ###
+1 -1
View File
@@ -5,7 +5,7 @@
* (and its CSS file) in your base layout (base.html.twig).
*/
// require('bootstrap');
require('bootstrap');
// any CSS you import will output into a single css file (app.scss in this case)
import './styles/app.scss';
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

+50 -2
View File
@@ -1,3 +1,37 @@
@use 'app/nav';
@use 'app/footer';
// =============================================================================
// Fonts
// =============================================================================
@font-face {
font-family: 'Agave';
src: url('../fonts/agave-regular.woff2') format('woff2');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Fantasque Sans Mono';
src: url('../fonts/fantasque-sans-mono-regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'JetBrains Mono';
src: url('../fonts/jetbrains-mono-regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Material Symbols Outlined';
font-style: normal;
src: url('../fonts/material-symbols-outlined.woff2') format('woff');
}
// =============================================================================
// Design Tokens — Light Palette
// =============================================================================
@@ -90,8 +124,8 @@ $dk-on-background: #dae2fd;
// Shared Tokens — Typography & Radius
// =============================================================================
$font-display: 'Space Grotesk', system-ui, sans-serif;
$font-body: 'Geist', system-ui, -apple-system, sans-serif;
$font-display: 'Agave', system-ui, sans-serif;
$font-body: 'Fantasque Sans Mono', system-ui, -apple-system, sans-serif;
$font-mono: 'JetBrains Mono', 'Courier New', monospace;
$radius-sm: 0.25rem;
@@ -545,3 +579,17 @@ pre {
box-shadow: var(--glow-primary);
}
}
.material-symbols-outlined {
font-family: 'Material Symbols Outlined';
font-weight: normal;
font-style: normal;
font-size: 20px;
display: inline-block;
line-height: 1;
text-transform: none;
letter-spacing: normal;
word-wrap: normal;
white-space: nowrap;
direction: ltr;
}
+20
View File
@@ -0,0 +1,20 @@
.footer-link {
color: rgba(255, 255, 255, .6);
transition: color .15s ease;
}
.footer-link:hover {
color: var(--color-primary-container);
}
#footer {
z-index: 50;
background: rgba(0,0,0,.3);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border-color: rgba(192, 199, 211, .1) !important;
}
#footer-copyright {
color: rgba(255,255,255,.4);
}
+31
View File
@@ -0,0 +1,31 @@
nav div {
height: 64px;
}
/* Glassmorphism nav — uses RGB channel var for rgba() composition */
.nav-glass {
background-color: rgba(var(--color-surface-container-lowest-rgb), .85);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
/* Nav link colours — needs :hover, can't do inline */
.nav-link-ds {
color: var(--color-on-surface-variant);
transition: color .15s ease;
}
.nav-link-ds:hover {
color: #50a7fa;
}
#top-nav {
z-index: 50;
border-color: rgba(192, 199, 211, .3) !important;
}
#nav-site-name {
font-family: var(--font-display);
letter-spacing: -.02em;
font-size: 1rem;
}
+9 -2
View File
@@ -10,14 +10,20 @@
"ext-ctype": "*",
"ext-iconv": "*",
"ext-redis": "*",
"symfony/asset": "8.1.*",
"symfony/asset-mapper": "8.1.*",
"symfony/cache": "8.1.*",
"symfony/console": "8.1.*",
"symfony/dotenv": "8.1.*",
"symfony/flex": "^2",
"symfony/framework-bundle": "8.1.*",
"symfony/runtime": "8.1.*",
"symfony/twig-bundle": "8.1.*",
"symfony/web-link": "8.1.*",
"symfony/webpack-encore-bundle": "^2.4",
"symfony/yaml": "8.1.*"
"symfony/yaml": "8.1.*",
"twig/extra-bundle": "^2.12|^3.0",
"twig/twig": "^2.12|^3.0"
},
"require-dev": {
"symfony/debug-bundle": "8.1.*",
@@ -47,7 +53,8 @@
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
"assets:install %PUBLIC_DIR%": "symfony-cmd",
"importmap:install": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
Generated
+906 -355
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -7,4 +7,5 @@ return [
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
];
+11
View File
@@ -0,0 +1,11 @@
framework:
asset_mapper:
# The paths to make available to the asset mapper.
paths:
- assets/
missing_import_mode: strict
when@prod:
framework:
asset_mapper:
missing_import_mode: warn
+4
View File
@@ -17,3 +17,7 @@ when@test:
test: true
session:
storage_factory_id: session.storage.factory.mock_file
when@prod:
framework:
http_cache: true
+54 -3
View File
@@ -286,7 +286,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* }>,
* },
* asset_mapper?: bool|array{ // Asset Mapper configuration
* enabled?: bool|Param, // Default: false
* enabled?: bool|Param, // Default: true
* paths?: string|array<string, scalar|Param|null>,
* excluded_patterns?: list<scalar|Param|null>,
* exclude_dotfiles?: bool|Param, // If true, any files starting with "." will be excluded from the asset mapper. // Default: true
@@ -416,7 +416,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* log_channel?: scalar|Param|null, // The channel of log message. Null to let Symfony decide. // Default: null
* }>,
* web_link?: bool|array{ // Web links configuration
* enabled?: bool|Param, // Default: false
* enabled?: bool|Param, // Default: true
* },
* lock?: bool|string|array{ // Lock configuration
* enabled?: bool|Param, // Default: false
@@ -471,7 +471,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* },
* disallow_search_engine_index?: bool|Param, // Enabled by default when debug is enabled. // Default: true
* http_client?: bool|array{ // HTTP Client configuration
* enabled?: bool|Param, // Default: false
* enabled?: bool|Param, // Default: true
* max_host_connections?: int|Param, // The maximum number of connections to a single host.
* default_options?: array{
* headers?: array<string, mixed>,
@@ -763,6 +763,53 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* script_attributes?: array<string, scalar|Param|null>,
* link_attributes?: array<string, scalar|Param|null>,
* }
* @psalm-type TwigExtraConfig = array{
* cache?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* html?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* markdown?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* intl?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* cssinliner?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* inky?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* string?: bool|array{
* enabled?: bool|Param, // Default: false
* },
* commonmark?: array{
* renderer?: array{ // Array of options for rendering HTML.
* block_separator?: scalar|Param|null,
* inner_separator?: scalar|Param|null,
* soft_break?: scalar|Param|null,
* },
* html_input?: "strip"|"allow"|"escape"|Param, // How to handle HTML input.
* allow_unsafe_links?: bool|Param, // Remove risky link and image URLs by setting this to false. // Default: true
* max_nesting_level?: int|Param, // The maximum nesting level for blocks. // Default: 9223372036854775807
* max_delimiters_per_line?: int|Param, // The maximum number of strong/emphasis delimiters per line. // Default: 9223372036854775807
* slug_normalizer?: array{ // Array of options for configuring how URL-safe slugs are created.
* instance?: mixed,
* max_length?: int|Param, // Default: 255
* unique?: mixed,
* },
* commonmark?: array{ // Array of options for configuring the CommonMark core extension.
* enable_em?: bool|Param, // Default: true
* enable_strong?: bool|Param, // Default: true
* use_asterisk?: bool|Param, // Default: true
* use_underscore?: bool|Param, // Default: true
* unordered_list_markers?: list<scalar|Param|null>,
* },
* ...<string, mixed>
* },
* }
* @psalm-type ConfigType = array{
* imports?: ImportsConfig,
* parameters?: ParametersConfig,
@@ -770,6 +817,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* framework?: FrameworkConfig,
* twig?: TwigConfig,
* webpack_encore?: WebpackEncoreConfig,
* twig_extra?: TwigExtraConfig,
* "when@dev"?: array{
* imports?: ImportsConfig,
* parameters?: ParametersConfig,
@@ -780,6 +828,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* twig?: TwigConfig,
* maker?: MakerConfig,
* webpack_encore?: WebpackEncoreConfig,
* twig_extra?: TwigExtraConfig,
* },
* "when@prod"?: array{
* imports?: ImportsConfig,
@@ -788,6 +837,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* framework?: FrameworkConfig,
* twig?: TwigConfig,
* webpack_encore?: WebpackEncoreConfig,
* twig_extra?: TwigExtraConfig,
* },
* "when@test"?: array{
* imports?: ImportsConfig,
@@ -798,6 +848,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param;
* debug?: DebugConfig,
* twig?: TwigConfig,
* webpack_encore?: WebpackEncoreConfig,
* twig_extra?: TwigExtraConfig,
* },
* ...<string, ExtensionType|array{ // extra keys must follow the when@%env% pattern or match an extension alias
* imports?: ImportsConfig,
+19
View File
@@ -0,0 +1,19 @@
<?php
/**
* Returns the importmap for this application.
*
* - "path" is a path inside the asset mapper system. Use the
* "debug:asset-map" command to see the full list of paths.
*
* - "entrypoint" (JavaScript only) set to true for any module that will
* be used as an "entrypoint" (and passed to the importmap() Twig function).
*
* The "importmap:require" command can be used to add new entries to this file.
*/
return [
'app' => [
'path' => './assets/app.js',
'entrypoint' => true,
],
];
+19 -1
View File
@@ -1,4 +1,19 @@
{
"symfony/asset-mapper": {
"version": "8.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.4",
"ref": "c01c47af2ec66a74ec046eccb919cfe27d3464ec"
},
"files": [
"assets/app.js",
"assets/styles/app.css",
"config/packages/asset_mapper.yaml",
"importmap.php"
]
},
"symfony/console": {
"version": "8.1",
"recipe": {
@@ -113,11 +128,14 @@
"ref": "b346dae458e64a1921ded2125993d94bd719a8dd"
},
"files": [
"assets/app.ts",
"assets/app.js",
"assets/styles/app.css",
"config/packages/webpack_encore.yaml",
"package.json",
"webpack.config.js"
]
},
"twig/extra-bundle": {
"version": "v3.24.0"
}
}
+20 -12
View File
@@ -1,29 +1,37 @@
<!DOCTYPE html>
<html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}creative-dragonslayer.de{% endblock %}</title>
<link rel="icon" href="{{ asset('images/logo.png') }}">
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{% endblock %}
{% block head %}{% endblock %}
{% set frankenphpHotReload = app.request.server.get('FRANKENPHP_HOT_RELOAD') %}
{% if frankenphpHotReload %}
<meta name="frankenphp-hot-reload:url" content="{{ frankenphpHotReload }}">
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
<meta name="frankenphp-hot-reload:url" content="{{ frankenphpHotReload }}">
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
{% endif %}
</head>
<body>
{% include 'widgets/nav_bar.html.twig' %}
<main>
{% block body %}{% endblock %}
{% block body %}{% endblock %}
</main>
<footer>
{% block javascripts %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</footer>
{% include 'widgets/footer.html.twig' %}
{% block javascripts %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
{{ encore_entry_script_tags('app') }}
{% endblock %}
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
<footer class="position-fixed bottom-0 start-0 end-0 border-top"
id="footer">
<div class="container d-flex flex-column flex-md-row justify-content-between align-items-center py-3">
<div id="footer-copyright" class="text-label-sm fw-bold">
© 2026 creative-dragonslayer.de
</div>
<div class="d-flex gap-4 mt-2 mt-md-0">
{# <a href="#" class="text-label-sm text-decoration-none footer-link">Impressum</a>#}
{# <a href="#" class="text-label-sm text-decoration-none footer-link">Datenschutz</a>#}
{# <a href="#" class="text-label-sm text-decoration-none footer-link">Nutzungsbedingungen</a>#}
<a href="#" class="text-label-sm text-decoration-none footer-link">Credits</a>
</div>
</div>
</footer>
+17
View File
@@ -0,0 +1,17 @@
<nav class="position-fixed top-0 start-0 end-0 nav-glass border-bottom"
id="top-nav"
aria-label="Hauptnavigation">
<div class="container d-flex justify-content-between align-items-center">
<span id="nav-site-name" class="fw-bold text-white">
CTDRA
</span>
<div class="d-none d-md-flex align-items-center gap-4">
<a href="#" class="text-label-sm text-decoration-none nav-link-ds">News</a>
<a href="#" class="text-label-sm text-decoration-none nav-link-ds">Projects</a>
<a href="#" class="text-label-sm text-decoration-none nav-link-ds">About Me</a>
</div>
<div>&nbsp;</div>
</div>
</nav>
+6 -1
View File
@@ -8,7 +8,12 @@
"isolatedModules": true,
"esModuleInterop": true,
"skipLibCheck": true,
"noEmit": true
"noEmit": true,
"plugins":[
{
"name": "typescript-plugin-css"
}
]
},
"include": ["assets/**/*"]
}
+6 -1
View File
@@ -20,7 +20,9 @@ Encore
* Each entry will result in one JavaScript file (e.g. app.js)
* and one CSS file (e.g. app.css) if your JavaScript imports CSS.
*/
.addEntry('app', './assets/app.ts')
.addEntry('app', './assets/app.js')
.addEntry('root', './assets/ts/root/root.ts')
// When enabled, Webpack "splits" your files into smaller pieces for greater optimization.
.splitEntryChunks()
@@ -61,6 +63,9 @@ Encore
// uncomment if you use TypeScript
.enableTypeScriptLoader()
// optionally enable forked type script for faster builds
// https://www.npmjs.com/package/fork-ts-checker-webpack-plugin
// requires that you have a tsconfig.json file that is setup correctly.
.enableForkedTypeScriptTypesChecking()
// uncomment if you use React