Diff -- /var/www/vhosts/3dshawn.com/ptmatrix.3dshawn.com/TEMPLATES/tf_admin_seo.html
Diff
/var/www/vhosts/3dshawn.com/ptmatrix.3dshawn.com/TEMPLATES/tf_admin_seo.html
added on local at 2026-07-01 12:34:50
Added
+148
lines
Removed
-0
lines
Context
0
unchanged
Blobs
from
to 5463f5f52cc7
to 5463f5f52cc7
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.| 1 | <!-- ===================================================================== | |
| 2 | Admin SEO -- platform-wide SEO + Open Graph + Twitter Card. | |
| 3 | Drives the meta tags on the PTMatrix marketing pages (landing, | |
| 4 | pricing, features, etc.) via MODS::PTMatrix::SEO + Wrapper. | |
| 5 | ===================================================================== --> | |
| 6 | ||
| 7 | <style> | |
| 8 | .tf-seo-grid { display:grid; grid-template-columns:minmax(0,1fr) 360px; gap:22px; align-items:flex-start; } | |
| 9 | @media (max-width: 980px) { .tf-seo-grid { grid-template-columns:1fr; } } | |
| 10 | ||
| 11 | .tf-seo-card { background: var(--col-surface); border:1px solid var(--col-border); border-radius: var(--radius-lg); padding:22px; } | |
| 12 | .tf-seo-form { display:grid; grid-template-columns: 1fr 1fr; gap:14px 16px; } | |
| 13 | .tf-seo-form .full { grid-column: 1/-1; } | |
| 14 | .tf-seo-form label { display:block; font-size:11px; letter-spacing:1px; text-transform:uppercase; color:var(--col-text-muted); font-weight:700; margin-bottom:6px; } | |
| 15 | .tf-seo-form input[type=text], | |
| 16 | .tf-seo-form textarea, | |
| 17 | .tf-seo-form select { width:100%; background:var(--col-bg-2); border:1px solid var(--col-border); border-radius:8px; color:var(--col-text); padding:10px 12px; font:13px/1.4 var(--font-body); outline:none; box-sizing:border-box; transition:border-color var(--t-fast); } | |
| 18 | .tf-seo-form input:focus, .tf-seo-form textarea:focus, .tf-seo-form select:focus { border-color: var(--col-primary); } | |
| 19 | .tf-seo-form textarea { min-height: 90px; resize: vertical; font-family: var(--font-body); } | |
| 20 | .tf-seo-form .hint { font-size:11px; color:var(--col-text-dim); margin-top:5px; line-height:1.4; } | |
| 21 | ||
| 22 | .tf-seo-form code { background:var(--col-bg-2); padding:1px 6px; border-radius:4px; color:var(--col-text); font-family: var(--font-mono); font-size:11px; } | |
| 23 | ||
| 24 | .tf-checkbox { display:inline-flex; align-items:center; gap:8px; color:var(--col-text); font-size:13px; font-weight:500; cursor:pointer; } | |
| 25 | .tf-checkbox input[type=checkbox] { width:16px; height:16px; accent-color: var(--col-primary); cursor:pointer; } | |
| 26 | ||
| 27 | .tf-seo-actions { display:flex; gap:10px; margin-top:18px; padding-top:18px; border-top:1px solid var(--col-border); } | |
| 28 | .tf-btn { display:inline-flex; align-items:center; gap:8px; padding:10px 18px; border-radius:8px; font:600 13px/1 var(--font-body); border:1px solid transparent; cursor:pointer; text-decoration:none; transition:transform var(--t-fast), background var(--t-fast); } | |
| 29 | .tf-btn-primary { background: var(--col-primary); color:#fff; } | |
| 30 | .tf-btn-primary:hover { background: var(--col-primary-2); } | |
| 31 | .tf-btn-secondary { background: var(--col-bg-3); color:var(--col-text); border-color: var(--col-border); } | |
| 32 | .tf-btn-secondary:hover { background: var(--col-bg-4); } | |
| 33 | ||
| 34 | .tf-seo-preview { background: var(--col-surface); border:1px solid var(--col-border); border-radius: var(--radius-lg); padding:18px; } | |
| 35 | .tf-seo-preview-head { font-size:10px; letter-spacing:1.5px; text-transform:uppercase; color:var(--col-text-muted); font-weight:700; margin-bottom:14px; } | |
| 36 | .tf-seo-preview-card { background: var(--col-bg-1); border:1px solid var(--col-border); border-radius:10px; padding:14px 16px; } | |
| 37 | .tf-seo-preview-url { font-size:11px; color: #4ade80; font-family: var(--font-mono); margin-bottom:4px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; } | |
| 38 | .tf-seo-preview-title { font-size:16px; color: var(--col-primary); font-weight:600; margin-bottom:4px; line-height:1.3; } | |
| 39 | .tf-seo-preview-desc { font-size:13px; color: var(--col-text-muted); line-height:1.45; } | |
| 40 | .tf-seo-preview-note { font-size:11px; color: var(--col-text-dim); margin-top:14px; line-height:1.5; } | |
| 41 | ||
| 42 | .tf-flash { padding:10px 14px; border-radius:8px; font-size:13px; font-weight:500; margin-bottom:14px; } | |
| 43 | .tf-flash.ok { background: var(--col-success-soft); color: #6ee7a7; border:1px solid var(--col-success); } | |
| 44 | ||
| 45 | .tf-page-head { margin-bottom: 22px; } | |
| 46 | .tf-page-eyebrow { display:inline-flex; align-items:center; gap:8px; font-size:11px; letter-spacing:1.5px; text-transform:uppercase; color: var(--col-text-muted); font-weight:700; margin-bottom:8px; } | |
| 47 | .tf-page-eyebrow .dot { width:8px; height:8px; border-radius:50%; background: var(--col-brand-2); box-shadow: 0 0 8px var(--col-brand-glow); } | |
| 48 | .tf-page-title { font-size:26px; font-weight:700; color:#fff; margin:0 0 6px; letter-spacing:-0.3px; } | |
| 49 | .tf-page-subtitle { font-size:14px; color: var(--col-text-muted); margin:0; max-width: 720px; line-height: 1.5; } | |
| 50 | ||
| 51 | .tf-warn-banner { background: var(--col-warn-soft); border:1px solid var(--col-warn); color: #fbbf24; padding:12px 16px; border-radius:8px; font-size:13px; margin-bottom:16px; } | |
| 52 | </style> | |
| 53 | ||
| 54 | <div class="tf-page-head"> | |
| 55 | <span class="tf-page-eyebrow"><span class="dot"></span> Admin · Platform SEO</span> | |
| 56 | <h1 class="tf-page-title">Platform SEO & social cards</h1> | |
| 57 | <p class="tf-page-subtitle">Set the title, description, keywords, and social-share defaults for the PTMatrix marketing pages (landing, pricing, features). These tags render in every page's <code><head></code> via the marketing wrapper.</p> | |
| 58 | </div> | |
| 59 | ||
| 60 | [if:$has_flash] | |
| 61 | <div class="tf-flash $flash_kind">$flash_msg</div> | |
| 62 | [/if] | |
| 63 | ||
| 64 | [if:$schema_missing] | |
| 65 | <div class="tf-warn-banner"><strong>platform_settings table not yet installed.</strong> Run the latest <code>db_schema.sql</code> or <code>_traffic_seo_migration.sql</code> against the database.</div> | |
| 66 | [/if] | |
| 67 | ||
| 68 | [if:$schema_ready] | |
| 69 | <div class="tf-seo-grid"> | |
| 70 | <form method="POST" action="/admin_seo.cgi" class="tf-seo-card"> | |
| 71 | <input type="hidden" name="act" value="save"> | |
| 72 | <div class="tf-seo-form"> | |
| 73 | ||
| 74 | <div class="full"> | |
| 75 | <label>Default page title</label> | |
| 76 | <input type="text" name="seo_title" maxlength="160" value="$seo_title" placeholder="PTMatrix - Project management for teams that ship"> | |
| 77 | <div class="hint">Used as the default <code><title></code> + <code>og:title</code> on every marketing page.</div> | |
| 78 | </div> | |
| 79 | ||
| 80 | <div class="full"> | |
| 81 | <label>Default meta description</label> | |
| 82 | <textarea name="seo_description" maxlength="320">$seo_description</textarea> | |
| 83 | <div class="hint">~150–160 characters. Should state clearly what PTMatrix is and who it is for.</div> | |
| 84 | </div> | |
| 85 | ||
| 86 | <div class="full"> | |
| 87 | <label>Default keywords</label> | |
| 88 | <input type="text" name="seo_keywords" maxlength="255" value="$seo_keywords" placeholder="project management, kanban, gantt, time tracking"> | |
| 89 | <div class="hint">Comma-separated.</div> | |
| 90 | </div> | |
| 91 | ||
| 92 | <div> | |
| 93 | <label>Canonical base URL</label> | |
| 94 | <input type="text" name="seo_canonical_base" maxlength="255" value="$seo_canonical_base" placeholder="https://ptmatrix.3dshawn.com"> | |
| 95 | <div class="hint">Production root URL. Used to build absolute canonical links and absolute OG image URLs.</div> | |
| 96 | </div> | |
| 97 | ||
| 98 | <div> | |
| 99 | <label>Allow search engines to index PTMatrix</label> | |
| 100 | <label class="tf-checkbox"><input type="checkbox" name="seo_robots_index" value="1"[if:$is_robots_on] checked[/if]> Show in Google, Bing, etc.</label> | |
| 101 | <div class="hint">Untick to emit <code>noindex, nofollow</code> on every page.</div> | |
| 102 | </div> | |
| 103 | ||
| 104 | <div class="full"> | |
| 105 | <label>Default social share image</label> | |
| 106 | <input type="text" name="seo_og_image" maxlength="255" value="$seo_og_image" placeholder="/Logo.png"> | |
| 107 | <div class="hint">Shown when PTMatrix URLs are pasted into Slack, Discord, X, iMessage, etc. 1200×630 PNG/JPG. Relative paths get prefixed with the canonical base.</div> | |
| 108 | </div> | |
| 109 | ||
| 110 | <div> | |
| 111 | <label>Open Graph site name</label> | |
| 112 | <input type="text" name="seo_og_site_name" maxlength="120" value="$seo_og_site_name" placeholder="PTMatrix"> | |
| 113 | </div> | |
| 114 | ||
| 115 | <div> | |
| 116 | <label>Twitter / X card style</label> | |
| 117 | <select name="seo_twitter_card"> | |
| 118 | <option value="summary_large_image"[if:$is_card_large] selected[/if]>Large image (recommended)</option> | |
| 119 | <option value="summary"[if:$is_card_summary] selected[/if]>Compact summary</option> | |
| 120 | </select> | |
| 121 | </div> | |
| 122 | ||
| 123 | <div> | |
| 124 | <label>Platform Twitter / X handle</label> | |
| 125 | <input type="text" name="seo_twitter_site" maxlength="64" value="$seo_twitter_site" placeholder="@taskforge"> | |
| 126 | <div class="hint">Adds attribution when shared on X.</div> | |
| 127 | </div> | |
| 128 | </div> | |
| 129 | ||
| 130 | <div class="tf-seo-actions"> | |
| 131 | <button type="submit" class="tf-btn tf-btn-primary">Save platform SEO</button> | |
| 132 | <a href="/admin_metrics.cgi" class="tf-btn tf-btn-secondary">Back to admin</a> | |
| 133 | </div> | |
| 134 | </form> | |
| 135 | ||
| 136 | <aside class="tf-seo-preview"> | |
| 137 | <div class="tf-seo-preview-head">Search preview</div> | |
| 138 | <div class="tf-seo-preview-card"> | |
| 139 | <div class="tf-seo-preview-url">$preview_url</div> | |
| 140 | <div class="tf-seo-preview-title">$preview_title</div> | |
| 141 | <div class="tf-seo-preview-desc">$preview_desc</div> | |
| 142 | </div> | |
| 143 | <div class="tf-seo-preview-note"> | |
| 144 | These defaults apply to every page that does not set its own. Once a marketing page wants a custom title, pass <code>page_title</code> into the Wrapper when rendering it. | |
| 145 | </div> | |
| 146 | </aside> | |
| 147 | </div> | |
| 148 | [/if] |