Fixup machine endpoints
This commit is contained in:
parent
4cb4b645ef
commit
86b20b2ce5
@ -31,6 +31,9 @@ RewriteRule ^domains/[^/]+/(.+[^/])$ /$1/ [R]
|
||||
RewriteCond %{REQUEST_FILENAME} -d
|
||||
RewriteRule ^subdom/[^/]+/(.+[^/])$ /$1/ [R]
|
||||
|
||||
# Route /api/data.json and /llms.txt to index.php for machine-readable data
|
||||
RewriteRule ^(api/data\.json|llms\.txt)$ index.php [L,QSA]
|
||||
|
||||
# Route /cv to index.php for CV view
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
|
||||
18
data.json
18
data.json
@ -9,7 +9,7 @@
|
||||
"contact_links": {
|
||||
"Website": "https://www.dejvino.cz",
|
||||
"Email": "mailto:explosive@dejvino.cz",
|
||||
"Resume": "https://dejvino.cz/cv"
|
||||
"Resume": "https://www.dejvino.cz/cv"
|
||||
},
|
||||
"about": [
|
||||
"Principal Software Engineer at Oracle NetSuite, focusing on AI-assisted developer enablement, UI platform architecture, performance, and observability for 40k+ enterprise customers."
|
||||
@ -153,33 +153,27 @@
|
||||
"interests": [
|
||||
{
|
||||
"name": "Mandolin",
|
||||
"caption": "Octave mandolin is my instrument of choice. Wide range of tones, pleasant sound. Great way to relax your mind, explore melodies and harmonies.",
|
||||
"image": null
|
||||
"caption": "Octave mandolin is my instrument of choice. Wide range of tones, pleasant sound. Great way to relax your mind, explore melodies and harmonies."
|
||||
},
|
||||
{
|
||||
"name": "Electronics tinkering",
|
||||
"caption": "Building a useful device from scratch. Retrofitting modern brains into a broken vintage shell. Electronics is the magic that makes things alive.",
|
||||
"image": null
|
||||
"caption": "Building a useful device from scratch. Retrofitting modern brains into a broken vintage shell. Electronics is the magic that makes things alive."
|
||||
},
|
||||
{
|
||||
"name": "Synthwave",
|
||||
"caption": "Neon-filled nostalgia. Fun to create, relaxing to listen to it.",
|
||||
"image": "interests/synthwave.png"
|
||||
},
|
||||
{
|
||||
"name": "3D Printing & Design",
|
||||
"caption": "Designing and printing custom parts that serve a purpose. Unique designs, useful accessories, toys or just repairs.",
|
||||
"image": null
|
||||
"caption": "Designing and printing custom parts that serve a purpose. Unique designs, useful accessories, toys or just repairs."
|
||||
},
|
||||
{
|
||||
"name": "Mountain Biking",
|
||||
"caption": "Going places under your own power. Exploring forests, trails and nature where cars aren't allowed.",
|
||||
"image": null
|
||||
"caption": "Going places under your own power. Exploring forests, trails and nature where cars aren't allowed."
|
||||
},
|
||||
{
|
||||
"name": "RC Cars",
|
||||
"caption": "Rock crawlers, construction trucks, military vehicles. Building a custom offroad course in the garden to trial them all.",
|
||||
"image": null
|
||||
"caption": "Rock crawlers, construction trucks, military vehicles. Building a custom offroad course in the garden to trial them all."
|
||||
}
|
||||
]
|
||||
}
|
||||
94
index.php
94
index.php
@ -40,13 +40,6 @@ $site_url = "https://www.dejvino.cz/";
|
||||
$site_title = $name;
|
||||
$site_desc = "$name - $headline";
|
||||
|
||||
$mailto_link = $cvData['contact_links']['Email'] ?? '';
|
||||
if (preg_match('/mailto:([^@]+)/', $mailto_link, $m)) {
|
||||
$email_user = $m[1];
|
||||
} else {
|
||||
$email_user = $cvData['email'] ?? '';
|
||||
}
|
||||
|
||||
$extra_contact_links = $cvData['contact_links'] ?? [];
|
||||
|
||||
/**
|
||||
@ -65,6 +58,39 @@ $pill_icons = [
|
||||
'GitHub' => '🐙',
|
||||
];
|
||||
|
||||
/** MACHINE READABLE ENDPOINTS */
|
||||
$parsedUrl = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||
if (in_array($parsedUrl, ['/api/data.json', '/api/data.json/'], true)) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
readfile(__DIR__ . '/data.json');
|
||||
exit;
|
||||
}
|
||||
if (in_array($parsedUrl, ['/llms.txt', '/llms.txt/'], true)) {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo '# ' . $site_url . PHP_EOL;
|
||||
echo '> ' . $name . ' — ' . $headline . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
echo $summary . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
echo '## Machine-readable data' . PHP_EOL;
|
||||
echo '- JSON: ' . $site_url . 'api/data.json' . PHP_EOL;
|
||||
echo PHP_EOL;
|
||||
echo '## Links' . PHP_EOL;
|
||||
foreach ($nav_links as $label => $href) {
|
||||
echo '- ' . $label . ': ' . $href . PHP_EOL;
|
||||
}
|
||||
if (!empty($cvData['contact_links'])) {
|
||||
echo PHP_EOL;
|
||||
echo '## Contact' . PHP_EOL;
|
||||
foreach ($cvData['contact_links'] as $label => $href) {
|
||||
echo '- ' . $label . ': ' . $href . PHP_EOL;
|
||||
}
|
||||
}
|
||||
exit;
|
||||
}
|
||||
/** END OF MACHINE READABLE ENDPOINTS */
|
||||
|
||||
/**
|
||||
* Extract a readable URL from a href (strip protocol, trailing slash)
|
||||
*/
|
||||
@ -142,6 +168,51 @@ $cv_education = array_map(function ($e) {
|
||||
// Keep skills categories as provided
|
||||
$cv_skills = $cvData['cv']['skills'] ?? [];
|
||||
|
||||
// JSON-LD structured data for machine readability (AI crawlers, schema.org)
|
||||
$jsonLd = [
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'Person',
|
||||
'name' => $name,
|
||||
'jobTitle' => $headline,
|
||||
'description' => $summary,
|
||||
'url' => $site_url,
|
||||
'email' => $cvData['email'] ?? '',
|
||||
'telephone' => $cvData['phone'] ?? '',
|
||||
'image' => $site_url . $photo_file,
|
||||
'address' => [
|
||||
'@type' => 'PostalAddress',
|
||||
'addressLocality' => $location,
|
||||
],
|
||||
'sameAs' => array_values($nav_links),
|
||||
'knowsAbout' => [],
|
||||
'alumniOf' => [],
|
||||
'worksFor' => [],
|
||||
];
|
||||
foreach ($cvData['cv']['skills'] ?? [] as $category => $skills) {
|
||||
$jsonLd['knowsAbout'] = array_merge($jsonLd['knowsAbout'], $skills);
|
||||
}
|
||||
foreach ($cvData['interests'] ?? [] as $interest) {
|
||||
$jsonLd['knowsAbout'][] = $interest['name'] ?? '';
|
||||
}
|
||||
$firstExp = $cvData['cv']['experience'][0] ?? null;
|
||||
if ($firstExp) {
|
||||
$jsonLd['worksFor'] = [
|
||||
'@type' => 'Organization',
|
||||
'name' => str_replace('|', ' / ', $firstExp['company'] ?? ''),
|
||||
'description' => $firstExp['title'] ?? '',
|
||||
];
|
||||
} else {
|
||||
unset($jsonLd['worksFor']);
|
||||
}
|
||||
foreach ($cvData['cv']['education'] ?? [] as $edu) {
|
||||
$jsonLd['alumniOf'][] = [
|
||||
'@type' => 'CollegeOrUniversity',
|
||||
'name' => $edu['institution'] ?? '',
|
||||
'description' => ($edu['degree'] ?? '') . ($edu['field'] ? ' in ' . $edu['field'] : ''),
|
||||
];
|
||||
}
|
||||
$jsonLdEncoded = json_encode($jsonLd, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
|
||||
/**
|
||||
* Page design:
|
||||
* - clean and simple, human-maintainable
|
||||
@ -166,6 +237,8 @@ $cv_skills = $cvData['cv']['skills'] ?? [];
|
||||
<meta property="og:title" content="<?= $name ?>">
|
||||
<meta property="og:description" content="<?= $headline ?>">
|
||||
|
||||
<script type="application/ld+json"><?= $jsonLdEncoded ?></script>
|
||||
|
||||
<style>
|
||||
<?php
|
||||
include 'style.css';
|
||||
@ -322,13 +395,6 @@ $cv_skills = $cvData['cv']['skills'] ?? [];
|
||||
<?php endif; ?>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
((u, d, t) => {
|
||||
const addr = (atob(u) + '@' + d + '.' + t).trim();
|
||||
const el = document.getElementById("contact-mail");
|
||||
if (el) el.innerHTML = `<a href="mailto:${addr}">${addr}</a>`;
|
||||
})('<?= base64_encode($email_user) ?>', 'dejvino', 'cz');
|
||||
</script>
|
||||
<!-- Cloudflare Web Analytics -->
|
||||
<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "90827cb740cd4b1db611be059f64daa9"}'></script><!-- End Cloudflare Web Analytics -->
|
||||
<?php $file_mod_time = filemtime(__FILE__); ?>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user