diff --git a/.htaccess b/.htaccess
index 720af4d..5448097 100644
--- a/.htaccess
+++ b/.htaccess
@@ -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
diff --git a/data.json b/data.json
index 397ee7a..66fd74b 100644
--- a/data.json
+++ b/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."
}
]
}
\ No newline at end of file
diff --git a/index.php b/index.php
index daff932..bcc68eb 100644
--- a/index.php
+++ b/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'] ?? [];
+
+