feat: set up migration to quarto

This commit is contained in:
2026-01-08 03:57:13 +02:00
parent 8c127289c7
commit a907728269
24 changed files with 1151 additions and 0 deletions

4
.gitignore vendored
View File

@@ -9,3 +9,7 @@ hugo.darwin
.DS_Store
.vscode/
# Quarto
/.quarto/
/_site/

66
MIGRATION-CHECKLIST.md Normal file
View File

@@ -0,0 +1,66 @@
# Migration Checklist
## 📋 Content Migration
### Blog Posts (8 total)
- [ ] `dataviz-blogs.md``posts/dataviz-blogs/index.qmd` (lang: uk)
- [ ] `dataviz-books-ua.md``posts/dataviz-books-ua/index.qmd` (lang: uk)
- [ ] `entso-e-ukraine-energy-transfer-viz.md``posts/entso-e-ukraine-energy-transfer-viz/index.qmd` (lang: uk, **showcase**)
- [ ] `forbes-50-foundations.md``posts/forbes-50-foundations/index.qmd` (lang: uk, **showcase**)
- [ ] `my-first-post.md``posts/my-first-post/index.qmd` (lang: uk)
- [ ] `vega-altair-hugo-shortcodes.md``posts/vega-altair-hugo-shortcodes/index.qmd` (lang: uk, **showcase**)
- [ ] `bar-charts-makeover.md` (English) → `posts/bar-charts-makeover/index.qmd` (lang: en, **showcase**)
- [ ] Convert all Vega-Lite shortcodes to code fences
### TILs (2 total)
- [ ] `inspired-by-blogs.md``til/inspired-by-blogs.qmd` (lang: uk)
- [ ] `obsidian-paperless.md``til/obsidian-paperless.qmd` (lang: uk)
## 🎨 Customization
- [ ] Update `about/index.qmd` with your actual bio
- [ ] Add contact information to About page
- [ ] Add any real projects to `projects/` section
- [ ] Customize homepage (`index.qmd`) if desired
- [ ] Review and adjust theme colors in `styles.css` if needed
## 🧹 Cleanup
- [ ] Delete `posts/sample-ukrainian-post/`
- [ ] Delete `posts/sample-english-post/`
- [ ] Delete `posts/sample-visualization-post/`
- [ ] Delete `til/sample-til-ukrainian.qmd`
- [ ] Delete `til/sample-til-english.qmd`
- [ ] Delete `projects/sample-project-1/`
## ✅ Testing
- [ ] Run `quarto preview` and check all pages
- [ ] Verify all blog posts render correctly
- [ ] Verify all TILs render correctly
- [ ] Check all Vega-Lite visualizations display properly
- [ ] Test portfolio page shows showcase items
- [ ] Test navigation between all sections
- [ ] Check responsive design on mobile
- [ ] Verify analytics scripts load (check browser console)
## 🚀 Deployment
- [ ] Run `quarto render` successfully
- [ ] Check build output in `_site/`
- [ ] Test old `/en/*` URL redirects
- [ ] Deploy `_site/` to hosting
- [ ] Verify production site works correctly
- [ ] Update DNS if needed
## 🗑️ Final Cleanup (After Successful Deployment)
- [ ] Archive or delete Hugo `content/` directory
- [ ] Delete `archetypes/`, `layouts/`, `themes/`
- [ ] Delete `hugo.yaml`
- [ ] Delete `public/`, `resources/`
- [ ] Keep `.git/` and version control as-is
---
**Tip:** Test with one post first to validate the workflow before batch-migrating everything!

250
MIGRATION-README.md Normal file
View File

@@ -0,0 +1,250 @@
# Hugo to Quarto Migration Guide
## ✅ Migration Status: Infrastructure Complete
The Quarto site infrastructure is now fully set up! The site builds successfully and is ready for content migration.
## 🏗️ What's Been Created
### Configuration
- `_quarto.yml` - Main site configuration with navbar, footer, analytics, **Vega-Lite filter**
- `vega-lite.lua` - **Lua filter for Vega-Lite support** (Quarto doesn't have native support)
- `styles.css` - Minimal custom styling (Vega chart centering)
- `_includes/analytics.html` - Plausible + Matomo analytics
- `_redirects` - URL redirects for old `/en/*` paths
- `.gitignore` - Updated with Quarto-specific entries
### Directory Structure
```
├── posts/ # Blog posts (3 sample placeholders)
├── til/ # TILs (2 sample placeholders)
├── portfolio/ # Portfolio listing page
├── projects/ # Projects section (1 sample project)
├── about/ # About page template
└── index.qmd # Homepage
```
### Sample Content (Placeholders)
- `posts/sample-ukrainian-post/` - Example Ukrainian post structure
- `posts/sample-english-post/` - Example English post structure
- `posts/sample-visualization-post/` - Example with Vega-Lite chart
- `til/sample-til-ukrainian.qmd` - Example Ukrainian TIL
- `til/sample-til-english.qmd` - Example English TIL
- `projects/sample-project-1/` - Example full project page
## 📝 Manual Migration Steps
### 1. Migrate Blog Posts (8 posts)
For each Hugo post in `content/posts/` and `content/en/posts/`:
1. **Create directory:** `posts/{post-slug}/`
2. **Convert file:** Copy `.md``index.qmd` in the new directory
3. **Update frontmatter:**
```yaml
---
title: "Your Title"
date: "YYYY-MM-DD"
lang: uk # or 'en' for English posts
categories:
- dataviz
- showcase # Add this for portfolio items!
description: "Brief description"
---
```
4. **Convert Vega-Lite shortcodes:**
- Remove: `{{</* vega-lite id="..." */>}}...{{</* /vega-lite */>}}`
- Replace with:
````markdown
```{vega-lite}
{your vega spec here}
```
````
- See `VEGA-LITE-SETUP.md` for detailed instructions
**Posts to migrate:**
- `content/posts/dataviz-blogs.md` → `posts/dataviz-blogs/index.qmd`
- `content/posts/dataviz-books-ua.md` → `posts/dataviz-books-ua/index.qmd`
- `content/posts/entso-e-ukraine-energy-transfer-viz.md` → `posts/entso-e-ukraine-energy-transfer-viz/index.qmd`
- `content/posts/forbes-50-foundations.md` → `posts/forbes-50-foundations/index.qmd` **(add 'showcase' category)**
- `content/posts/my-first-post.md` → `posts/my-first-post/index.qmd`
- `content/posts/vega-altair-hugo-shortcodes.md` → `posts/vega-altair-hugo-shortcodes/index.qmd` **(add 'showcase' category)**
- `content/en/posts/bar-charts-makeover.md` → `posts/bar-charts-makeover/index.qmd` **(add 'showcase' category, lang: en)**
### 2. Migrate TILs (2 posts)
For each Hugo TIL in `content/til/`:
1. **Convert file:** Copy `.md` → `.qmd` directly in `til/` folder
2. **Update frontmatter:**
```yaml
---
title: "Your Title"
date: "YYYY-MM-DD"
lang: uk
categories:
- tools
---
```
**TILs to migrate:**
- `content/til/inspired-by-blogs.md` → `til/inspired-by-blogs.qmd`
- `content/til/obsidian-paperless.md` → `til/obsidian-paperless.qmd`
### 3. Posts/TILs Auto-Discovery
✅ **Good news!** The listing pages automatically discover new posts and TILs:
- **Posts:** Any directory with `index.qmd` in `posts/` appears automatically
- **TILs:** Any `.qmd` file in `til/` appears automatically
- **No manual updates needed!** Just add your files and they'll show up
### 4. Update Portfolio Page
The portfolio page needs manual updates. Edit `portfolio/index.qmd` and add your showcase posts:
```markdown
::: {.g-col-12 .g-col-md-6}
### [Forbes Top-50 Foundations](../posts/forbes-50-foundations/)
Interactive visualization of Ukraine's top charitable foundations
:::
::: {.g-col-12 .g-col-md-6}
### [Bar Charts Makeover](../posts/bar-charts-makeover/)
Seven ways to visualize year-over-year growth
:::
```
### 5. Delete Sample Placeholders
After migrating and updating listings, delete these placeholder files:
```bash
rm -rf posts/sample-*
rm til/sample-*
rm -rf projects/sample-project-1
```
### 6. Customize About Page
Edit `about/index.qmd` and replace template content with:
- Your bio
- Skills and expertise
- Contact information
- Links to social profiles
### 7. Add Real Projects
Option A: Full project page
```bash
mkdir projects/your-project-name
# Create projects/your-project-name/index.qmd
```
Option B: Just list in `projects/index.qmd`
## 🔧 Key Technical Details
### Language Tags
Use `lang: uk` or `lang: en` in frontmatter to tag content language. This allows filtering by language if needed.
### Portfolio Items
Add `showcase` to the categories list for any post you want in your portfolio:
```yaml
categories:
- dataviz
- showcase # This makes it appear in portfolio
```
### Vega-Lite Visualizations
Enabled via `vega-lite.lua` filter (already configured). Use:
````markdown
```{vega-lite}
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"mark": "bar",
...
}
```
````
Optional attributes:
- `#| echo: false` - Hide code, show only visualization
- `#| code-fold: true` - Make code collapsible
See `VEGA-LITE-SETUP.md` for complete documentation.
## 🚀 Building & Previewing
### Local Preview
```bash
quarto preview
```
Opens at `http://localhost:4848`
### Build Site
```bash
quarto render
```
Output goes to `_site/`
### Check for Errors
```bash
quarto check
```
## 📂 What to Keep vs Delete
### Keep (Quarto):
- All `*.qmd` files
- `_quarto.yml`
- `styles.css`
- `_includes/`
- `_redirects`
- `_site/` (build output)
### Can Eventually Delete (Hugo):
- `archetypes/`
- `content/` (after migrating to `posts/` and `til/`)
- `data/`
- `i18n/`
- `layouts/`
- `public/`
- `resources/`
- `static/`
- `templates/`
- `themes/`
- `hugo.yaml`
**Don't delete Hugo files yet!** Wait until you've confirmed the Quarto migration is complete and deployed.
## 🌐 Deployment
1. Build: `quarto render`
2. Deploy `_site/` directory to your hosting
3. Ensure `_redirects` file is included for old URL support
## 📌 Important Notes
- **URL Preservation:** Old `/en/posts/*` URLs will redirect to `/posts/*` via `_redirects`
- **Analytics:** Already integrated (Plausible + Matomo)
- **No Language Duplication:** All posts in one location, tagged with `lang` field
- **Sample Content:** Delete all `sample-*` files after migrating real content
## ✨ Benefits You'll Gain
1. ✅ Vega-Lite support via Lua filter (cleaner than Hugo shortcodes)
2. ✅ Can add Python/R code that generates visualizations
3. ✅ Observable JS for interactive dashboards
4. ✅ Better data analysis workflows
5. ✅ Single source of truth (no language directory duplication)
6. ✅ Cleaner, more maintainable structure
## 📚 Additional Documentation
- **`VEGA-LITE-SETUP.md`** - Complete guide to Vega-Lite filter and usage
- **`QUICK-START.md`** - How to use Quarto, add posts, common commands
- **`MIGRATION-CHECKLIST.md`** - Checkbox list to track migration progress
---
**Ready to migrate!** Start with one post to test the workflow, then batch-migrate the rest.

132
QUICK-START.md Normal file
View File

@@ -0,0 +1,132 @@
# Quick Start Guide
## ✅ Setup is Complete!
The Quarto site infrastructure is ready. Here's how to work with it:
## 🚀 Preview the Site
```bash
quarto preview
```
Opens at http://localhost:4848 with live reload.
## 🎨 Theme & Styling
- **Theme:** Cosmo (clean, minimal Bootstrap theme)
- **Custom CSS:** `styles.css` (minimal - just Vega chart centering)
- To change theme, edit `_quarto.yml` and try: cosmo, flatly, litera, minty, etc.
## 📝 Adding Your First Real Post
1. **Create post directory:**
```bash
mkdir posts/your-post-slug
```
2. **Create `posts/your-post-slug/index.qmd`:**
```yaml
---
title: "Your Post Title"
date: "2024-03-15"
lang: uk # or 'en'
categories:
- dataviz
- showcase # Include for portfolio items
description: "Brief description"
---
Your content here...
```
3. **Preview changes** (posts auto-discovered!):
```bash
quarto preview
```
✅ Your new post will automatically appear in the listing - no manual updates needed!
## 📊 Using Vega-Lite Visualizations
**Important:** This project uses `vega-lite.lua` filter for Vega-Lite support.
**Hugo shortcode (OLD):**
```markdown
{{</* vega-lite id="chart1" */>}}
{vega spec}
{{</* /vega-lite */>}}
```
**Quarto with Lua filter (NEW):**
````markdown
```{vega-lite}
{vega spec}
```
````
**With options:**
````markdown
```{vega-lite}
#| echo: false
#| code-fold: true
{vega spec}
```
````
See **`VEGA-LITE-SETUP.md`** for complete documentation and examples.
## 🔧 Common Commands
```bash
# Preview with live reload
quarto preview
# Build the site
quarto render
# Check for issues
quarto check
# Clean build cache
quarto clean
```
## 📂 Where Things Go
- **Blog posts:** `posts/post-slug/index.qmd`
- **TILs:** `til/post-name.qmd`
- **Projects:** `projects/project-name/index.qmd` (or just list in `projects/index.qmd`)
- **About page:** `about/index.qmd`
- **Homepage:** `index.qmd`
## ⚠️ Important Notes
1. **Use `lang: uk` or `lang: en`** (not `language:` - that's reserved by Quarto)
2. **Update listing pages** when you add real content (see MIGRATION-README.md)
3. **Posts with `showcase` category** automatically appear in portfolio
4. **Delete sample files** after migrating your real content
## 🆘 Troubleshooting
**Error: "list needs to have at least one item"**
- Update the listing `contents:` in the index page to reference actual files/directories
**Vega chart not showing:**
- Check the JSON is valid
- Ensure you're using ````{vega-lite}` code fence (not `{json}`)
- Check browser console for errors
**Styles look wrong:**
- Run `quarto clean && quarto render` to rebuild from scratch
- Check `styles.css` hasn't been corrupted
## 📚 Next Steps
1. Test by migrating one post from Hugo
2. Verify it displays correctly
3. Batch migrate the rest
4. Update all listing pages
5. Delete sample placeholders
6. Deploy!
See `MIGRATION-README.md` for detailed migration instructions.

181
VEGA-LITE-SETUP.md Normal file
View File

@@ -0,0 +1,181 @@
# Vega-Lite Setup with Quarto
## Important: Vega-Lite Lua Filter Required
**Quarto does NOT have native Vega-Lite support out of the box.** This project uses `vega-lite.lua` - a Quarto filter that enables Vega-Lite visualization rendering.
## ✅ What's Already Configured
1. **`vega-lite.lua`** - Custom Lua filter that processes Vega-Lite code blocks
2. **`_quarto.yml`** - Already configured to use the filter:
```yaml
filters:
- vega-lite.lua
```
## 🎨 How to Use Vega-Lite in Your Posts
### Basic Usage
````markdown
```{vega-lite}
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": [
{"category": "A", "value": 28},
{"category": "B", "value": 55}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "category", "type": "nominal"},
"y": {"field": "value", "type": "quantitative"}
}
}
```
````
### With Options
````markdown
```{vega-lite}
#| echo: false
#| code-fold: true
{your vega spec}
```
````
**Supported options:**
- `echo: false` - Hide the code, show only the visualization
- `echo: true` - Show both code and visualization (default)
- `code-fold: true` - Make code collapsible (collapsed by default)
- `code-fold: show` - Make code collapsible but open by default
## 🔧 How the Filter Works
The `vega-lite.lua` filter:
1. **Detects** code blocks with class `vega-lite`
2. **Includes** Vega libraries (Vega, Vega-Lite, Vega-Embed) from CDN
3. **Renders** the specification using `vegaEmbed()` JavaScript
4. **Handles** code display options (echo, code-fold)
### Libraries Loaded
- `vega@5` - Core Vega library
- `vega-lite@5` - Vega-Lite library
- `vega-embed@6` - Embedding library
## 📝 Migrating from Hugo Shortcodes
**Hugo shortcode (OLD):**
```markdown
{{</* vega-lite id="chart-bar-in-bar" actions="true" */>}}
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"mark": "bar",
...
}
{{</* /vega-lite */>}}
```
**Quarto with Lua filter (NEW):**
````markdown
```{vega-lite}
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"mark": "bar",
...
}
```
````
**Key differences:**
- No need for `id` attribute - filter auto-generates unique IDs
- No `actions` attribute - actions toolbar enabled by default
- No `load_vega` frontmatter needed - filter includes libraries automatically
- Just paste your Vega-Lite JSON spec inside the code fence!
## 🎯 Migration Steps for Vega Posts
1. **Find Hugo shortcode:**
```markdown
{{</* vega-lite id="..." */>}}
```
2. **Copy the JSON spec** (everything between the shortcode tags)
3. **Replace with code fence:**
````markdown
```{vega-lite}
{your JSON spec here}
```
````
4. **Remove** the `load_vega: true` from frontmatter (no longer needed)
## 🧪 Testing
After adding a Vega-Lite visualization:
1. **Build:** `quarto render`
2. **Preview:** `quarto preview`
3. **Check:**
- Visualization renders correctly
- Actions toolbar appears (export PNG/SVG/etc.)
- No errors in browser console
- Code display respects your echo/fold settings
## 📋 Example Post with Visualization
```yaml
---
title: "My Vega-Lite Post"
date: "2024-03-15"
lang: en
categories:
- dataviz
- showcase
---
## Simple Bar Chart
```{vega-lite}
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "A simple bar chart",
"data": {
"values": [
{"category": "A", "value": 28},
{"category": "B", "value": 55},
{"category": "C", "value": 43}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "category", "type": "nominal"},
"y": {"field": "value", "type": "quantitative"}
}
}
```
```
## 🔗 Additional Resources
- [Vega-Lite Documentation](https://vega.github.io/vega-lite/)
- [Vega-Lite Examples](https://vega.github.io/vega-lite/examples/)
- [Quarto Filters Guide](https://quarto.org/docs/extensions/filters.html)
## ⚠️ Troubleshooting
**Visualization not rendering:**
- Check that `vega-lite.lua` exists in the project root
- Verify `filters: - vega-lite.lua` is in `_quarto.yml`
- Ensure JSON spec is valid (test at https://vega.github.io/editor/)
**Browser console errors:**
- Check network tab for CDN library loading issues
- Verify Vega-Lite spec schema version matches (v5)
**Code block shown as plain text:**
- Make sure you're using ````{vega-lite}` not ````{json}` or ````json`

17
_includes/analytics.html Normal file
View File

@@ -0,0 +1,17 @@
<!-- Plausible Analytics -->
<script defer data-domain="olehomelchenko.com" src="https://plausible.io/js/script.file-downloads.outbound-links.tagged-events.js"></script>
<script>window.plausible = window.plausible || function() { (window.plausible.q = window.plausible.q || []).push(arguments) }</script>
<!-- Matomo Analytics -->
<script>
var _paq = window._paq = window._paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
var u = "//matomo.olehomelchenko.com/";
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '1']);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
g.async = true; g.src = u + 'matomo.js'; s.parentNode.insertBefore(g, s);
})();
</script>

59
_quarto.yml Normal file
View File

@@ -0,0 +1,59 @@
project:
type: website
output-dir: _site
render:
- "*.qmd"
- "!archetypes/"
- "!content/"
- "!data/"
- "!i18n/"
- "!layouts/"
- "!public/"
- "!resources/"
- "!static/"
- "!templates/"
- "!themes/"
filters:
- vega-lite.lua
website:
title: "Oleh Omelchenko"
site-url: "https://olehomelchenko.com"
description: "Data visualization and analysis blog"
navbar:
background: light
left:
- text: "Posts"
href: posts/index.qmd
- text: "TILs"
href: til/index.qmd
- text: "Portfolio"
href: portfolio/index.qmd
- text: "Projects"
href: projects/index.qmd
- text: "About"
href: about/index.qmd
right:
- icon: github
href: https://github.com/olehomelchenko
aria-label: GitHub
page-footer:
left: "© 2025 Oleh Omelchenko"
right:
- icon: github
href: https://github.com/olehomelchenko
aria-label: GitHub
format:
html:
theme: cosmo
css: styles.css
toc: false
page-layout: article
include-in-header: _includes/analytics.html
execute:
freeze: auto

6
_redirects Normal file
View File

@@ -0,0 +1,6 @@
# Redirects for old Hugo URLs (English language paths)
# Redirects old /en/* paths to the new unified structure
/en/posts/* /posts/:splat 301
/en/til/* /til/:splat 301
/en/* /:splat 301

53
about/index.qmd Normal file
View File

@@ -0,0 +1,53 @@
---
title: "About"
page-layout: article
---
## Hi, I'm Oleh Omelchenko
<!-- Replace this template with your actual bio and information -->
### Background
Add your background, education, and experience here.
### Skills & Expertise
::: {.grid}
::: {.g-col-12 .g-col-md-4}
**Data Visualization**
- Vega-Lite
- Python (Altair, Matplotlib)
- R (ggplot2)
:::
::: {.g-col-12 .g-col-md-4}
**Analysis & Tools**
- Python (pandas, numpy)
- R
- SQL
:::
::: {.g-col-12 .g-col-md-4}
**Communication**
- Quarto
- Jupyter Notebooks
- Technical Writing
:::
:::
### Projects
Check out my [portfolio](/portfolio/) and [projects](/projects/) pages to see examples of my work.
### Contact
- GitHub: [github.com/olehomelchenko](https://github.com/olehomelchenko)
- Email: [your-email@example.com](mailto:your-email@example.com)
- LinkedIn: [Add your LinkedIn URL]
---
*Replace this template with your actual information, accomplishments, and links.*

41
index.qmd Normal file
View File

@@ -0,0 +1,41 @@
---
title: "Oleh Omelchenko"
page-layout: full
---
## Welcome
Привіт! Я Олег, ви можете знати мене як аналітика в MacPaw та/або викладача в Київській школі економіки.
Цей сайт - сховище моїх знахідок в інтернеті, а також подекуди статей за темою аналізу та візуалізації даних.
![](https://static.olehomelchenko.com/oleh-omelchenko.jpeg)
Data visualization enthusiast and analyst. This site showcases my work in data analysis, visualization, and storytelling with data.
### Recent Posts
::: {.grid}
::: {.g-col-12 .g-col-md-4}
### [Posts](/posts/)
Latest articles and analysis
:::
::: {.g-col-12 .g-col-md-4}
### [Portfolio](/portfolio/)
Selected visualization work
:::
::: {.g-col-12 .g-col-md-4}
### [TILs](/til/)
Quick tips and learnings
:::
:::
---
Explore my [projects](/projects/) or learn more [about me](/about/).

26
portfolio/index.qmd Normal file
View File

@@ -0,0 +1,26 @@
---
title: "Portfolio"
page-layout: full
---
Selected data visualization projects showcasing interactive charts, dashboards, and analytical narratives.
::: {.grid}
::: {.g-col-12 .g-col-md-6}
### [Sample Visualization Post](../posts/sample-visualization-post/)
Example post with Vega-Lite visualization - posts with the `showcase` category will appear here.
:::
:::
---
**Note:** After migrating your Hugo posts, manually add links here to your visualization-heavy posts (those with the `showcase` category). Example:
```markdown
::: {.g-col-12 .g-col-md-6}
### [Forbes Top-50 Foundations](../posts/forbes-50-foundations/)
Interactive visualization of Ukraine's top charitable foundations
:::
```

2
posts/_metadata.yml Normal file
View File

@@ -0,0 +1,2 @@
# Shared metadata for all posts
freeze: auto

16
posts/index.qmd Normal file
View File

@@ -0,0 +1,16 @@
---
title: "Posts"
page-layout: full
listing:
contents: "*.qmd"
type: default
sort: "date desc"
categories: true
sort-ui: true
filter-ui: true
fields: [date, title, reading-time, categories]
date-format: "D MMMM YYYY"
page-size: 10
---
All blog posts covering data visualization, analysis, and related topics. Posts are available in both Ukrainian and English.

View File

@@ -0,0 +1,25 @@
---
title: "Sample English Post"
date: "2024-02-20"
lang: en
categories:
- dataviz
- tutorial
description: "Example structure for an English post"
---
## Introduction
This is a sample English post. Replace this with your actual content from Hugo.
### Main Content
When you migrate your posts from Hugo, they will have this structure:
- Frontmatter with metadata (title, date, language, categories)
- Markdown content
- Support for Vega-Lite visualizations
## Conclusion
Replace this file with your actual Hugo posts.

View File

@@ -0,0 +1,25 @@
---
title: "Зразок Української Статті"
date: "2024-01-15"
lang: uk
categories:
- dataviz
- example
description: "Приклад структури для української статті"
---
## Вступ
Це зразок статті українською мовою. Тут ви можете додати свій контент.
### Основний зміст
Коли ви перенесете свої статті з Hugo, вони матимуть таку структуру:
- Frontmatter з метаданими (title, date, language, categories)
- Markdown контент
- Підтримка Vega-Lite візуалізацій
## Висновки
Замініть цей файл своїми реальними статтями з Hugo.

View File

@@ -0,0 +1,55 @@
---
title: "Sample Visualization Post"
date: "2024-03-10"
lang: en
categories:
- dataviz
- showcase
- vega-lite
description: "Example post with Vega-Lite visualization"
---
## Vega-Lite Example
This post demonstrates how to include Vega-Lite visualizations in Quarto. Note the `showcase` category - posts with this category will appear in your Portfolio.
### Simple Bar Chart
```{vega-lite}
//| label: fig-simple-bar
//| fig-cap: "A simple bar chart"
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "A simple bar chart with embedded data.",
"data": {
"values": [
{"category": "A", "value": 28},
{"category": "B", "value": 55},
{"category": "C", "value": 43},
{"category": "D", "value": 91},
{"category": "E", "value": 81}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "category", "type": "nominal", "axis": {"labelAngle": 0}},
"y": {"field": "value", "type": "quantitative"}
},
"width": 400,
"height": 300
}
```
### Migration Notes
When migrating from Hugo:
1. **Remove the Hugo shortcode**:
- Old: `{{</* vega-lite id="chart1" */>}}...{{</* /vega-lite */>}}`
2. **Use Quarto code fence**:
- New: ````{vega-lite}` with `//| label: chart-name`
3. **The visualization JSON stays the same** - just change the wrapper!
Replace this with your actual visualization posts from Hugo.

30
projects/index.qmd Normal file
View File

@@ -0,0 +1,30 @@
---
title: "Projects"
page-layout: full
---
## Featured Projects
::: {.grid}
::: {.g-col-12 .g-col-md-6}
### [Sample Project 1](sample-project-1/)
A full project page with detailed analysis and visualizations. Replace with your actual projects.
:::
::: {.g-col-12 .g-col-md-6}
### Sample Project 2
A brief description without a dedicated page. Just a reference in the listing.
:::
:::
---
## Other Projects
- **Quick Project Reference 1** - Brief description
- **Quick Project Reference 2** - Brief description
- **Quick Project Reference 3** - Brief description
Some projects get full dedicated pages (like Sample Project 1 above), while others are just listed here with brief descriptions.

View File

@@ -0,0 +1,32 @@
---
title: "Sample Project 1"
subtitle: "Full Project Page Example"
date: "2024-03-01"
categories:
- project
- dataviz
---
## Overview
This is an example of a full project page. Some projects warrant detailed explanations with multiple sections, code examples, and visualizations.
### Background
Describe the context and motivation for this project.
### Approach
Explain your methodology and approach.
### Results
Show your findings, visualizations, and analysis.
### Conclusions
Summarize the key takeaways.
---
Replace this with your actual project content.

12
styles.css Normal file
View File

@@ -0,0 +1,12 @@
/* Minimal custom styling for olehomelchenko.com */
/* Vega-Lite visualization styling - center and add subtle shadow */
.vega-embed {
justify-content: center;
display: flex;
}
.vega-embed canvas.marks {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin: 10px;
}

2
til/_metadata.yml Normal file
View File

@@ -0,0 +1,2 @@
# Shared metadata for TILs (Today I Learned)
freeze: auto

14
til/index.qmd Normal file
View File

@@ -0,0 +1,14 @@
---
title: "TILs - Today I Learned"
page-layout: full
listing:
contents: "*.qmd"
type: table
sort: "date desc"
fields: [date, title, categories]
date-format: "YYYY-MM-DD"
table-striped: true
filter-ui: true
---
Quick tips, discoveries, and learnings. Short-form content about interesting things I've discovered.

View File

@@ -0,0 +1,14 @@
---
title: "Sample TIL (Today I Learned)"
date: "2024-03-20"
lang: en
categories:
- tools
- quick-tip
---
A short note about something interesting I learned today.
TIL articles are typically shorter than full blog posts and contain quick tips or useful discoveries.
Replace this file with your actual TILs from Hugo.

View File

@@ -0,0 +1,14 @@
---
title: "Зразок TIL (Today I Learned)"
date: "2024-03-15"
lang: uk
categories:
- tools
- quick-tip
---
Короткий запис про щось цікаве, що я дізнався сьогодні.
TIL статті зазвичай коротші за повноцінні пости і містять швидкі поради або корисні знахідки.
Замініть цей файл своїми реальними TIL з Hugo.

75
vega-lite.lua Normal file
View File

@@ -0,0 +1,75 @@
-- vega-lite.lua
-- A Quarto filter to render vega-lite code blocks using vega-embed
local vegaEmbedIncluded = false
function ensureVegaEmbed()
if not vegaEmbedIncluded then
vegaEmbedIncluded = true
quarto.doc.include_text("in-header", [[
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
]])
end
end
local counter = 0
function CodeBlock(block)
if block.classes:includes('vega-lite') then
ensureVegaEmbed()
counter = counter + 1
local divId = 'vega-viz-' .. counter
-- Get the spec as a string
local spec = block.text
-- Parse options from attributes
local echo = block.attributes['echo']
local codeFold = block.attributes['code-fold']
-- Default to showing code
if echo == nil then echo = "true" end
local result = {}
-- Handle code display
if echo ~= "false" then
local codeBlock = pandoc.CodeBlock(spec, {class = "json"})
if codeFold == "true" or codeFold == "show" then
-- Wrap in collapsible details/summary
local openAttr = ""
if codeFold == "show" then
openAttr = " open"
end
local foldedCode = pandoc.RawBlock('html', string.format([[
<details%s>
<summary>Click to expand code</summary>
]], openAttr))
table.insert(result, foldedCode)
table.insert(result, codeBlock)
table.insert(result, pandoc.RawBlock('html', '</details>'))
else
-- Show code normally
table.insert(result, codeBlock)
end
end
-- Create the HTML output for the visualization
local html = string.format([[
<div id="%s"></div>
<script type="text/javascript">
vegaEmbed('#%s', %s, {"actions": true});
</script>
]], divId, divId, spec)
table.insert(result, pandoc.RawBlock('html', html))
return result
end
end