| Type | Naming Convention | Example | Where Used |
|---|---|---|---|
| Directories | lowerCamel case | controller, services, viewModels |
universally |
| Namespaces | lowerCamel Case | app\controllers, app\services |
universally |
| Files | lowerCamel case | header.php, navbar.php |
mostly outside of /app AND in /app/views |
| Class Files | UpperCamel Case | User.php, ProjectCtrl.php |
/app |
| Non-code files | kebab-case (hyphen) | logo-FFF.svg, db-access.png |
images, media, assets |
Because filenames can get very long. the following abbreviations are used:
| Full Name | Abbreviation | Naming | Example |
|---|---|---|---|
| Model | - | Suffix | UserModel.php |
| Dto | - | Suffix | UserIdentityDto.php |
| View | - | Suffix | landingPage.php / login |
| ViewModel | VM | Suffix | UserVM.php |
| Controller | Ctrl | Suffix | UserCtrl.php |
| Service | Serv | Suffix | UserServ.php |
| Repository | Repo | Suffix | UserRepo.php |
| Exception | Exc | Suffix | UserServExc.php / UserRepoExc.php |
| Interface | I | Prefix | IUserServ.php / IUserRepo.php |
| Layer | Throws | Catches | Error Messages |
|---|---|---|---|
| Repository | *BaseRepoExc (impl.) |
PDOException (logs, throws RepoExc (impl.)) |
Technical for developers (Not reachable for end-users) |
| Service | *BaseServExc (impl.) |
Via ServExc::handleRepoCall() |
User-friendly for display |
| Controller | - | ServExc (impl.) & Exception as fallback |
Sets flash messages & redirects to Correct OR Exception specific path |
NOTE: Impl. = Implementation (concrete class, not interface/abstract)
Methods follow: <action><cardinality><property>By<criteria> (e.g., IUserServ::getByEmail,
IUserServ::getUserIdentityById)
- Cardinality should only be used when performing an action on many/more instead of one, e.g.,
IDanceArtistServ::getManyByShowIdorIYummyReservationServ::getManyByRestaurantId - Property is optional if the action is clear without it, e.g.,
IUserRepo::getByIdNOTIUserRepo::getUserById
| Layer | Action | Examples |
|---|---|---|
| Repository | CRUD: create*, get*, exists*,update*, remove*, delete* |
fetchByEmail, existsByUsername, getUserIdentityById |
| Service | Same as repository, but less strict (not requiring 'By') | verifyAccessRole, editAccount, login |
| Controller | <pageName>+Page (GET) OR <action> (POST/PUT/DELETE) |
loginPage (GET), login (POST), editAccount (POST) |
| Pattern | Rule | Example |
|---|---|---|
| Single-line conditions | Omit braces for single statements (implied body) | if ($condition) throw new Exception(); |
| Nested conditions | Always use braces for clarity (explicit body) | if ($outer) { if ($nested) { ... }} |
| Multi-line arrays | [ on the var line, ] on it's own line |
$array = [ 'key' => 'value']; |
| SQL queries | Same logic as multi-line rule | $stmt->execute([ 'key' => $value]); |
- Indentation: 4 spaces
| Type | Usage | Example |
|---|---|---|
| PHPDoc (classes) | Brief description | /** Toast notification component for rendering flash messages */ |
| PHPDoc (methods) | Description + @param + @return + @throws |
/** Returns a user by its ID. * @throws UserRepoExc */ |
| Inline comments | Explain non-obvious logic or decisions | // Temp placeholder value, will be replaced by the service |
| Section headers | Group related code with //region comments |
//region POST Requests ... //endregion |
| TODO (general) | Task without specific assignee | // TODO: Add exceptions |
| TODO (assigned) | Task assigned to specific person | // TODO (Stef): Refactor this method to use exceptions |
PHPDoc tags: Use @param, @return, @throws for interfaces and public methods (implementation methods do
not)
Inline comments: Place above the code block, not on the same line (unless very short)
- Priority (Suggestion): Your brain → Official docs / Forums → Popular Composer/NPM dependencies → AI assistance
- When using AI: Every generated line must be understood, analyzed, and verified for adherence to this style guide
- Preferred AI: Use agentic AI (such as CoPilot) over copy-paste LLM conversations (due to agentic AI having better project context & file awareness)
- Repetition: Repetitive tasks can be done with AI (as long as no new concept needs to be introduced), but must be reviewed for consistency and correctness
- Documentation: Agentic autofill AI (such as CoPilot) can be used and is recommended for use in generating documentation (PHPDoc, comments). As long as the generated text is verified for accuracy and clarity
| File | Description | Example |
|---|---|---|
| ^fest-.*$ | Global components / festival specific components | fest-header, fest-modal, fest-wysiwyg |
| ^dance-.*$ | Dance specific components | dance-artist-card, dance-list |
| ^history-.*$ | History specific components | history-timeline, history-location |
| ^jazz-.*$ | Jazz specific components | jazz-artist-card, jazz-list |
| ^yummy-.*$ | Yummy specific components | yummy-card, yummy-list |
Because tailwind is easily added as classes,
these predefined components are only necessary for frequently used combinations of tailwind classes.
Such as: fest-header, dance-artist-card & yummy-restaurant-card
Don't create new components just for a better name.
Instead, use the base component and customize it with Tailwind classes.
For example, use fest-header bg-red-500 instead of creating a separate dance-header component.
This prevents component bloat and keeps your styling flexible.
Only if your variant is used frequently AND having a significant amount of additions,
should you create a new component with a new name.
When you need size or structural variants (not just color/spacing tweaks),
follow Tailwind's naming convention with suffixes like fest-container-sm or dance-container-lg.
Consider using custom components instead of making them 'shared' with fest- if you think you might change the tailwind
of that component in the future. As this results in other developers having to change their tailwind classes as well,
which can be easily forgotten and cause bugs in their components/views.
Custom colors can also be specified in input @theme. If your colorscheme is too familiar to tailwind's default palette, then just use that.
- PHP Docs: https://www.php.net/manual/en/langref.php
- Composer dependencies: https://packagist.org/explore/popular
- JS Docs (IIFE): https://developer.mozilla.org/en-US/docs/Glossary/IIFE
- NPM dependencies (Sort most downloaded this month): https://www.npmjs.com/search?page=0&q=tailwind&sortBy=downloads_monthly
- Cheatsheet: https://nerdcave.com/tailwind-cheat-sheet
- Docs start: https://tailwindcss.com/docs/utility-first
- Docs colors: https://tailwindcss.com/docs/customizing-colors
- Custom colors: https://uicolors.app/generate/ff0000
- Fonts & Icons: https://fonts.google.com/icons
- AI Icon generator: https://www.recraft.ai/
- Illustrations: https://undraw.co/illustrations
- WCAG Contrast Checker: https://webaim.org/resources/contrastchecker/