SEO record links; story markets repair; story page titles
Kev's keyword CSV and TYPO3 hold the same solutions under slightly
different names, so the structure check filed them as missing/extra.
Matching is now slug -> normalized title -> record alias, using the
per-model alias store the import tabs got on 2026-08-18
(tx_vitec_import_mapping.record_aliases, key = lowercased CSV name).
One link therefore serves the import union list, the structure check
and vitec:create-markets (same service - linked rows are no longer
proposed as new records).
- every "Missing in TYPO3" row carries a select of all records the
direct match did not claim; "Save record links" persists per model
- alias-matched rows show under "Both" with a "linked" badge and the
same select; option 0 removes the link
- SeoResearchService::recordsCheck() additionally returns `linkable`
(the select options) and flags alias matches with via=link
- new backend POST route seo_aliases
Success stories: --markets-only repair mode
- /success-stories emitted empty `markets` for all 48 stories - a data
problem (code and TCA untouched since 17.08.); read-only diagnosis
script migrations/check_usecase_markets.php added
- vitec:import-success-stories --markets-only re-derives each story's
industries from the export exactly like the full import and rewrites
ONLY the markets MM relation of the existing record via DataHandler;
nothing else is touched, no usecase created or deleted, unresolved
stories keep their current relations
- decision: industries are translated onto the nine main markets of
the current taxonomy (INDUSTRY_TO_MARKET) instead of recreating the
seven deleted industry markets; the repair mode never creates
market records (root cause: those industry markets were deleted
after the 07.08. taxonomy import, orphaning all story relations)
- ensureMarkets() gained a $create flag for reuse by the full import
Story detail pages: real page title
- every story page answered with the generic page title "Story"; same
defect and same fix as the product pages on 21.08.: new
UsecasePageTitleProvider (singleton), registered as vitecUsecase in
config.pageTitleProviders, fed from UsecaseShowJsonRenderer with
seo_title falling back to title
Requires on the server:
vendor/bin/typo3 cache:flush
This commit is contained in:
1 parent
d846ba2007
commit
7442d10e68
9 files changed
+378
-9
No files matched your search
@@ -91,6 +91,10 @@
|
||||
sub-solutions. Products: level x.y and deeper (the top product rows are
|
||||
categories). Matching: record slug against the last URL segment, falling back
|
||||
to a normalized title comparison. The Page Ref column shows the hierarchy.
|
||||
A row the matcher misses can be <strong>linked by hand</strong> via its select
|
||||
— the link is stored per model (shared with the import tabs) and re-applied
|
||||
on every future delivery. Linked rows show up under "Both" with a badge
|
||||
and can be re-pointed or removed there.
|
||||
</p>
|
||||
|
||||
<div class="row">
|
||||
@@ -98,22 +102,52 @@
|
||||
<f:if condition="{area} != 'pages'">
|
||||
<div class="col-md-4">
|
||||
<h4 style="text-transform:capitalize;">{area}</h4>
|
||||
<form action="{f:be.uri(route: 'web_vitecimport.seo_aliases')}" method="post">
|
||||
<input type="hidden" name="model" value="{area}" />
|
||||
<f:if condition="{check.both}">
|
||||
<p><strong>Both in CSV and TYPO3 ({check.both -> f:count()})</strong></p>
|
||||
<ul>
|
||||
<f:for each="{check.both}" as="pair">
|
||||
<li><code>{pair.ref}</code> {pair.name} <small class="text-muted">→ uid {pair.uid} ({pair.title})</small></li>
|
||||
<f:for each="{check.both}" as="pair" iteration="bIt">
|
||||
<li>
|
||||
<code>{pair.ref}</code> {pair.name}
|
||||
<small class="text-muted">→ uid {pair.uid} ({pair.title})</small>
|
||||
<f:if condition="{pair.via} == 'link'">
|
||||
<span class="vitec-badge vitec-badge-info">linked</span>
|
||||
<input type="hidden" name="aliaskey[b{bIt.index}]" value="{pair.name}" />
|
||||
<select name="alias[b{bIt.index}]" class="form-select form-select-sm" style="margin:2px 0 6px;">
|
||||
<option value="0">— remove link —</option>
|
||||
<f:for each="{check.linkable}" as="rec">
|
||||
<option value="{rec.uid}" {f:if(condition: '{rec.uid} == {pair.uid}', then: 'selected')}>{rec.title} (uid {rec.uid})</option>
|
||||
</f:for>
|
||||
</select>
|
||||
</f:if>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</f:if>
|
||||
<f:if condition="{check.missing}">
|
||||
<p><strong>Missing in TYPO3 ({check.missing -> f:count()})</strong></p>
|
||||
<ul>
|
||||
<f:for each="{check.missing}" as="row">
|
||||
<li><code>{row.ref}</code> {row.name}</li>
|
||||
<f:for each="{check.missing}" as="row" iteration="mIt">
|
||||
<li>
|
||||
<code>{row.ref}</code> {row.name}
|
||||
<f:if condition="{check.linkable}">
|
||||
<input type="hidden" name="aliaskey[m{mIt.index}]" value="{row.name}" />
|
||||
<select name="alias[m{mIt.index}]" class="form-select form-select-sm" style="margin:2px 0 6px;">
|
||||
<option value="0">— really missing —</option>
|
||||
<f:for each="{check.linkable}" as="rec">
|
||||
<option value="{rec.uid}">{rec.title} (uid {rec.uid})</option>
|
||||
</f:for>
|
||||
</select>
|
||||
</f:if>
|
||||
</li>
|
||||
</f:for>
|
||||
</ul>
|
||||
</f:if>
|
||||
<f:if condition="{check.missing} || {check.both}">
|
||||
<p><button type="submit" class="btn btn-default btn-sm">Save record links</button></p>
|
||||
</f:if>
|
||||
</form>
|
||||
<f:if condition="{check.extra}">
|
||||
<p><strong>Only in TYPO3 ({check.extra -> f:count()})</strong></p>
|
||||
<ul>
|
||||
|
||||
Reference in new issue
Block a user