Miscellaneous web stuff
Miscellaneous web stuff
These pages have miscellaneous useful code, snippets, and other 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:
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.
Music symbology
Music symbology
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): 𝄇
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:
| Person | Organization | Role |
|---|---|---|
| Bob Smith | Acme Corp | Engineer |
| Bob Smith | Makers Guild | Treasurer |
| Jane Jones | Acme Corp | Manager |
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
| Person | Roles |
|---|---|
| Bob Smith | Engineer, Treasurer |
The Roles field contains multiple values.
1NF
| Person ID | Person Name |
|---|---|
| 1 | Bob Smith |
| Person ID | Role |
|---|---|
| 1 | Engineer |
| 1 | Treasurer |
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 ID | Organization ID | Organization Name |
|---|---|---|
| 1 | 10 | Acme Corp |
| 2 | 10 | Acme Corp |
Organization Name depends only on Organization ID, not on the entire key.
2NF
Organizations table:
| Organization ID | Organization Name |
|---|---|
| 10 | Acme Corp |
Membership table:
| Person ID | Organization ID |
|---|---|
| 1 | 10 |
| 2 | 10 |
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 ID | Zip Code | City |
|---|---|---|
| 1 | 55402 | Minneapolis |
City depends on Zip Code, not directly on Person ID.
3NF
People table:
| Person ID | Zip Code |
|---|---|
| 1 | 55402 |
Zip table:
| Zip Code | City |
|---|---|
| 55402 | Minneapolis |
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
| Person | Hobby | Language |
|---|---|---|
| Bob | Painting | English |
| Bob | Painting | French |
| Bob | Music | English |
| Bob | Music | French |
The hobbies and languages are unrelated, yet every combination must be stored.
4NF
Person Hobbies:
| Person | Hobby |
|---|---|
| Bob | Painting |
| Bob | Music |
Person Languages:
| Person | Language |
|---|---|
| Bob | English |
| Bob | French |
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
| Person | Organization | Role |
|---|---|---|
| Bob Smith | Acme Corp | Engineer |
| Bob Smith | Makers Guild | Treasurer |
| Jane Jones | Acme Corp | Manager |
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.
Comments
Summary 3 normal forms
Yes. In fact, I think your three bullet points are a better teaching tool than the formal definitions.
| Normal Form | Formal Definition | Plain-English Version |
|---|---|---|
| 1NF | Atomic values, no repeating groups | Do cells hold one value? |
| 2NF | Every non-key attribute depends on the whole key | Do facts live with the right entity? |
| 3NF | No transitive dependencies | Do facts depend only on the key? |
For example:
1NF – Do cells hold one value?
Bad:
| Person | Roles |
|---|---|
| Bob | Engineer, Treasurer |
Good:
| Person | Role |
|---|---|
| Bob | Engineer |
| Bob | Treasurer |
Each cell contains a single value.
2NF – Do facts live with the right entity?
Bad:
| Person ID | Organization ID | Organization Name |
|---|---|---|
| 1 | 10 | Acme Corp |
| 2 | 10 | Acme Corp |
The fact "Acme Corp" is really a property of the organization, not the person-organization relationship.
Good:
Organizations
| Organization ID | Name |
|---|---|
| 10 | Acme Corp |
Memberships
| Person ID | Organization ID |
|---|---|
| 1 | 10 |
| 2 | 10 |
The organization fact now lives with the organization entity.
3NF – Do facts depend only on the key?
Bad:
| Person ID | Zip Code | City |
|---|---|---|
| 1 | 55402 | Minneapolis |
The city is not determined by Person ID. It is determined by Zip Code.
Dependency chain:
Good:
People
| Person ID | Zip Code |
|---|---|
| 1 | 55402 |
Zip Codes
| Zip Code | City |
|---|---|
| 55402 | Minneapolis |
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:
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.
- Log in to post comments