Add support for metatags
This commit is contained in:
parent
ae440be40c
commit
4564aa9534
25 changed files with 230 additions and 22 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -24,5 +24,5 @@
|
|||
node_modules
|
||||
/assets/styles/*.css.map
|
||||
###> dont upload files to repo
|
||||
/public/photos
|
||||
/public/files
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -141,9 +141,10 @@
|
|||
|
||||
.close {
|
||||
cursor: pointer;
|
||||
font-family: AtomicAge-Regular;
|
||||
font-size: 2rem;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
right: 5px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@
|
|||
}
|
||||
}
|
||||
.intro {
|
||||
//color: colors.$primaryWhite;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.list {
|
||||
padding-top: 1rem;
|
||||
padding: 2rem 0;
|
||||
border-top: 5px solid colors.$primaryYellow;
|
||||
|
||||
.post {
|
||||
|
|
|
|||
13
assets/styles/scss/front/_taxonomy.scss
Normal file
13
assets/styles/scss/front/_taxonomy.scss
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
@use '../shared/colors' as colors;
|
||||
|
||||
.category, .tag {
|
||||
.posts, .photos {
|
||||
ul {
|
||||
list-style-type: square;
|
||||
color: colors.$primaryWhite;
|
||||
li {
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
@use './front/typography';
|
||||
@use './front/layout';
|
||||
@use './front/menu';
|
||||
|
||||
@use './front/lists';
|
||||
@use './front/photos';
|
||||
@use './front/posts';
|
||||
@use './front/taxonomy';
|
||||
35
migrations/Version20260608200422.php
Normal file
35
migrations/Version20260608200422.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20260608200422 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE page ADD description TEXT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE photos ADD description TEXT DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE post ADD description TEXT DEFAULT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE page DROP description');
|
||||
$this->addSql('ALTER TABLE photos DROP description');
|
||||
$this->addSql('ALTER TABLE post DROP description');
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ final class PhotosController extends AbstractController
|
|||
'title' => $photo->getTitle(),
|
||||
'date' => $photo->getDate(),
|
||||
'category' => $photo->getCategory()->getTitle(),
|
||||
'thumbnail' => 'photos/' . strtolower(str_replace(' ', '_', $photo->getTitle())) . '/' . $photo->getThumbnail(),
|
||||
'thumbnail' => 'files/uploads/photos/' . strtolower(str_replace(' ', '_', $photo->getTitle())) . '/' . $photo->getThumbnail(),
|
||||
'url' => $photo->getUrl(),
|
||||
];
|
||||
}
|
||||
|
|
@ -44,12 +44,15 @@ final class PhotosController extends AbstractController
|
|||
'title' => $photos->getTitle(),
|
||||
'category' => $photos->getCategory()->getTitle(),
|
||||
'urlSafeCategory' => $photos->getCategory()->getUrlSafeTitle(),
|
||||
'tags' => $photos->getTags(),
|
||||
'text' => $photos->getText(),
|
||||
'date' => $photos->getDate()
|
||||
'description' => $photos->getDescription(),
|
||||
'date' => $photos->getDate(),
|
||||
'thumbnail' => '/files/uploads/photos/' . strtolower(str_replace(' ', '_', $photos->getTitle())) . '/' . $photos->getThumbnail(),
|
||||
];
|
||||
|
||||
foreach ($uploads as $index => $upload) {
|
||||
$filePath = 'photos/' . strtolower(str_replace(' ', '_', $album['title'])) . '/' . $upload->getFile();
|
||||
$filePath = 'files/uploads/photos/' . strtolower(str_replace(' ', '_', $album['title'])) . '/' . $upload->getFile();
|
||||
|
||||
$album['uploads'][] = [
|
||||
'file' => $filePath,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Entity;
|
|||
use App\Repository\CategoryRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\Common\Collections\Order;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity(repositoryClass: CategoryRepository::class)]
|
||||
|
|
@ -22,12 +23,14 @@ class Category
|
|||
* @var Collection<int, Post>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Post::class, mappedBy: 'category')]
|
||||
#[ORM\OrderBy(['date' => 'DESC'])]
|
||||
private Collection $posts;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Photos>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Photos::class, mappedBy: 'category')]
|
||||
#[ORM\OrderBy(['date' => 'DESC'])]
|
||||
private Collection $photos;
|
||||
|
||||
public function __construct()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ class Page
|
|||
#[ORM\Column]
|
||||
private ?bool $published = null;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
private ?string $description = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
|
|
@ -78,4 +81,16 @@ class Page
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): static
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ class Photos
|
|||
#[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'photos')]
|
||||
private Collection $tags;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
private ?string $description = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->uploads = new ArrayCollection();
|
||||
|
|
@ -182,4 +185,16 @@ class Photos
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): static
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ class Post
|
|||
#[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'posts')]
|
||||
private Collection $tags;
|
||||
|
||||
#[ORM\Column(type: Types::TEXT, nullable: true)]
|
||||
private ?string $description = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->tags = new ArrayCollection();
|
||||
|
|
@ -145,4 +148,16 @@ class Post
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): static
|
||||
{
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,14 @@ class Tag
|
|||
* @var Collection<int, Post>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Post::class, mappedBy: 'tags')]
|
||||
#[ORM\OrderBy(['date' => 'DESC'])]
|
||||
private Collection $posts;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Photos>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: Photos::class, mappedBy: 'tags')]
|
||||
#[ORM\OrderBy(['date' => 'DESC'])]
|
||||
private Collection $photos;
|
||||
|
||||
public function __construct()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class PhotoUploader {
|
|||
){}
|
||||
|
||||
public function upload(UploadedFile $file, string $galleryName) : string {
|
||||
$this->setTargetDirectory('photos/' . strtolower(str_replace(' ', '_', $galleryName)));
|
||||
$this->setTargetDirectory('files/uploads/photos/' . strtolower(str_replace(' ', '_', $galleryName)));
|
||||
$originalFilename = pathInfo($file->getClientOriginalName(), PATHINFO_FILENAME);
|
||||
$safeFilename = $this->slugger->slug($originalFilename);
|
||||
$filename = $safeFilename . '.' . $file->guessExtension();
|
||||
|
|
|
|||
|
|
@ -20,6 +20,24 @@
|
|||
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- Metatags -->
|
||||
<meta name="title" content="{% block metatitle %}{% endblock %}" />
|
||||
<meta name="description" content="{% block metadescription %}{% endblock %}" />
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://alexdaniels.me" />
|
||||
<meta property="og:title" content="{% block ogtitle %}{% endblock %}" />
|
||||
<meta property="og:description" content="{% block ogdescription %}{% endblock %}" />
|
||||
<meta property="og:image" content="{% block ogimage %}{% endblock %}" />
|
||||
|
||||
<!-- X (Twitter) -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content="https://alexdaniels.me" />
|
||||
<meta property="twitter:title" content="{% block twittertitle %}{% endblock %}" />
|
||||
<meta property="twitter:description" content="{% block twitterdescription %}{% endblock %}" />
|
||||
<meta property="twitter:image" content="{% block twitterimage %}{% endblock %}" />
|
||||
|
||||
</head>
|
||||
<body class="secondary layout--v1 {{ app.user ? 'auth': '' }}">
|
||||
<div id="root">
|
||||
|
|
|
|||
|
|
@ -1,25 +1,33 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Categories | Alex Daniels{% endblock %}
|
||||
{% block title %}{{title}} - Categories | Alex Daniels{% endblock %}
|
||||
|
||||
{% block metatitle %}{{title}} - Categories | Alex Daniels {% endblock %}
|
||||
{% block ogtitle %}{{title}} - Categories | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}Writing and Albums that contain the category '{{title}}'{% endblock %}
|
||||
{% block metadescription %}Writing and Albums that contain the category '{{title}}'{% endblock %}
|
||||
{% block ogdescription %}Writing and Albums that contain the category '{{title}}'{% endblock %}
|
||||
{% block twitterdescription %}Writing and Albums that contain the category '{{title}}'{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<section class="category">
|
||||
<h2>{{title}}</h2>
|
||||
{% if posts|length %}
|
||||
<div class="posts">
|
||||
<h2>Posts</h2>
|
||||
<h3>Posts</h3>
|
||||
<ul>
|
||||
{% for post in posts %}
|
||||
<li><a href="/words/{{post.url}}">{{post.title}}</a></li>
|
||||
<li><a href="/words/{{post.url}}">{{post.title}} - {{ post.date|date('l M d Y') }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if photos|length %}
|
||||
<div class="photos">
|
||||
<h2>Photos</h2>
|
||||
<h3>Photos</h3>
|
||||
<ul>
|
||||
{% for photo in photos %}
|
||||
<li><a href="/photos/{{photo.url}}">{{photo.title}}</a></li>
|
||||
<li><a href="/photos/{{photo.url}}">{{photo.title}} - {{ photo.date|date('l M d Y') }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
{% block title %}Categories | Alex Daniels{% endblock %}
|
||||
|
||||
{% block metatitle %}Categories | Alex Daniels {% endblock %}
|
||||
{% block ogtitle %}Categories | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}Categories used in posts and albums{% endblock %}
|
||||
{% block metadescription %}Categories used in posts and albums{% endblock %}
|
||||
{% block ogdescription %}Categories used in posts and albums{% endblock %}
|
||||
{% block twitterdescription %}Categories used in posts and albums{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<section class="categories">
|
||||
<h2>Categories</h2>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
{% block title %}{{page.title}} | Alex Daniels{% endblock %}
|
||||
|
||||
{% block metatitle %}{{page.title}} | Alex Daniels {% endblock %}
|
||||
{% block ogtitle %}{{page.title}} | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}{{page.title}} | Alex Daniels{% endblock %}
|
||||
{% block metadescription %}{{page.description }} {% endblock %}
|
||||
{% block ogdescription %}{{page.description }} {% endblock %}
|
||||
{% block twitterdescription %}{{page.description }} {% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<section class="page">
|
||||
<h2>{{page.title}}</h2>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
{% block title %}{{photos['title']}} - Photography | Alex Daniels{% endblock %}
|
||||
|
||||
{% block metatitle %}{{photos['title']}} | Alex Daniels {% endblock %}
|
||||
{% block ogtitle %}{{photos['title']}} | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}{{photos['title']}} | Alex Daniels{% endblock %}
|
||||
{% block metadescription %}{{photos['description']}} {% endblock %}
|
||||
{% block ogdescription %}{{photos['description']}} {% endblock %}
|
||||
{% block twitterdescription %}{{photos['description'] }} {% endblock %}
|
||||
{% block ogimage %}{{ photos['thumbnail']}}{% endblock %}
|
||||
{% block twitterimage %}{{ photos['thumbnail']}}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<article id="album">
|
||||
<h2 class="title">{{photos['title']}}</h2>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
{% block title %}Photography | Alex Daniels{% endblock %}
|
||||
|
||||
{% block metatitle %}Photography | Alex Daniels {% endblock %}
|
||||
{% block ogtitle %}Photography | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}Photography | Alex Daniels{% endblock %}
|
||||
{% block metadescription %}Photo Albums of things I find neat{% endblock %}
|
||||
{% block ogdescription %}Photo Albums of things I find neat{% endblock %}
|
||||
{% block twitterdescription %}Photo Albums of things I find neat{% endblock %}
|
||||
{# {% block ogimage %}{{ photos['thumbnail']}}{% endblock %}
|
||||
{% block twitterimage %}{{ photos['thumbnail']}}{% endblock %} #}
|
||||
|
||||
{% block body %}
|
||||
<h2>Photography</h2>
|
||||
<div class="photos">
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
{% block title %} {{post.title}} - Writing | Alex Daniels{% endblock %}
|
||||
|
||||
{% block metatitle %}{{post.title}} - Writing | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}{{post.title}} - Writing | Alex Daniels{% endblock %}
|
||||
{% block metadescription %}{{post.description }} {% endblock %}
|
||||
{% block ogdescription %}{{post.description }} {% endblock %}
|
||||
{% block twitterdescription %}{{post.description }} {% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<article class="post">
|
||||
<h2 class="title">{{post.title}}</h2>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
{% block title %}Writing | Alex Daniels{% endblock %}
|
||||
|
||||
{% block metatitle %}Writing | Alex Daniels {% endblock %}
|
||||
{% block ogtitle %}Writing | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}A truly random smattering of thoughts and feelings. Things may not always be relevant, but they will always be irreverant.{% endblock %}
|
||||
{% block metadescription %}A truly random smattering of thoughts and feelings. Things may not always be relevant, but they will always be irreverant.{% endblock %}
|
||||
{% block ogdescription %}A truly random smattering of thoughts and feelings. Things may not always be relevant, but they will always be irreverant.{% endblock %}
|
||||
{% block twitterdescription %}A truly random smattering of thoughts and feelings. Things may not always be relevant, but they will always be irreverant.{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<section class="posts">
|
||||
<h2>Writing</h2>
|
||||
|
|
|
|||
|
|
@ -1,25 +1,35 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Tags | Alex Daniels{% endblock %}
|
||||
{% block title %}{{title}} - Tags | Alex Daniels{% endblock %}
|
||||
|
||||
|
||||
{% block metatitle %}{{title}} - Tags | Alex Daniels {% endblock %}
|
||||
{% block ogtitle %}{{title}} - Tags | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}Writing and Albums that contain the tag '{{title}}'{% endblock %}
|
||||
{% block metadescription %}Writing and Albums that contain the tag '{{title}}'{% endblock %}
|
||||
{% block ogdescription %}Writing and Albums that contain the tag '{{title}}'{% endblock %}
|
||||
{% block twitterdescription %}Writing and Albums that contain the tag '{{title}}'{% endblock %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
<section class="tag">
|
||||
<h2>{{title}}</h2>
|
||||
{% if posts|length %}
|
||||
<div class="posts">
|
||||
<h2>Posts</h2>
|
||||
<h3>Posts</h3>
|
||||
<ul>
|
||||
{% for post in posts %}
|
||||
<li><a href="/words/{{post.url}}">{{post.title}}</a></li>
|
||||
<li><a href="/words/{{post.url}}">{{post.title}} - {{ post.date|date('l M d Y') }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if photos|length %}
|
||||
<div class="photos">
|
||||
<h2>Photos</h2>
|
||||
<h3>Photos</h3>
|
||||
<ul>
|
||||
{% for photo in photos %}
|
||||
<li><a href="/photos/{{photo.url}}">{{photo.title}}</a></li>
|
||||
<li><a href="/photos/{{photo.url}}">{{photo.title}} - {{ photo.date|date('l M d Y') }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
{% block title %}Tags | Alex Daniels{% endblock %}
|
||||
|
||||
{% block metatitle %}Tags | Alex Daniels {% endblock %}
|
||||
{% block ogtitle %}Tags | Alex Daniels {% endblock %}
|
||||
{% block twittertitle %}Tags used in posts and albums{% endblock %}
|
||||
{% block metadescription %}Tags used in posts and albums{% endblock %}
|
||||
{% block ogdescription %}Tags used in posts and albums{% endblock %}
|
||||
{% block twitterdescription %}Tags used in posts and albums{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<section class="tags">
|
||||
<h2>Tags</h2>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,24 @@
|
|||
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- Metatags -->
|
||||
<meta name="title" content="Alex Daniels" />
|
||||
<meta name="description" content="hello, i'm alex i'm a web developer based in portland, oregon in my free time i enjoy hiking, camping, reading, photography, and more. welcome to my little corner of the internet" />
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://alexdaniels.me" />
|
||||
<meta property="og:title" content="Alex Daniels" />
|
||||
<meta property="og:description" content="hello, i'm alex i'm a web developer based in portland, oregon in my free time i enjoy hiking, camping, reading, photography, and more. welcome to my little corner of the internet" />
|
||||
{# <meta property="og:image" content="https://metatags.io/images/meta-tags.png" /> #}
|
||||
|
||||
<!-- X (Twitter) -->
|
||||
<meta property="twitter:card" content="summary_large_image" />
|
||||
<meta property="twitter:url" content="https://alexdaniels.me" />
|
||||
<meta property="twitter:title" content="Alex Daniels" />
|
||||
<meta property="twitter:description" content="hello, i'm alex i'm a web developer based in portland, oregon in my free time i enjoy hiking, camping, reading, photography, and more. welcome to my little corner of the internet" />
|
||||
{# <meta property="twitter:image" content="https://metatags.io/images/meta-tags.png" /> #}
|
||||
|
||||
</head>
|
||||
<body class="home layout--v1 {{ app.user ? 'auth': '' }}">
|
||||
<header>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue