Risherry began as a customizable personal website and portfolio build using Bootstrap, Handlebars and JQuery frameworks. It also incorporates Sass, Font Awesome and Google Fonts.
If you want to customize locally the sources you will need Node.js and npm.
The build system uses Grunt with plugins like watch, sass, and cssmin. The plugins are installed and managed via npm.
Install all dependencies.
Build all themes by compiling SCSS to CSS and minifying the output.
Compile SCSS files to CSS only.
Minify CSS files only.
Launch the watch task that monitors file changes and automatically compiles and minifies the CSS sources.
You should run the build tasks on the src/sass files and commit the results in the dist folder.
The content it's easily customizable since it reads the data from JSON.
risherry/
├── src/
├── data/
│ ├── config.json
│ ├── content.json
├── js/
└── sass/
By default, there are default available themes.
Each of these themes have a custom.scss and a variables.scss file, that contain the theme's definition. New themes can be created and used.
risherry/
├── src/
├── data/
├── js/
└── sass/
├── skin/
├── style.scss
└── themes/
└── default/
├── custom.scss
└── variables.scss
Test your changes using a local web server. Depending on your configuration there might be changes between the master and the ghpages branches.
This project has been transformed to separate content from presentation, following the pattern from the React example in the example/ folder.
The content is now stored in structured data files and rendered dynamically by JavaScript, making it easier to:
- Update content without touching HTML
- Maintain consistency across the site
- Add new content items programmatically
- Potentially support multiple languages or themes
src/js/
├── content.js # All content data (site config, case studies, talks)
└── app.js # Main application logic for rendering content
dist/js/
└── app.js # Bundled JavaScript (generated by Grunt)
Contains global site information:
- Name, title, subtitle, motto
- Contact information
- Statistics (years experience, team size, etc.)
- Tags for filtering/highlighting
- Social media links
Array of case study objects with:
- Title, description, period
- Icon and styling class
- Highlights (key metrics/achievements)
- Skills/tags
- URL for detailed view
Array of talk objects with:
- Title, venue, year
- YouTube video ID
- Event information
- Open
src/js/content.js - Add a new object to the
caseStudiesarray:
{
slug: "new-project",
title: "New Project Name",
description: "Description of the project...",
period: "2023-2024 • 1 Year",
icon: "code", // Material Icons name
iconClass: "new-project", // CSS class for styling
url: "case-studies/new-project.html",
highlights: [
{ title: "Metric 1", value: "Value 1" },
{ title: "Metric 2", value: "Value 2" }
],
skills: [
{ name: "Skill 1", type: "design" },
{ name: "Skill 2", type: "strategy" }
]
}- Add a new object to the
talksarray:
{
id: "talk-4",
title: "New Talk Title",
venue: "Conference Name • Location",
youtubeId: "YOUTUBE_VIDEO_ID"
}Modify the siteConfig object to update:
- Personal information
- Statistics
- Social media links
- Contact details
- Edit content: Modify
src/js/content.js - Build: Run
npm run buildorgruntto bundle JavaScript - Test: Open
index.htmlin a browser
For development with auto-rebuild:
grunt watch- Separation of Concerns: Content and presentation are clearly separated
- Maintainability: Easy to update content without touching HTML
- Consistency: Structured data ensures consistent formatting
- Scalability: Easy to add new content items
- Reusability: Content can be used in different contexts (e.g., API endpoints)
- Internationalization Ready: Structure supports multiple languages
This implementation follows the same pattern as the React example:
- Content stored in structured data files
- Components/functions for rendering different content types
- Dynamic content population
- Separation of data from presentation logic
The main difference is using vanilla JavaScript instead of React components, making it compatible with the existing HTML/CSS structure.
Potential improvements:
- Content management system integration
- API endpoints for dynamic content loading
- Multi-language support
- Content versioning
- Admin interface for content editing