Miscellaneous web stuff

Miscellaneous web stuff

Miscellaneous web stuff

Entity-Oriented Website Design Manual

Entity-Oriented Website Design Manual

Core Principle

Design the website around things that exist in the subject matter, not around pages, menus, or articles.

Ask:

"What are the things I want to know about?"

not

"What pages do I want on my website?"


Step 1: Identify Core Entities

An entity is something important enough to deserve its own page.

For Contraptions, examples include:

  • Contraption
  • Sound
  • Voice
  • MIDI Map
  • MIDI Map Entry
  • Function
  • Registration
  • Effect
  • Article
  • Tech

The test is:

Would I ever want to browse, search, categorize, or link to this thing directly?

If yes, consider making it an entity.


Step 2: Separate Things from Stories

Distinguish between persistent objects and temporary narratives.

Objects

Things that exist over time:

  • Topsy
  • Glockenbox
  • MIDI Interface
  • Reuter 1674

Stories

Things that document activity:

  • Build logs
  • Progress reports
  • Announcements
  • Historical articles

Objects accumulate stories over time.


Step 3: Normalize Concepts

Separate different dimensions of classification.

For example:

What it IS

Instrument
Interface
Controller
Rank
Tool

This belongs in:

Contraption Type

What disciplines are involved

Electronics
Mechanical
Woodworking
Software
Physics
Music

This belongs in:

Genre

A single taxonomy should answer a single question.


Step 4: Prefer Relationships Over Hierarchies

Many systems naturally form networks rather than trees.

Avoid forcing this:

Parent
 └─ Child

when reality looks more like:

A relates to B
A uses C
A inspired D
B controls E

Use flexible relationships whenever possible.


Step 5: Model Reality, Not Implementation

Example:

Don't ask:

"Should MIDI Controller be a content type?"

Ask:

"What is a MIDI Controller in the real world?"

The answer determines the model.

A database should describe reality rather than software structure.


Step 6: Create New Entities Only When Necessary

Avoid creating content types for every idea.

Ask:

Is this fundamentally different?

If not, use an existing entity.

For example, we discovered many "components" are actually specialized contraptions:

  • Pipe chest
  • MIDI interface
  • Bellows
  • Test bench

Rather than creating a new Component entity, they can remain Contraptions.


Step 7: Use Taxonomies for Classification

Use content types for things.

Use taxonomies for categories.

Good entity

Contraption

Good taxonomy

Contraption Type

Good taxonomy

Genre

Step 8: Make Relationships Discoverable

Store the relationship once.

Examples:

Topsy
→ related contraption
→ MIDI Interface

Then use Views to discover:

What references this item?

instead of storing reciprocal links manually.


Step 9: Let Real Content Drive the Model

Avoid endless redesign.

Enter real content.

Examples:

  • Topsy
  • Reuter 1674
  • Glockenbox
  • MIDI Interface

Then observe:

  • Which fields feel useful?
  • Which relationships keep appearing?
  • Which categories emerge naturally?

The content will reveal the proper architecture.


Step 10: Think Like a Museum Curator

The website is not a collection of pages.

The website is a collection of interconnected knowledge.

For Contraptions:

 

Contraption
├─ Sounds
├─ Voices
├─ MIDI Maps
├─ Registrations
├─ Functions
├─ Articles
├─ Tech Notes
└─ Related Contraptions

 

Each item can be viewed from multiple perspectives without duplicating information.


Guiding Question

Whenever you are unsure how to model something, ask:

"Is this a thing, a category, a relationship, or a story?"

Most content-modeling decisions fall naturally out of that question.

Project type

From Gallery Hierarchies to Entity-Oriented Design: Rethinking Cheddarmongers and Contraptions

From Gallery Hierarchies to Entity-Oriented Design: Rethinking Cheddarmongers and Contraptions

I did a bunch of brainstorming with my buddy Coppy, and we came up with these observations and strategies:  

Introduction

What began as a discussion about migrating old Gallery2 and Drupal sites evolved into a broader conversation about information architecture, data modeling, and the long-term sustainability of hobby websites.

The key realization was that both Cheddarmongers and Contraptions are not fundamentally photo galleries. They are collections of interconnected knowledge. Photos matter, but they represent only one aspect of the underlying content.

Rather than organizing content primarily through folders, albums, pages, and manually assembled galleries, a modern Drupal implementation should organize content around entities and their relationships.

In short:

Cheddarmongers and Contraptions should function more like digital museums or knowledge systems than traditional photo galleries.


The Problem with Page-Oriented and Gallery-Oriented Thinking

Traditional websites often start with a page structure:

 

Site
└─ Section
   └─ Category
      └─ Page
         └─ Photo

 

Gallery2 used a similar hierarchy:

 

User
└─ Album
   └─ Subalbum
      └─ Images

 

This structure works reasonably well when each item belongs in exactly one place. However, it becomes restrictive when one object belongs in several categories at the same time.

For example, a miniature such as Village Idiot might be:

 

Fantasy
Human
Villager
Hasslefree
Kevin White sculpt
Painted by David Rosenthal

 

A folder hierarchy forces that miniature into one primary location. An entity-oriented model allows all of those facts to exist simultaneously.

Likewise, a contraption such as Topsy Street Organ might be:

 

Street organ
MIDI-controlled instrument
Mechanical music project
Pneumatic system
Percussion instrument
Build log subject
Photo collection subject

 

Again, the object has many relationships. It does not naturally belong in one folder.


Core Principle: Entity-Oriented Design

A content-oriented website asks:

What kinds of content do I have?

Examples:

 

Articles
Photos
Videos
Projects
Documents

 

That approach improves on simple page design, but it still treats content as the main object.

An entity-oriented website asks a better question:

What real-world things am I describing?

For Cheddarmongers, the primary entities might include:

 

People
Characters
Miniatures
Manufacturers
Artists
Articles
Media
Organizations

 

For Contraptions, the primary entities might include:

 

People
Contraptions
Components
Technologies
Articles
Media
Organizations

 

Then Drupal stores relationships between those entities:

 

built by
painted by
sculpted by
owned by
depicts
used by
part of
derived from
inspired by
successor to
documented in

 

Content becomes discoverable through metadata and relationships rather than folder placement.


The Museum Catalog Analogy

A useful way to think about this model is to imagine a museum catalog.

A museum would not primarily catalog:

Web Page #12

It would catalog an object:

 

Object: Topsy Street Organ
Type: Mechanical musical instrument
Builder: David Rosenthal
Status: In progress
Technologies: MIDI, pneumatics, pallet magnets

 

Then it would attach supporting material:

 

Photos
Videos
Sound samples
Technical documents
Build logs
Related components

 

Drupal can work the same way.

The entity is the durable object. Articles, photos, videos, and documents provide evidence, history, and context around that object.


Lessons Learned from Gallery2

Gallery2 Was Secretly a Database

The original Gallery2 installation contained much more than photos. It held structured metadata such as:

 

Manufacturer
Genre
Range
Item Name
Model Number
Race
Sculptor
Painter

 

That reveals something important: the old site was already functioning less like a simple photo gallery and more like a structured catalog.

The photos themselves are relatively easy to preserve. The more valuable asset is the metadata.

In a Drupal migration, the goal should not simply be:

Move the galleries into Drupal.

The better goal is:

Preserve and improve the underlying knowledge model.


Static Albums vs. Dynamic Collections

A static Gallery2 structure might look like this:

 

David Rosenthal
├─ Fantasy
├─ Sci-Fi
├─ Villagers
├─ Heroes
└─ Monsters

 

The problem is that a miniature can belong to several of those collections at once.

Instead of assigning an item to one album, Drupal can store structured facts:

 

Miniature: Village Idiot


 

Genre: Fantasy
Creature Type: Humanoid
Ancestry: Human
Role: Villager
Manufacturer: Hasslefree
Sculptor: Kevin White
Painter: David Rosenthal

 

Drupal Views can then generate dynamic collections:

 

All Fantasy Miniatures
All Human Miniatures
All Villagers
All Hasslefree Figures
All Kevin White Sculpts
All Miniatures Painted by David Rosenthal

 

No duplicate images or duplicate content are required.

The same principle applies to Contraptions:

 

Contraption: Topsy Street Organ


 

Type: Street Organ
Technologies: MIDI, pneumatics, electromagnets
Components: MIDI Reader, drum actuator, bellows
Builder: David Rosenthal
Status: In progress

 

Drupal Views can generate:

 

All MIDI Projects
All Pneumatic Instruments
All Street Organs
All Projects Using Pallet Magnets
All Projects Built by David Rosenthal

 


Proposed Cheddarmongers Data Model

User

A User represents an actual site member.

Examples:

 

David Rosenthal
Joe Painter
Jane Brushmaster

 

Potential fields:

 

Display Name
Biography
Avatar
Location
Website

 

Users can own miniatures, paint miniatures, write articles, and create characters.


Miniature

A Miniature represents a physical miniature figure.

Suggested fields:

 

Name
Manufacturer
Range
Model Number
Scale
Description
Photos
Owner
Painter
Sculptor
Character Represented

 

A miniature may depict a character, but it does not have to. Some miniatures are generic figures, monsters, scenery, or prototypes.


Character

A Character represents a fictional person, creature, or persona.

Examples:

 

Grunk Ironjaw
Brother Thimblewick
Village Idiot

 

Suggested fields:

 

Name
Biography
Campaign
Portrait
Creature Type
Ancestry
Role
D&D Beyond URL

 

A character can exist with or without a miniature.

Relationship pattern:

 

Character
└─ depicted by → Miniature

 

This allows:

 

One character represented by multiple miniatures
One miniature representing one character
Characters with no miniature yet
Miniatures with no named character

 


Person

A Person represents an individual who may not be a site user.

Examples:

 

Kevin White
Julie Guthrie
Bob Olley

 

A person may serve as:

 

Sculptor
Painter
Author
Designer
Manufacturer representative
Contributor

 

This separates site accounts from real-world people. A famous sculptor should not need a Drupal login to exist as a referenced person.


Replacing “Race” With a Better Model

The term “race” has become increasingly awkward in fantasy gaming and often fails to describe creatures accurately.

A better model separates broad biological or mythological classification from specific lineage.

Creature Type

Broad classification.

Examples:

 

Humanoid
Undead
Construct
Animal
Dragon
Demon
Elemental
Plant
Reptilian
Insectoid
Aquatic

 

Ancestry

Specific lineage.

Examples:

 

Human
Elf
Dwarf
Orc
Goblin
Kobold
Troll
Halfling
``

 

Examples:

 

Village Idiot
Creature Type: Humanoid
Ancestry: Human
Role: Villager

 

 

Skeleton Warrior
Creature Type: Undead
Ancestry: Human
Role: Warrior

 

 

Orc Chieftain
Creature Type: Humanoid
Ancestry: Orc
Role: Leader

 

This structure is more expressive, more flexible, and more future-proof.


Role Versus Class

Not all miniatures represent adventurers. A miniature site needs broader language than traditional role-playing game classes.

Instead of using only:

 

Wizard
Fighter
Cleric
Rogue

 

a broader Role taxonomy can support both adventurers and ordinary figures.

Examples:

 

Fighter
Wizard
Priest
Merchant
Craftsman
Guard
Peasant
Villager
Noble
Scholar
Monster
Leader
Animal
Civilian

 

Examples:

 

Village Idiot
Creature Type: Humanoid
Ancestry: Human
Role: Villager

 

 

Elven Mage
Creature Type: Humanoid
Ancestry: Elf
Role: Wizard

 

 

Town Blacksmith
Creature Type: Humanoid
Ancestry: Human
Role: Craftsman

 

The same taxonomy can apply to characters, miniatures, and even people when useful.


D&D Beyond Integration

Characters should exist as first-class Drupal entities.

D&D Beyond can serve as an optional external reference, but Drupal should remain the authoritative source for the site’s content model.

Potential Character fields:

 

Name
Biography
Campaign
Portrait
D&D Beyond URL
Imported Metadata
`

 

Recommended relationship model:

 

Drupal Character
       ^
       |
depicted by
       |
Miniature

 

Benefits include:

  1. Characters with no miniatures
  2. Multiple miniatures representing one character
  3. Campaign tracking
  4. Future integration opportunities
  5. Independence from an external platform

Proposed Contraptions Data Model

The same principles apply to Contraptions.

Rather than structuring the site as:

 

Projects
└─ Photos

 

the site can model a broader ecosystem of instruments, components, technologies, articles, media, and people.


User

A User represents a site participant.

Examples:

 

Builder
Artist
Musician
Designer
Contributor
Author

 

Users may create articles, document projects, build instruments, or contribute media.


Contraption

A Contraption represents a physical or conceptual object.

Examples:

 

Topsy Street Organ
Steam Tractor
Calliope
Automaton
Rackett Prototype
Mechanical Xylophone

 

Suggested fields:

 

Name
Description
Builder
Status
Start Date
Completion Date
Photos
Videos
Sound Samples
Documentation
Related Articles
Related Components
Related Technologies

 

The Contraption should serve as the center of the content model.

Example:

 

Topsy Street Organ
├─ Photos
├─ Videos
├─ Build Logs
├─ Sound Samples
├─ Technical Documentation
├─ Components
└─ Technologies

 


Component

A Component represents a physical part, subsystem, mechanism, or module.

Examples:

 

MIDI Controller
Pallet Magnet Assembly
Bellows
Drum Actuator
Pipe Chest
Snare Mechanism
MIDI Reader

 

Relationships:

 

Component
└─ used by → Contraption

 

However, components may have flexible boundaries. A component may become complex enough to qualify as a contraption. Likewise, a contraption may become a component of a larger contraption.

For that reason, Drupal should support related contraptions and component relationships rather than force a rigid hierarchy.

Example:

 

MIDI Controller
├─ used by Topsy Street Organ
├─ used by Rackett Prototype
└─ used by Mechanical Xylophone

 


Technology

A Technology represents a reusable technical concept, mechanism, or method.

Examples:

 

MIDI
Pneumatics
Book Music
Pinned Cylinder
Electromagnets
Arduino
Stepper Motors
Pallet Magnets
Tracker Bar
Bellows

 

Technologies should usually be taxonomy terms or reference entities, depending on how much detail each technology requires.

If the site only needs to tag content, taxonomy works well.

If each technology needs its own description, photos, articles, and history, then Technology may deserve its own content type.


Contraption Relationships

Potential relationship types include:

 

uses component
part of
derived from
successor to
inspired by
built by
documented by
uses technology

 

Example:

 

Topsy Street Organ
├─ uses MIDI Reader
├─ uses Drum Actuator
├─ uses Pallet Magnet Assembly
├─ uses MIDI
├─ inspired by Previous Organ
└─ successor to Earlier Prototype

 

This structure allows Drupal to reveal relationships automatically instead of requiring every page to be manually assembled.


Media Management Lessons

One challenge involved image organization.

The original goal was complete normalization:

 

Single Image
├─ referenced by Article
├─ referenced by Contraption
└─ referenced by Book Page

 

That approach is technically clean because it prevents duplicate files. However, it can become cumbersome if every relationship requires manual Media references.

A more practical model is:

 

Contraption
└─ Gallery Images


 

Article
└─ References Contraption

 

Then the article can display:

 

Its own images
Images attached to the related contraption
Other articles about the same contraption
Related technologies
Related components

 

This keeps the file storage normalized while reducing manual relationship maintenance.

For build logs, images may also live naturally inside the article body through media embeds or paragraphs. The Media entity still stores the actual file once, but the editor can place the image where it makes sense narratively.


Dynamic Views Instead of Manual Galleries

Entity-oriented design shifts much of the organizational burden from the editor to Drupal.

Instead of manually creating:

Topsy Photo Gallery

Drupal can generate:

All media where Related Contraption = Topsy

Instead of manually creating:

Kevin White Sculpt Gallery

Drupal can generate:

All miniatures where Sculptor = Kevin White

Instead of manually maintaining:

MIDI Projects Page

Drupal can generate:

All contraptions where Technology = MIDI

In this model:

 

Galleries become Views.
Categories become taxonomies.
Albums become dynamic collections.
Metadata becomes the primary asset.

 


Content Type Consolidation

A related design lesson involves content type granularity.

If content frequently needs to move between types, such as:

 

Article → Build Log
Build Log → Documentation
Documentation → Project

 

that may indicate too many content types.

In many cases, it may be better to use one flexible content type:

Article

with taxonomy terms such as:

 

Build Log
How-To
Reference
Historical Note
Review
Project Update
Technical Article

 

Content types should represent genuinely different entities, not merely different presentation styles.

For Contraptions, the durable content types may be:

 

Contraption
Person
Article

 

with Media and Taxonomy supporting them.

For Cheddarmongers, the durable content types may be:

 

Miniature
Character
Person
Article

 

with Media and Taxonomy supporting them.


Shared Architecture Between Cheddarmongers and Contraptions

Although Cheddarmongers and Contraptions appear to cover very different subjects, they share the same underlying model.

Both sites include:

 

People
Objects
Articles
Media
Taxonomies
Relationships

 

The domain-specific entities differ.

Cheddarmongers:

 

Miniature
Character
Manufacturer
Sculptor
Painter

 

Contraptions:

 

Contraption
Component
Technology
Builder
Instrument

 

But the pattern remains the same:

 

Object
├─ described by Articles
├─ depicted by Media
├─ created by People
├─ categorized by Taxonomy
└─ connected to other Objects

 

That shared structure means the two sites can use similar Drupal patterns even when their subject matter differs.


Practical Drupal Implementation Philosophy

When designing the Drupal content model, ask:

What real-world thing am I describing?

Better questions:

 

What contraption does this article describe?
Who built this instrument?
Which technology does this project use?
Which miniature does this photo depict?
Who sculpted this figure?
Which character does this miniature represent?

 

Less useful starting questions:

 

What page should this go on?
Which album should contain this photo?
Which menu should hold this item?

 

Menus, landing pages, galleries, and indexes can come later. Drupal Views can generate them from the underlying relationships.

The hard part is getting the entities and relationships right.


Recommended High-Level Architecture

A combined entity-oriented architecture for both sites might look like this:

 

Entities
├─ Person
├─ User
├─ Miniature
├─ Character
├─ Contraption
├─ Component
├─ Organization
├─ Technology
└─ Article


 

Media
├─ Images
├─ Video
├─ Audio
└─ Documents


 

Taxonomy
├─ Tags
├─ Genre
├─ Role
├─ Creature Type
├─ Ancestry
├─ Manufacturer
├─ Contraption Type
├─ Technology Type
├─ Material
└─ Status


 

Relationships
├─ built by
├─ painted by
├─ sculpted by
├─ owned by
├─ depicts
├─ used by
├─ part of
├─ derived from
├─ inspired by
├─ successor to
└─ documented in

 


Final Conclusion

The major takeaway is that both Cheddarmongers and Contraptions should be designed as knowledge systems rather than galleries.

Photos remain important, but they become attributes of richer entities. Articles remain important, but they become documentation about people, objects, technologies, and creative work.

The modern Drupal architecture should focus on:

 

People
Characters
Miniatures
Contraptions
Components
Technologies
Articles
Organizations
Media
Taxonomies
Relationships

 

This approach provides several advantages:

  1. It preserves metadata as a first-class asset.
  2. It avoids duplicate images and duplicate content.
  3. It allows one object to appear in many dynamic collections.
  4. It supports long-term growth.
  5. It allows Drupal Views to generate galleries, timelines, indexes, and related-content sections automatically.
  6. It treats both sites as living archives rather than static albums.
  7. It remains understandable even after the original folder structures and legacy gallery software have been forgotten.

In short:

The folder is not the truth. The entity is the truth.

A successful Drupal 11 rebuild should not merely recreate the old Gallery2 hierarchy. It should preserve the knowledge that hierarchy was trying to express and then make that knowledge easier to maintain, discover, and extend.

Project type

Music symbology

Music symbology

Image
Music symbols

This page collects commonly used music symbols — especially accidentals, clefs, and notation marks — so they’re easy to copy and paste into web content, documentation, or project notes. All characters below are standard Unicode and work in CKEditor 5, HTML, and most text fields.

♯ ♭ ♮ 𝄪 𝄫 ♪ ♫ 𝅘𝅥 𝅗𝅥 𝅝 𝄞 𝄢 𝄐 𝄁 𝄂 𝄆 𝄇
 

🎵 Accidentals

These symbols modify pitch and are the most frequently needed in mechanical‑music documentation.

  • Sharp:
  • Flat:
  • Natural:
  • Double sharp: 𝄪
  • Double flat: 𝄫

Enharmonic examples

  • C♯ / D♭
  • F♯ / G♭
  • G♮ (natural)
  • A𝄪 (double sharp)
  • B𝄫 (double flat)
 

🎶 Notes & Rhythmic Symbols

Useful for describing rhythmic structure, lyric timing, or mechanical playback behavior.

  • Eighth note:
  • Beamed eighth notes:
  • Quarter note: 𝅘𝅥
  • Half note: 𝅗𝅥
  • Whole note: 𝅝
 

🎼 Clefs

Clefs define pitch ranges and are helpful when documenting organ pipes, glockenspiel ranges, or MIDI mappings.

  • Treble clef: 𝄞
  • Bass clef: 𝄢
 

🎚️ Other Notation Marks

These symbols appear in sheet music and can be useful for describing phrasing or mechanical timing.

  • Fermata: 𝄐
  • Barline: 𝄁
  • Double barline: 𝄂
  • Repeat sign (left): 𝄆
  • Repeat sign (right): 𝄇

 

Project type

The Great Cheddarmongers Archaeological Expedition

The Great Cheddarmongers Archaeological Expedition

Introduction

What began as a simple question about migrating a Drupal 6 website and gallery to Drupal 11 evolved into a digital archaeology project spanning more than twenty years of hobbyist history.

The subject of the investigation was Cheddarmongers.org, a community site dedicated to miniature gaming, painting, and related hobbies. Over the years, the site ran on multiple versions of Drupal and relied heavily on Gallery2 for image management. Like many hobby sites of the early internet, it accumulated thousands of photos, tutorials, blog posts, and user contributions.

The challenge was not simply upgrading software. The challenge was identifying and preserving the site's true historical and informational value.


The Original Goal

Initially, the objective was straightforward:

Drupal 6 + Gallery2 integration
    ↓
Drupal 7 + Gallery2 coexistence
    ↓
Drupal 7 + Gallery3 coexistence
    ↓
Drupal 11 + gallery migrated to Drupal Media

 

The site had already been resurrected in DDEV using a backup, and the question was how best to migrate it.

However, as more information surfaced, it became clear that migration was only part of the story.


Discovering the Site's History

Several clues emerged from Wayback Machine captures and old blog posts.

Welcome to Cheddarmongers! | Cheddarmongers (on Wayback)

A September 2007 Wayback capture showed a thriving hobby portal featuring:

  • Gallery
  • Tutorials
  • Blogs
  • Forums
  • Contests
  • User-generated content
  • Recent photos and community activity

This was not just a personal website. It was a functioning hobby community.

An old homepage post from September 29, 2011 provided another important clue:

"My goal has always been to make it so that the links in the site stay so that if you ever link to a picture or page here, your link wouldn't go bad."

This concern for URL permanence became a recurring theme throughout the site's history.


Reconstructing the Technical Timeline

Based on the available evidence, the likely timeline became:

2003–2004

Cheddarmongers launches on Drupal 4.

2004–2005

Migration to Drupal 5.

2005–2011

Long and successful Drupal 5 era.

Gallery2 becomes deeply integrated into the site's identity.

Early 2011

Migration from Drupal 5 to Drupal 6.

2011–2019

Years spent evaluating:

  • Drupal 7
  • Gallery2
  • Gallery3
  • Gallery bridge modules
  • Alternative gallery solutions

By January 2020

A backup restored successfully in DDEV revealed:

  • Drupal 7
  • Gallery2 tables
  • Gallery2 data
  • Gallery3 files

This proved that a Drupal 7 migration had already occurred.

2021–2022

Wayback captures indicate:

  • Gallery integration struggles
  • Site restructuring
  • Decoupling of Gallery2 from Drupal
  • Continued search for sustainable solutions

Solving the /prod Mystery

One mystery involved Wayback captures referencing:

http://www.cheddarmongers.org/prod/

At first glance, this appeared to indicate a migration problem.

Eventually the true explanation emerged.

The original plan had been to implement a small-scale SDLC structure:

 

/dev
/test
/prod

 

The idea was surprisingly enterprise-grade for a hobby website.

In reality, only the /prod environment was ever used. Most development happened directly in production.

This discovery explained why Wayback continued referencing /prod years later.


The Most Important Discovery: g2data Survived

Among all the findings, one stood above the rest.

The original g2data directory still exists.

This is significant because Gallery2 stored its image assets there.

Even if:

  • Drupal fails,
  • Gallery2 fails,
  • modules become unavailable,

the photographs themselves remain preserved.

For a miniature-painting community site, the images represent the most valuable and irreplaceable content.


Gallery2 Was Not Dead

Attempts were made to resurrect Gallery2 using:

  • PHP 5.6
  • MariaDB 5.5

Results were surprisingly positive.

Gallery2:

  • authenticated users,
  • displayed the gallery homepage,
  • displayed user gallery thumbnails,
  • initiated upgrade procedures.

Some images and links were broken, but the system clearly still recognized:

  • its database,
  • its users,
  • its albums,
  • portions of its content.

The conclusion was encouraging:

Gallery2 is not dead. It is merely wounded.


The Database Revelation

Another breakthrough came when examining the database.

Rather than using a separate Gallery2 database, the site contained:

 

Drupal tables
+
g2_* Gallery2 tables

 

in the same MySQL database.

This means the gallery metadata likely survives along with the images.

Potentially recoverable information includes:

  • album structure
  • image captions
  • descriptions
  • upload dates
  • user relationships

Combined with the g2data directory, this dramatically improves recovery prospects.


The Shift to Entity-Oriented Design

The discussion gradually shifted away from migration and toward information architecture.

A key realization emerged:

Gallery2 organized content like this:

 

Album
└─ Album
     └─ Album
         └─ Image

 

But hobby data doesn't naturally fit into hierarchical albums.

A miniature can simultaneously belong to:

  • a manufacturer,
  • a range,
  • a painter,
  • a sculptor,
  • a game system,
  • a genre.

This led to the adoption of an entity-oriented content model.


Building Cheddar2

The proposed successor, Cheddar2, would focus on relationships rather than albums.

Core entities include:

 

Person
Miniature
Character
Article
Tutorial

 

Supporting taxonomies include:

 

Ancestry
Creature Type
Game System
Genre
Manufacturer
Range
Role
Scale
Status
Tags

 

A particularly elegant concept involved the Role taxonomy:

 

Painter
Sculptor
Merchant
Wizard
Villager
Guard

 

The same Role vocabulary can apply to both:

  • real people,
  • fictional characters,
  • miniature subjects.

People as a First-Class Entity

The first new content type created was:

Person

This allows representation of:

  • painters,
  • sculptors,
  • photographers,
  • authors,
  • community members.

Rather than treating people as simple tags, they become fully referenceable entities.

Examples include:

 

Kevin White
Julie Guthrie
David Rosenthal

 

This provides a foundation for rich relationships throughout the site.


The Core Lesson

Perhaps the most important lesson from the investigation was this:

Build the framework first. Then migrate the data.

Rather than modifying the new design to match Gallery2's historical limitations, the recommendation is:

  1. Design the ideal entity model.
  2. Create the entities and relationships.
  3. Map the historical data into that structure.

The old data should inform the framework.

The old data should not dictate the framework.


Current Recommendation

Preservation Sources

The current recovery assets are remarkably complete:

✅ Drupal 7 backup

✅ Gallery2 tables

✅ g2data directory

✅ Gallery2 code

✅ Gallery3 test installation

✅ Wayback Machine captures

✅ Historical blog posts

✅ Original site creator available for consultation

Recovery Strategy

 

D6/D7 + Gallery2
       ↓
Inventory and Understand
       ↓
Define Entity Model
       ↓
Build Drupal 11 Framework
       ↓
Migrate Content
       ↓
Generate Modern Views and Galleries

 

The goal is no longer simply upgrading Drupal.

The goal is preserving two decades of community history while creating a sustainable platform for the future.


Conclusion

What began as an upgrade project became something much larger.

The investigation revealed that Cheddarmongers is not merely a website. It is a historical archive of miniature gaming, painting, tutorials, photography, and community contributions spanning more than twenty years.

The encouraging news is that the evidence increasingly suggests the content survives:

  • the databases survive,
  • the images survive,
  • Wayback captures survive,
  • institutional knowledge survives.

The project has moved beyond recovery and into assessment and design.

The next chapter is not restoring Gallery2.

The next chapter is building Cheddar2—a modern, entity-oriented successor that preserves the past while remaining sustainable for the future.

Project type

Comments

Permalink

I got Gallery2 from 4/2020 up and running (somewhat maybe) on DDEV!!  Next I'm gonna try to get the Drupal6+G2 site working.

Understanding Database Normalization: The Normal Forms

Understanding Database Normalization: The Normal Forms

When designing a database, one of the most important goals is to organize data in a way that minimizes redundancy, improves consistency, and makes updates easier. Database normalization is the process of structuring data according to a set of rules known as normal forms.

Normalization helps answer a simple question:

"Where should a piece of information be stored so that it exists in exactly one place?"

Without normalization, databases often suffer from duplicated data, inconsistent values, and difficult maintenance. With normalization, data becomes easier to manage and relationships between entities become clearer.

Why Normalize Data?

Consider a simple table containing information about people, organizations, and roles:

PersonOrganizationRole
Bob SmithAcme CorpEngineer
Bob SmithMakers GuildTreasurer
Jane JonesAcme CorpManager

This structure looks simple at first, but problems quickly emerge:

  • A person's name may be repeated dozens of times.
  • An organization's name must be updated everywhere if it changes.
  • Deleting the last role for an organization may accidentally remove the organization itself.
  • Adding a new organization requires creating a dummy record.

Normalization addresses these problems by separating data into logical entities and defining relationships among them.


First Normal Form (1NF)

A table is in First Normal Form when:

  • Every column contains a single value.
  • No repeating groups exist.
  • Each row can be uniquely identified.

Not 1NF

PersonRoles
Bob SmithEngineer, Treasurer

The Roles field contains multiple values.

1NF

Person IDPerson Name
1Bob Smith
Person IDRole
1Engineer
1Treasurer

Each field now contains only one value.

Drupal Example

A multi-value field in Drupal may appear as multiple database rows behind the scenes rather than a comma-separated list in a single column.


Second Normal Form (2NF)

A table is in Second Normal Form when:

  • It is already in 1NF.
  • Every non-key column depends on the entire primary key.

This issue usually appears in tables with composite keys.

Not 2NF

Person IDOrganization IDOrganization Name
110Acme Corp
210Acme Corp

Organization Name depends only on Organization ID, not on the entire key.

2NF

Organizations table:

Organization IDOrganization Name
10Acme Corp

Membership table:

Person IDOrganization ID
110
210

Organization information is stored once and referenced through keys.


Third Normal Form (3NF)

A table is in Third Normal Form when:

  • It is already in 2NF.
  • Non-key columns depend only on the primary key.
  • No transitive dependencies exist.

A transitive dependency occurs when one non-key column determines another non-key column.

Not 3NF

Person IDZip CodeCity
155402Minneapolis

City depends on Zip Code, not directly on Person ID.

3NF

People table:

Person IDZip Code
155402

Zip table:

Zip CodeCity
55402Minneapolis

The dependency chain has been removed.


Boyce-Codd Normal Form (BCNF)

BCNF is a stricter version of Third Normal Form.

A table satisfies BCNF when:

  • Every determinant is a candidate key.

Most practical databases that reach 3NF also satisfy BCNF, though edge cases involving overlapping candidate keys can require additional decomposition.

BCNF is especially important when a business rule allows multiple candidate keys that each uniquely identify a record.


Fourth Normal Form (4NF)

A table is in Fourth Normal Form when:

  • It is already in BCNF.
  • Independent many-to-many relationships are stored separately.

Not 4NF

PersonHobbyLanguage
BobPaintingEnglish
BobPaintingFrench
BobMusicEnglish
BobMusicFrench

The hobbies and languages are unrelated, yet every combination must be stored.

4NF

Person Hobbies:

PersonHobby
BobPainting
BobMusic

Person Languages:

PersonLanguage
BobEnglish
BobFrench

The duplicated combinations disappear.


Fifth Normal Form (5NF)

A table is in Fifth Normal Form when:

  • It is already in 4NF.
  • Complex many-way relationships can be reconstructed from simpler relationships without introducing incorrect records.

5NF addresses rare situations involving three or more entities with intricate join dependencies.

Most business applications never require deliberate design beyond 4NF.


Domain-Key Normal Form (DKNF)

DKNF represents the theoretical ideal.

A database is in DKNF when every constraint is enforced entirely through:

  • Domain definitions
  • Key definitions

No additional business rules are required to ensure data integrity.

In practice, very few systems achieve full DKNF because business logic often extends beyond simple domains and keys.


A Practical Example

For a site such as Cheddar2, a normalized model might include separate entities for:

  • People
  • Organizations
  • Places
  • Events
  • Artifacts
  • Roles
  • Taxonomy terms

Relationships would be stored independently:

People

  • Bob Smith
  • Jane Jones

Organizations

  • Acme Corp
  • Makers Guild

Roles

  • Engineer
  • Treasurer
  • Manager

Memberships

PersonOrganizationRole
Bob SmithAcme CorpEngineer
Bob SmithMakers GuildTreasurer
Jane JonesAcme CorpManager

In this design:

  • People are stored once.
  • Organizations are stored once.
  • Roles are stored once.
  • Relationships connect them.

This approach avoids duplication and allows a person, organization, or role to be updated in a single location.


The Trade-Off: Normalization vs. Convenience

Normalization improves:

  • Data consistency
  • Data integrity
  • Maintainability
  • Reuse of information

However, highly normalized databases can require many joins to assemble information for display.

Modern systems often use a balance:

  • Normalize operational data.
  • Denormalize selectively for reporting, caching, and search.

Drupal itself follows this philosophy. Content entities, taxonomy terms, users, and media are stored separately and connected through references, while search indexes and caches may contain denormalized data for performance.


Conclusion

Normalization is fundamentally about identifying entities and relationships, then storing each fact in exactly one place. First Normal Form eliminates repeating groups. Second and Third Normal Forms remove partial and transitive dependencies. Higher normal forms address increasingly specialized situations involving keys and relationships.

For most Drupal applications, designing entities and relationships thoughtfully and achieving Third Normal Form provides an excellent balance between flexibility, maintainability, and performance. When modeling a site such as Cheddar2, thinking in terms of people, places, organizations, events, and relationships naturally leads toward a well-normalized design that remains easy to extend as the content grows.

Project type

Comments

Permalink

Yes. In fact, I think your three bullet points are a better teaching tool than the formal definitions.

Normal FormFormal DefinitionPlain-English Version
1NFAtomic values, no repeating groupsDo cells hold one value?
2NFEvery non-key attribute depends on the whole keyDo facts live with the right entity?
3NFNo transitive dependenciesDo facts depend only on the key?

For example:

1NF – Do cells hold one value?

Bad:

PersonRoles
BobEngineer, Treasurer

Good:

PersonRole
BobEngineer
BobTreasurer

Each cell contains a single value.


2NF – Do facts live with the right entity?

Bad:

Person IDOrganization IDOrganization Name
110Acme Corp
210Acme Corp

The fact "Acme Corp" is really a property of the organization, not the person-organization relationship.

Good:

Organizations

Organization IDName
10Acme Corp

Memberships

Person IDOrganization ID
110
210

The organization fact now lives with the organization entity.


3NF – Do facts depend only on the key?

Bad:

Person IDZip CodeCity
155402Minneapolis

The city is not determined by Person ID. It is determined by Zip Code.

Dependency chain:

 

Person ID
    ↓
Zip Code
    ↓
City

 

Good:

People

Person IDZip Code
155402

Zip Codes

Zip CodeCity
55402Minneapolis

Now every fact in each table depends directly on that table's key.


As an architect, I often summarize normalization this way:

  • 1NF: One fact per cell.
  • 2NF: Put facts with the thing they describe.
  • 3NF: Store each fact exactly once.

Or even more briefly:

 

1NF: One value per cell.
2NF: Right fact, right entity.
3NF: No indirect dependencies.

 

That captures about 95% of what most developers and data modelers need to remember in practice. For a Drupal article aimed at a mixed technical audience, I'd actually lead with those three bullets before introducing the formal terminology. They are much more intuitive.