Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
fa3296d
Add PostCSS setup with required dependencies and Jekyll plugin
liberaldev Dec 29, 2025
5b0d28d
Add PostCSS config with Tailwind CSS and Autoprefixer plugins
liberaldev Dec 29, 2025
c7295c5
Add empty front matter to `tailwind.css` for Jekyll compatibility
liberaldev Dec 29, 2025
edbe822
Update stylesheet references to use `main.css` instead of `compiled.c…
liberaldev Dec 29, 2025
9d169eb
Remove unused Tailwind CSS build scripts from `package.json`
liberaldev Dec 29, 2025
520c35c
Add Node.js setup and dependency installation steps to Jekyll workflow
liberaldev Dec 29, 2025
ce3387d
Update `CLAUDE.md` to remove outdated Tailwind CSS build details and …
liberaldev Dec 29, 2025
d040c6d
Add `jekyll-postcss-v2` plugin and update exclude list in `_config.yml`
liberaldev Dec 29, 2025
c801925
Expand exclusion list in linter to ignore `node_modules` and `_site` …
liberaldev Dec 29, 2025
32f5da7
Remove `compiled.css` as it's no longer in use
liberaldev Dec 29, 2025
3c39d29
Add Node.js setup and npm install steps to CI workflow
liberaldev Dec 29, 2025
f54c5d8
Updated `_config.yml` to exclude additional files and directories fro…
liberaldev Dec 29, 2025
9fb30e3
Documented Tailwind CSS setup and usage details in README.md.
liberaldev Dec 29, 2025
8881c4c
Added incremental build support for CSS regeneration based on HTML/Ma…
liberaldev Dec 30, 2025
4a9285b
Added tests for Tailwind incremental build plugin and integrated them…
liberaldev Dec 30, 2025
2480592
Fixed missing newline at EOF in plugin and test files.
liberaldev Dec 30, 2025
9fcdb45
simplify content patterns array using %w notation
liberaldev Dec 30, 2025
1a6c6b7
Refactor Tailwind incremental fix tests
liberaldev Dec 30, 2025
82e1642
Fix Gemfile quoting for consistency in `jekyll-postcss-v2` entry
liberaldev Jan 1, 2026
ec738a9
Refactor stylesheet structure: move components to `_components` and u…
liberaldev Jan 1, 2026
c045c89
Rename and update Tailwind incremental fix plugin to PostCSS incremen…
liberaldev Jan 1, 2026
60d42bd
Remove outdated Tailwind CSS instructions and redundant content in RE…
liberaldev Jan 1, 2026
7f3476e
Update CLAUDE.md: streamline instructions, remove outdated Tailwind C…
liberaldev Jan 1, 2026
d585a0a
Refactor PostCSS incremental fix plugin: extract watched file pattern…
liberaldev Jan 1, 2026
b3d4f61
Add Node.js installation instructions to README
liberaldev Jan 3, 2026
11ad72a
Clarify CSS modification note in README
liberaldev Jan 3, 2026
9ed4e1f
Merge branch 'master' into integrate-postcss
liberaldev Jan 3, 2026
df4edd2
Update note about CSS changes in README
liberaldev Jan 3, 2026
e4f01cb
Add .git, .gitignore, and .github to ignore list
liberaldev Jan 3, 2026
0324c77
Clarify CSS partial handling in CLAUDE.md
liberaldev Jan 3, 2026
8829216
Fix formatting and punctuation in CLAUDE.md
liberaldev Jan 3, 2026
720f34f
Add PostCSS and related plugins to documentation
liberaldev Jan 3, 2026
b340422
Fix formatting in CLAUDE.md stylesheets section
liberaldev Jan 3, 2026
e28bf90
Add cssnano for CSS minification in production builds and update docu…
liberaldev Jan 4, 2026
9819afc
Reorganized `<link rel="preconnect>` tags for improved font loading
liberaldev Jan 4, 2026
52c9179
Merge branch 'master' into integrate-postcss
liberaldev Jan 5, 2026
e8dd9bd
Merge branch 'master' into integrate-postcss
liberaldev Jan 6, 2026
7f0081d
Merge branch 'master' into integrate-postcss
liberaldev Jan 10, 2026
4cf7fa1
Merge branch 'master' into integrate-postcss
liberaldev Jan 13, 2026
f422673
Merge branch 'master' into integrate-postcss
liberaldev Jan 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ jobs:
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: '24'
- name: Install node dependencies
run: npm install
- name: Dump Ruby version
run: ruby -v
- name: Run tests
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/jekyll.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ jobs:
with:
ruby-version: '3.2'
bundler-cache: true
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: '24'
- name: Install node dependencies
run: npm install
- name: Setup Pages
id: pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
Expand Down
27 changes: 12 additions & 15 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,6 @@ bundle exec rake serve
bundle exec jekyll serve --watch --future --incremental
```

### CSS (Tailwind)

```bash
# Build CSS (production)
npm run build-css

# Watch CSS for development
npm run watch-css
```

### Testing & Quality Assurance

```bash
Expand All @@ -40,6 +30,7 @@ bundle exec rake test
# Run individual test suites
bundle exec rake test-news-plugin # News archive plugin tests
bundle exec rake test-linter # Linter library tests
bundle exec rake test-postcss-incremental-fix-plugin # PostCSS incremental build plugin tests

# Linting
bundle exec rake lint # Markdown linter
Expand All @@ -56,7 +47,7 @@ bundle exec rake check:links # Check for broken links (needs local serv
bundle exec rake new_post:en # English
bundle exec rake new_post:ja # Japanese
bundle exec rake new_post:fr # French
# ... etc for: bg, de, es, id, it, ko, pl, pt, ru, tr, vi, zh_cn, zh_tw
# ... etc for: bg, de, es, id, it, ja, ko, pl, pt, ru, tr, vi, zh_cn, zh_tw
```

## Architecture & Structure
Expand All @@ -83,24 +74,25 @@ bundle exec rake new_post:fr # French
- `_data/`: YAML data files (releases.yml, downloads.yml, branches.yml, locales/)
- `lib/`: Ruby utilities (linter, markup checker, draft release)
- `test/`: Test files for plugins and linter
- `stylesheets/`: CSS source and compiled output
- `stylesheets/`: CSS source (includes partials that Jekyll excludes by default: directories prefixed with `_` and files starting with `_`)
- `_javascripts_src/`: TypeScript source files
- `javascripts/`: Compiled JavaScript output

### Design System (Tailwind CSS)

The site uses a custom Tailwind configuration with:

- **Semantic color tokens** via CSS variables (defined in `tailesheets/semantic-colors.css`)
- **Semantic color tokens** via CSS variables (defined in `stylesheets/semantic-colors.css`)
- Accessible via `bg-semantic-*`, `text-semantic-*`, `border-semantic-*` classes
- Automatically handles light/dark mode via `prefers-color-scheme`
- **Incremental Build**: Uses `_plugins/postcss_incremental_fix.rb` to trigger PostCSS rebuilds during `jekyll serve --incremental` when CSS partials are modified
- **CSS partials**: Files/directories that Jekyll normally excludes (underscore-prefixed like `_components/` or `_variables. css`) but are imported by main stylesheets
- The plugin watches these excluded partials and forces a rebuild when they change, ensuring Tailwind processes updated styles
- **Brand colors**: Ruby (red) and Gold palettes
- **Typography plugin** for prose styling
- **Custom breakpoints**: Container max-widths configured for content layouts
- **Dark mode**: Enabled via OS preference (`darkMode: 'media'`)

Input: `stylesheets/tailwind.css` → Output: `stylesheets/compiled.css`

### News System

The news system is powered by a custom Jekyll plugin (`_plugins/news.rb`):
Expand Down Expand Up @@ -179,6 +171,11 @@ lang: en
**Node (package.json):**
- `tailwindcss` - CSS framework
- `@tailwindcss/typography` - Prose styling plugin
- `postcss` - CSS transformation tool
- `postcss-cli` - PostCSS command-line interface
- `postcss-import` - PostCSS plugin for @import resolution
- `autoprefixer` - PostCSS plugin for vendor prefix automation
- `cssnano` - CSS minification tool (activated only in production builds to optimize CSS file size)

## Important Conventions

Expand Down
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ gem "validate-website", "~> 1.6"
# Jekyll need them for Ruby 3.4+
gem "csv"
gem "base64"

group :jekyll_plugins do
gem "jekyll-postcss-v2"
end
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ GEM
safe_yaml (~> 1.0)
terminal-table (>= 1.8, < 4.0)
webrick (~> 1.7)
jekyll-postcss-v2 (1.0.2)
jekyll-sass-converter (3.1.0)
sass-embedded (~> 1.75)
jekyll-watch (2.2.1)
Expand Down Expand Up @@ -245,6 +246,7 @@ DEPENDENCIES
csv
html-proofer
jekyll
jekyll-postcss-v2
minitest
rake
rouge
Expand Down Expand Up @@ -292,6 +294,7 @@ CHECKSUMS
i18n (1.14.7) sha256=ceba573f8138ff2c0915427f1fc5bdf4aa3ab8ae88c8ce255eb3ecf0a11a5d0f
io-event (1.10.0) sha256=e4e1f5bf01a1a8b8484db3c5d99b431eb3609dbc988b96622d14d77993e0e9dc
jekyll (4.4.1) sha256=4c1144d857a5b2b80d45b8cf5138289579a9f8136aadfa6dd684b31fe2bc18c1
jekyll-postcss-v2 (1.0.2) sha256=f179d3de83918ebb266ac8adc3191e422107fec5b088cb1c35fa9ff9c50b89c3
jekyll-sass-converter (3.1.0) sha256=83925d84f1d134410c11d0c6643b0093e82e3a3cf127e90757a85294a3862443
jekyll-watch (2.2.1) sha256=bc44ed43f5e0a552836245a54dbff3ea7421ecc2856707e8a1ee203a8387a7e1
json (2.10.2) sha256=34e0eada93022b2a0a3345bb0b5efddb6e9ff5be7c48e409cfb54ff8a36a8b06
Expand Down
13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This is the [Jekyll](http://www.jekyllrb.com/) source code for the official [Rub
### Prerequisites

- **Ruby** (latest stable version recommended) - [Install Ruby](https://www.ruby-lang.org/en/documentation/installation/)
- **Node.js** - [Install Node.js](https://nodejs.org/en/download/)
- **Git** - [Install Git](https://git-scm.com/downloads)

### Get It Running
Expand All @@ -29,6 +30,7 @@ This is the [Jekyll](http://www.jekyllrb.com/) source code for the official [Rub
cd www.ruby-lang.org/
bundle config set --local without production
bundle install
npm install
```

3. **Start the development server**:
Expand Down Expand Up @@ -125,16 +127,9 @@ If you can't build locally or want to test under production conditions:

## Styling with Tailwind CSS

This site uses [Tailwind CSS](https://tailwindcss.com/) for styling.
After making changes to HTML/Markdown files or Tailwind configuration:

``` sh
npm run build-css # build CSS
npm run watch-css # watch and rebuild CSS automatically
```

**Note:** You need to have Node.js installed to run these commands.
This site uses [Tailwind CSS](https://tailwindcss.com/) for styling.

⏱️ **Note:** When you modify CSS files or add/modify CSS classes in HTML or Markdown files, it might take a moment for the changes to be reflected in the preview, as the CSS needs to be rebuilt.

## Testing

Expand Down
10 changes: 9 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ CONFIG = "_config.yml"
task default: [:build]

desc "Run tests (test-linter, lint, build)"
task test: %i[test-news-plugin test-html-lang-plugin test-linter lint build]
task test: %i[test-news-plugin test-html-lang-plugin test-postcss-incremental-fix-plugin test-linter lint build]

desc "Build the Jekyll site"
task :build do
Expand Down Expand Up @@ -137,3 +137,11 @@ Rake::TestTask.new(:"test-html-lang-plugin") do |t|
t.test_files = FileList['test/test_plugin_html_lang.rb']
t.verbose = true
end

require "rake/testtask"
Rake::TestTask.new(:"test-postcss-incremental-fix-plugin") do |t|
t.description = "Run tests for the PostCSS incremental fix plugin"
t.libs = ["test"]
t.test_files = FileList['test/test_plugin_postcss_incremental_fix.rb']
t.verbose = true
end
14 changes: 14 additions & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,24 @@ exclude:
- Gemfile.lock
- Rakefile
- README.md
- CLAUDE.md
- lib
- test
- vendor
- tsconfig.json
- package.json
- package-lock.json
- node_modules
- tailwind.config.js
- postcss.config.js
- .git
- .gitignore
- .github
- .idea
- .vscode

plugins:
- jekyll-postcss-v2

url: https://www.ruby-lang.org

Expand Down
4 changes: 2 additions & 2 deletions _layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@
<meta itemprop="description" content="{{ meta_description }}">
<meta itemprop="image" content="{{ site.url }}/images/og-image.png">

<link rel="stylesheet" type="text/css" href="/stylesheets/compiled.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900&family=Noto+Sans+KR:wght@100..900&family=Noto+Sans+SC:wght@100..900&family=Noto+Sans+TC:wght@100..900&family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&family=Material+Icons&family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..24,200..700,0,0&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/stylesheets/main.css">
<link rel="canonical" href="{{ site.url }}{{ page.url | replace: 'index.html', '' }}">

<link rel="icon" href="/favicon.ico" sizes="32x32">
Expand Down Expand Up @@ -122,4 +122,4 @@
</div>

{% include footer.html %}
</body>
</body>
2 changes: 1 addition & 1 deletion _layouts/homepage.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@
<meta itemprop="description" content="{{ meta_description }}">
<meta itemprop="image" content="{{ site.url }}/images/og-image.png">

<link rel="stylesheet" type="text/css" href="/stylesheets/compiled.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900&family=Noto+Sans+KR:wght@100..900&family=Noto+Sans+SC:wght@100..900&family=Noto+Sans+TC:wght@100..900&family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&family=Material+Icons&family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..24,200..700,0,0&display=swap" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/stylesheets/main.css">
<link rel="canonical" href="{{ site.url }}{{ page.url | replace: 'index.html', '' }}">

<link rel="icon" href="/favicon.ico" sizes="32x32">
Expand Down
76 changes: 76 additions & 0 deletions _plugins/postcss_incremental_fix.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Regenerate CSS when HTML/Markdown files or imported CSS partials change
# Detects changes in content files and CSS partials (e.g., _components/*.css, _variables.css)
# to trigger PostCSS rebuild via jekyll-postcss-v2 plugin

module Jekyll
module PostcssTrigger
# File patterns to watch for changes that should trigger CSS rebuild
WATCHED_FILE_PATTERNS = %w[
_layouts/**/*.html
_includes/**/*.html
*.html
*.md
*/**/*.html
*/**/*.md
stylesheets/**/_*.css
stylesheets/_*/**/*.css
].freeze

class << self
attr_accessor :last_check_time, :css_touched
end
end
end

Jekyll::Hooks.register :site, :post_read do |site|
# Skip if not in incremental mode
next unless site.config['incremental']

# On first build, only record the check time
if Jekyll::PostcssTrigger.last_check_time.nil?
Jekyll::PostcssTrigger.last_check_time = Time.now
Jekyll::PostcssTrigger.css_touched = false
next
end

# Skip if CSS was already touched in this build
next if Jekyll::PostcssTrigger.css_touched

# Check if any HTML/Markdown files or included CSS files have changed
content_patterns = Jekyll::PostcssTrigger::WATCHED_FILE_PATTERNS

html_changed = false
last_check = Jekyll::PostcssTrigger.last_check_time

content_patterns.each do |pattern|
Dir.glob(site.in_source_dir(pattern)).each do |file|
next if file.start_with?(site.dest) # Exclude _site directory

# Check if a file was modified since the last check
if File.exist?(file) && File.mtime(file) > last_check
html_changed = true
Jekyll.logger.info "PostCSS Trigger:", "Detected change in #{File.basename(file)}"
break
end
end
break if html_changed
end

# Touch CSS file if HTML has changed
if html_changed
css_file = site.in_source_dir("stylesheets/main.css")
if File.exist?(css_file)
Jekyll.logger.info "PostCSS Trigger:", "Marking CSS for rebuild"
FileUtils.touch(css_file)
Jekyll::PostcssTrigger.css_touched = true
end
end

# Update check time
Jekyll::PostcssTrigger.last_check_time = Time.now
end

# Reset flag after build completes
Jekyll::Hooks.register :site, :post_write do |site|
Jekyll::PostcssTrigger.css_touched = false
end
4 changes: 3 additions & 1 deletion lib/linter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class Linter
%r{\Aadmin/index\.md},
%r{\A[^/]*/examples/},
%r{\A_includes/},
%r{\Atest/}
%r{\Atest/},
%r{\Anode_modules/},
%r{\A_site/}
].freeze

WHITESPACE_EXCLUSIONS = [
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
"name": "www-renewal",
"version": "1.0.0",
"description": "Ruby Language Website Renewal with Tailwind CSS",
"scripts": {
"build-css": "tailwindcss -i ./stylesheets/tailwind.css -o ./stylesheets/compiled.css",
"watch-css": "tailwindcss -i ./stylesheets/tailwind.css -o ./stylesheets/compiled.css --watch"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.19",
"autoprefixer": "^10.4.23",
"cssnano": "^7.1.2",
"postcss": "^8.5.6",
"postcss-cli": "^11.0.1",
"postcss-import": "^16.1.1",
"tailwindcss": "^3.4.14"
}
}
16 changes: 16 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const path = require('node:path');

module.exports = {
plugins: {
"postcss-import": {
path: path.join(__dirname, 'stylesheets')
},
tailwindcss: {},
autoprefixer: {},
...(process.env.JEKYLL_ENV === 'production' && {
cssnano: {
preset: 'default'
}
})
}
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading