R3.2: Kontakt-/Ueber-uns-Routen zurueckgebaut, Spoke-Footer bereinigt
- GET kontakt/ueber-uns -> 301 auf die Ausgaben-Startseite; kontakt.store-POST bleibt fuer das Hub-Kontakt-Modal - Legacy-Aliases (contact/kontakt/ueber-uns) buendeln auf die Startseite - Spoke-Footer: Kontakt als mailto (Betreiber-Fallback bis R2.1), Ueber-uns-Link raus, Selfservice-Kuendigungslink ergaenzt - Sitemap-Konstanten bereinigt, Tests angepasst Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
73fc3827c8
commit
0645d1d855
6 changed files with 55 additions and 25 deletions
|
|
@ -16,21 +16,22 @@ use Illuminate\Support\Facades\Cache;
|
|||
* Host-aware XML-Sitemap: Der Hub listet Landing- und Rechts-/Info-Seiten,
|
||||
* die Spokes (presseecho, businessportal24) zusätzlich Kategorien, Newsrooms
|
||||
* und alle im Archiv sichtbaren Pressemitteilungen ihres Portals. Marketing-
|
||||
* Platzhalterseiten (team, presse, karriere, partner) und die Suche bleiben
|
||||
* bewusst draußen (R2.4/R3.2). Pro Host eine Stunde gecacht.
|
||||
* Platzhalterseiten (team, presse, karriere, partner, kontakt, ueber-uns)
|
||||
* und die Suche bleiben bewusst draußen (R2.4/R3.2). Pro Host eine Stunde
|
||||
* gecacht.
|
||||
*/
|
||||
class SitemapController extends Controller
|
||||
{
|
||||
/** @var list<string> */
|
||||
private const HUB_PAGES = [
|
||||
'faq', 'kontakt', 'ueber-uns', 'hilfe', 'api', 'kuendigung',
|
||||
'faq', 'hilfe', 'api', 'kuendigung',
|
||||
'impressum', 'datenschutz', 'agb', 'cookies',
|
||||
];
|
||||
|
||||
/** @var list<string> */
|
||||
private const PORTAL_PAGES = [
|
||||
'preise', 'veroeffentlichen', 'newsrooms', 'faq', 'kontakt',
|
||||
'ueber-uns', 'hilfe', 'api', 'impressum', 'datenschutz', 'agb', 'cookies',
|
||||
'preise', 'veroeffentlichen', 'newsrooms', 'faq',
|
||||
'hilfe', 'api', 'impressum', 'datenschutz', 'agb', 'cookies',
|
||||
];
|
||||
|
||||
public function __invoke(Request $request): Response
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
$brandAccent = $brand['accent'] ?? '';
|
||||
$brandTagline = $brand['tagline_short'] ?? 'Pressemitteilungen · DACH';
|
||||
$brandTaglineLong = $brand['tagline_long'] ?? 'Pressemitteilungen aus dem DACH-Raum.';
|
||||
$aboutLabel = $brand['about_label'] ?? ('Über '.$brandName.$brandAccent);
|
||||
// Betreiber-Postfach (adametz.media) als Fallback, bis die portal-
|
||||
// spezifischen CONTACT_EMAIL_*-Adressen gesetzt sind (R2.1).
|
||||
$contactEmail = $brand['contact_email'] ?? 'info@businessportal24.com';
|
||||
$legal = str_replace(':year', (string) now()->format('Y'), $brand['footer_legal'] ?? '© :year · Alle Rechte vorbehalten');
|
||||
@endphp
|
||||
|
||||
|
|
@ -59,10 +61,10 @@
|
|||
<div>
|
||||
<div class="eyebrow mb-3.5">Unternehmen</div>
|
||||
<ul class="space-y-2 text-[13px] text-white/75 list-none p-0 m-0">
|
||||
<li><a href="{{ route('ueber-uns') }}" class="cursor-pointer hover:text-white transition-colors">{{ $aboutLabel }}</a></li>
|
||||
<li><a href="{{ route('kontakt') }}" class="cursor-pointer hover:text-white transition-colors">Kontakt</a></li>
|
||||
<li><a href="mailto:{{ $contactEmail }}" class="cursor-pointer hover:text-white transition-colors">Kontakt</a></li>
|
||||
<li><a href="{{ route('faq') }}" class="cursor-pointer hover:text-white transition-colors">FAQ</a></li>
|
||||
<li><a href="{{ route('hilfe') }}" class="cursor-pointer hover:text-white transition-colors">Hilfe-Center</a></li>
|
||||
<li><a href="{{ route('kuendigung') }}" class="cursor-pointer hover:text-white transition-colors">Verträge hier kündigen</a></li>
|
||||
<li><a href="{{ route('impressum') }}" class="cursor-pointer hover:text-white transition-colors">Impressum</a></li>
|
||||
<li><a href="{{ route('datenschutz') }}" class="cursor-pointer hover:text-white transition-colors">Datenschutz</a></li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -118,22 +118,25 @@ $htmlRedirect = static function (string $edition, string $path) {
|
|||
}
|
||||
|
||||
// Legacy-Slugs des Altsystems (meist englisch) -> neue deutsche Pfade.
|
||||
// team/partner/karriere: Seiten wurden zurückgebaut (R3.2) -> Startseite.
|
||||
// team/partner/karriere/kontakt/ueber-uns: Seiten wurden zurückgebaut
|
||||
// (R3.2 bzw. Platzhalter-Inhalte) -> Startseite.
|
||||
$staticAliases = [
|
||||
'pricelist' => 'preise',
|
||||
'service' => 'veroeffentlichen',
|
||||
'contact' => 'kontakt',
|
||||
'contact' => '',
|
||||
'imprint' => 'impressum',
|
||||
'terms' => 'agb',
|
||||
'privacypolicy' => 'datenschutz',
|
||||
'team' => '',
|
||||
'partner' => '',
|
||||
'karriere' => '',
|
||||
'kontakt' => '',
|
||||
'ueber-uns' => '',
|
||||
];
|
||||
|
||||
// Bereits saubere Zielpfade der neuen Struktur (Pfad bleibt erhalten).
|
||||
$staticPages = [
|
||||
'preise', 'faq', 'kontakt', 'ueber-uns', 'veroeffentlichen',
|
||||
'preise', 'faq', 'veroeffentlichen',
|
||||
'suche', 'newsrooms', 'api',
|
||||
'hilfe', 'impressum', 'datenschutz', 'agb', 'cookies',
|
||||
];
|
||||
|
|
@ -194,13 +197,15 @@ Route::prefix('{edition}')->whereIn('edition', SetEdition::EDITIONS)->group(func
|
|||
// Preise / Tarife (datengetrieben: Plan + config/billing + config/credits)
|
||||
Route::get('preise', PreiseController::class)->name('preise');
|
||||
|
||||
// Statische Seiten
|
||||
// Statische Seiten. Kontakt- und Über-uns-Seite wurden zurückgebaut
|
||||
// (Platzhalter-Adresse/-Team); Alt-Links landen per 301 auf der Startseite.
|
||||
// Der Kontakt-POST bleibt für das Hub-Kontakt-Modal erhalten.
|
||||
Route::view('faq', 'web.faq')->name('faq');
|
||||
Route::view('kontakt', 'web.kontakt')->name('kontakt');
|
||||
Route::get('kontakt', fn (string $edition) => redirect(request()->getSchemeAndHttpHost().'/'.$edition, 301));
|
||||
Route::get('ueber-uns', fn (string $edition) => redirect(request()->getSchemeAndHttpHost().'/'.$edition, 301));
|
||||
Route::post('kontakt', ContactController::class)
|
||||
->middleware('throttle:10,1')
|
||||
->name('kontakt.store');
|
||||
Route::view('ueber-uns', 'web.ueber-uns')->name('ueber-uns');
|
||||
Route::get('veroeffentlichen', VeroeffentlichenController::class)->name('veroeffentlichen');
|
||||
Route::get('suche', SucheController::class)->name('suche');
|
||||
Route::get('newsrooms', NewsroomsController::class)->name('newsrooms');
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ use App\Mail\ContactRequestSubmitted;
|
|||
use Illuminate\Support\Facades\Mail;
|
||||
use Tests\TestCase;
|
||||
|
||||
test('the contact page renders the form', function () {
|
||||
test('the hub landing renders the contact modal form', function () {
|
||||
/** @var TestCase $this */
|
||||
$this->get('https://businessportal24.test/de/kontakt')
|
||||
// Die frühere Kontakt-Seite wurde zurückgebaut; das Formular lebt im
|
||||
// Kontakt-Modal des Hubs und postet weiter auf kontakt.store.
|
||||
$this->get('https://pressekonto.test/')
|
||||
->assertSuccessful()
|
||||
->assertSee('name="name"', false)
|
||||
->assertSee('name="email"', false)
|
||||
|
|
@ -19,13 +21,13 @@ test('a valid contact request sends a mail to the configured recipient', functio
|
|||
Mail::fake();
|
||||
config()->set('domains.domains.businessportal24.brand.contact_email', 'redaktion@businessportal24.de');
|
||||
|
||||
$this->from('https://businessportal24.test/de/kontakt')
|
||||
$this->from('https://businessportal24.test/de')
|
||||
->post('https://businessportal24.test/de/kontakt', [
|
||||
'name' => 'Paula Presse',
|
||||
'email' => 'paula@example.test',
|
||||
'message' => 'Ich habe eine Frage zu Ihrer Plattform und bitte um Rückruf.',
|
||||
])
|
||||
->assertRedirect('https://businessportal24.test/de/kontakt')
|
||||
->assertRedirect('https://businessportal24.test/de')
|
||||
->assertSessionHas('contact-status');
|
||||
|
||||
Mail::assertSent(ContactRequestSubmitted::class, function (ContactRequestSubmitted $mail) {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,24 @@ test('legacy static slugs of the old site redirect to the new german paths', fun
|
|||
})->with([
|
||||
'pricelist -> preise' => ['pricelist.html', 'preise'],
|
||||
'service -> veroeffentlichen' => ['service.html', 'veroeffentlichen'],
|
||||
'contact -> kontakt' => ['contact.html', 'kontakt'],
|
||||
'imprint -> impressum' => ['imprint.html', 'impressum'],
|
||||
'terms -> agb' => ['terms.html', 'agb'],
|
||||
'privacypolicy -> datenschutz' => ['privacypolicy.html', 'datenschutz'],
|
||||
]);
|
||||
|
||||
test('retired static pages redirect to the edition home', function (string $legacy) {
|
||||
/** @var TestCase $this */
|
||||
// kontakt/ueber-uns wurden zurückgebaut (Platzhalter-Inhalte); die
|
||||
// Alt-Slugs landen wie team/partner/karriere auf der Startseite.
|
||||
$this->get('https://businessportal24.test/de/'.$legacy)
|
||||
->assertStatus(301)
|
||||
->assertRedirect('https://businessportal24.test/de');
|
||||
})->with([
|
||||
'contact' => ['contact.html'],
|
||||
'kontakt' => ['kontakt.html'],
|
||||
'ueber-uns' => ['ueber-uns.html'],
|
||||
]);
|
||||
|
||||
test('legacy account urls redirect to the publisher hub', function (string $legacy, string $hubPath) {
|
||||
/** @var TestCase $this */
|
||||
$hubUrl = rtrim((string) config('domains.domain_portal_url'), '/');
|
||||
|
|
@ -104,9 +116,9 @@ test('dropped language/region variants redirect to the default edition', functio
|
|||
|
||||
test('legacy aliases also work without an edition prefix', function () {
|
||||
/** @var TestCase $this */
|
||||
$this->get('https://businessportal24.test/contact.html')
|
||||
$this->get('https://businessportal24.test/terms.html')
|
||||
->assertStatus(301)
|
||||
->assertRedirect('https://businessportal24.test/de/kontakt');
|
||||
->assertRedirect('https://businessportal24.test/de/agb');
|
||||
|
||||
$this->get('https://businessportal24.test/imprint.html')
|
||||
->assertStatus(301)
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@ dataset('static pages', [
|
|||
'cookies' => ['de/cookies', 'Cookie-Richtlinien'],
|
||||
'faq' => ['de/faq', 'Häufig gestellte Fragen'],
|
||||
'hilfe' => ['de/hilfe', 'Hilfe-Center'],
|
||||
'kontakt' => ['de/kontakt', 'Kontakt'],
|
||||
'ueber-uns' => ['de/ueber-uns', 'Über uns'],
|
||||
'api' => ['de/api', 'API & Integrationen'],
|
||||
'api' => ['de/api', 'API-Dokumentation'],
|
||||
]);
|
||||
|
||||
test('static pages render in the editorial design', function (string $path, string $heading) {
|
||||
|
|
@ -32,9 +30,19 @@ test('the faq page lists questions and links to support', function () {
|
|||
->assertSuccessful()
|
||||
->assertSeeText('Wie veröffentliche ich meine erste Pressemitteilung?')
|
||||
->assertSeeText('Frage nicht gefunden?')
|
||||
->assertSee(route('kontakt'), false);
|
||||
// Kontakt läuft nach dem Rückbau der Kontakt-Seite über das
|
||||
// Support-Postfach und die Kündigung über die eigene Seite.
|
||||
->assertSee('mailto:', false)
|
||||
->assertSee(route('kuendigung', ['edition' => 'de']), false);
|
||||
});
|
||||
|
||||
test('the retired contact and about pages redirect to the edition home', function (string $path) {
|
||||
/** @var TestCase $this */
|
||||
$this->get('https://businessportal24.test/de/'.$path)
|
||||
->assertStatus(301)
|
||||
->assertRedirect('https://businessportal24.test/de');
|
||||
})->with(['kontakt', 'ueber-uns']);
|
||||
|
||||
test('the help center shows quick links and topics', function () {
|
||||
/** @var TestCase $this */
|
||||
$this->get('https://businessportal24.test/de/hilfe')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue