Back to Wekan

Where everything is

docs/DeveloperDocs/Directory-Structure.md

10.9927.0 KB
Original Source

Where everything is

The sections below walk through the directories in detail. This table is the whole tree at a glance, because the detail is easy to get lost in - and because for years this page described four directories out of twenty and did not say so.

DirectoryWhat is in it
client/everything the browser runs: Blaze components, their styles, the client-side libraries
server/everything only the server runs: startup, publications, methods, the REST routes, lib/
models/the collections, their schemas, helpers and mutations - shared by both, so a model must never import from server/
imports/shared code that is neither a model nor a component: i18n, the reactive cache, the shared SimpleSchema, startup
packages/the Meteor packages WeKan maintains itself - the accounts integrations (CAS, LDAP, OIDC, Sandstorm), the lockout, markdown
config/the router and the accounts configuration
migrations/one file per database migration, run in order at startup
public/files served as-is: icons, fonts, the web app manifest
private/files the SERVER can read and the client cannot
tests/the suites - *.test.cjs run by tests/run-node-suites.cjs, plus the Playwright and e2e directories
docs/this documentation
releases/how a release is built and published - the bundle steps, the translations tooling, the CHANGELOG tooling
snap/, snap-src/, snap-base-debian/the snap package
sandstorm-src/the Sandstorm package
openapi/the REST API description, generated from the routes
meta/signatures, icons, screenshots, project description
old-CHANGELOG/the CHANGELOG's history, by year and by month (CHANGELOG.md holds the current month)
.tools/NOT part of this repository: the companion repos and toolchains a build needs, ignored by git and by Meteor
node_modules/, .meteor/, .build/generated; never edited, never committed

Two rules that the layout only implies:

  • models/ is shared code. It is loaded on the client too, so a model that imports from server/ breaks the client build. Server-only logic that a model needs lives behind Meteor.isServer or in server/lib/.
  • A .jade file is not picked up by being on disk. Every template is imported by name from client/features/*.js, and a component .js that other components import must import its own .jade - see tests/clientBundleImports.test.cjs and tests/templateRegistration.test.cjs.

Routing

We're using FlowRouter client side router inside config/router.js. For accounts there is AccountsTemplates configured in config/accounts.js.

Client

public

Files in this directory are served by meteor as-is to the client. It hosts some (fav)icons and fonts. svg-etc/manifest.json: goes into link rel="manifest" in the header of the generated page and is a Web App Manifest.

components

  • activities:
    • activities.jade: activities template for the list of activities placed inside a sidebar-content; uses boardActivities or cardActivities depending on mode; <span style="color:red">XXX: does this mean that sidebar should be visible in board list mode? when does the board activity gets shown?</span>
    • comments.jade: commentForm template used in card-details-canvas for adding comments;
  • boards:
    • boardArchive.jade: archivedBoards template for the modal dialog showing the list of archived boards that might be restored;
    • boardBody.jade: top level template for presenting a board is board and, based on screen size and current state, it uses either cardDetails or boardBody templates; boardBody is the one including the sidebar, each list, cardDetails for larger screens when a card is selected and the addListForm for adding a new list (also defined in this file);
    • boardHeader.jade: boardHeaderBar, boardMenuPopup, boardVisibilityList, boardChangeVisibilityPopup, boardChangeWatchPopup, boardChangeColorPopup, createBoard, chooseBoardSource, boardChangeTitlePopup, archiveBoardPopup, outgoingWebhooksPopup;
    • boardsList.jade: boardList and boardListHeaderBar for the list of boards in the initial screen;
  • cards:
    • attachments.jade: cardAttachmentsPopup, previewClipboardImagePopup, previewAttachedImagePopup, attachmentDeletePopup, attachmentsGalery;
    • cardDate.jade: editCardDate and dateBadge templates;
    • cardDetails.jade: boardsAndLists is the usual layout for a board display with boardLists being used in sandstorm where each board is independent;cardDetails, editCardTitleForm, cardDetailsActionsPopup, moveCardPopup, copyCardPopup,cardMembersPopup,cardMorePopup, cardDeletePopup;
    • cardTime.jade: editCardSpentTime and timeBadge templates;
    • checklists.jade: checklists, checklistDetail, checklistDeleteDialog, addChecklistItemForm, editChecklistItemForm, checklistItems, itemDetail;
    • labels.jade: formLabel, createLabelPopup, editLabelPopup, deleteLabelPopup, cardLabelsPopup;
    • minicard.jade: has the minicard template
  • forms: inlinedform.jade has theinlinedForm template;
  • import:
  • lists:
    • list.jade: list is the simple, main template for lists;
    • listBody.jade: listBody, addCardForm, autocompleteLabelLine templates;
    • listHeader.jade: listHeader, editListTitleForm, listActionPopup, boardLists, listMorePopup, listDeletePopup, setWipLimitPopup, wipLimitErrorPopup templates;
  • main:
    • editor.jade: editor and viewer templates;
    • header.jade: header and offlineWarning templates; if the user is connected we display a small "quick-access" top bar that list all starred boards with a link to go there (this is inspired by the Reddit "subreddit" bar); the first link goes to the boards page;
    • keyboardShortcuts.jade: shortcutsHeaderBar, shortcutsModalTitle, keyboardShortcuts - all for the shortcuts that are presented when you press ?re implemented inhere;
    • layouts.jade: has the template for head portion of the html page and other general purpose templates: userFormsLayout, defaultLayout, notFound, message;
    • popup.tpl.jade: tpl files only define a single template so there's no need to wrap content in a template tag; the name of the template is the base name of the file (popup in this case);
  • settings:
    • informationBody.jade: the statistics template — the Version pane of Admin Panel / Settings, five tables (Platform, OS, Meteor, Database, Node). There is no information template any more: it is a pane rendered by settingBody.jade, not a page;
    • invitationCode.jade: invitationCode template;
    • peopleBody.jade: people, peopleGeneral, peopleRow, editUserPopup;
    • settingBody.jade: setting, general, email, accountSettings, announcementSettings
    • settingHeader.jade: settingHeaderBar template;
  • sidebar:
    • sidebar.jade: sidebar, homeSidebar, membersWidget, labelsWidget, memberPopup, removeMemberPopup, leaveBoardPopup, addMemberPopup, changePermissionsPopup
    • sidebarArchives.jade: archivesSidebar
    • sidebarFilters.jade: filterSidebar, multiselectionSidebar, disambiguateMultiLabelPopup, disambiguateMultiMemberPopup, moveSelectionPopup;
  • users:
    • userAvatar.jade: userAvatar, userAvatarInitials, userPopup, memberName, changeAvatarPopup, cardMemberPopup
    • userHeader.jade: headerUserBar, memberMenuPopup, editProfilePopup, editNotificationPopup, changePasswordPopup, changeLanguagePopup, changeSettingsPopup;

features

client/features is the list of what the client LOADS. One file per area - boards.js, cards.js, settings.js, main.js and so on - each importing that area's .jade, then its .js, then its .css, and client/imports.js imports them all. A component that is not named here is not in the bundle, however finished it is: tests/templateRegistration.test.cjs fails when a template is included by name and never imported.

config

lib

  • accessibility.js: define a set of DOM transformations that are specifically intended for blind screen readers;
  • cssEvents.js: the CSSEventsobject has methods that select the name of the event based on the specific transitions and animations;
  • pasteImage.js and dropImage.js: utility for pasting and dropping images on a web app; <span style="color:red">XXX: add comments; not same style as the rest of the code</span>
  • escapeActions.js: defines the behavior (mostly canceling current edit) for escape keyboard key;
  • i18n.js: at startup we choose the language for the ui based on user profile or browser language;
  • inlinedform.js: forms for editing a single field (like adding a card); <span style="color:red">XXX: comments in code suggest that a form that is not submitted will retain its value to prevent data loss using unsavedEdits.js;bug?</span>; <span style="color:red">XXX: edit button to save and open</span>;
  • cardMenuSource.js: says which hamburger opened the card's action menu — the opened card's or a minicard's — so its first entry is Show on Card or Show on Minicard;
  • minicardLabelText.js: reads and writes the personal Hide minicard label text setting (the user's profile, or this browser when nobody is logged in), used by the minicard and by Minicard menu / Show on Minicard;
  • sectionCaret.js: which way a collapsible section's caret points — down when open, and toward the text when closed, mirrored in right-to-left languages — shared by the card's sections and the board sidebar's Activities;
  • keyboard.js: the shortcuts that are presented when you press ?re implemented inhere;
  • popup.js: defines Popup class for things likes electing a date; <span style="color:red">XXX: not a Blaze helper?</span>
  • textComplete.js: extends jquery-textcomplete to integrate with the rest of the system (like escape actions, tab and enter key handling); <span style="color:red">XXX: deprecated?</span>
  • utils.js: various methods all over the place (resize, screen size, sort, capitalize, navigate to board and card);
  • Blaze helpers:
    • filter.js: registers Filter Blaze helper to support filtering cards by labels and by members;
    • modal.js: registers Modal Blaze helper to support showing modal windows like the one for archived boards;
    • multiSelection.js: registers Modal Blaze helper to support multiple selection mode;
    • unsavedEdits.js: registers getUnsavedValue and hasUnsavedValue Blaze helpers to preserve content entered in fields but not saved;

Server

.js files in this directory are not available to the client.

The four directories that hold most of it:

  • server/lib - the server-only libraries the rest of it calls. The security log and the event-log fold that Admin Panel / Problems is built on, the login throttle and timing defence, the database problem classifier, the API usage counter, the recovery and migration helpers.

  • server/methods - Meteor methods that are not part of a model: the backups, the repairs, the reports the Admin Panel calls.

  • server/publications - what the client may subscribe to, and with which fields.

  • server/routes - the HTTP routes that are not the REST API: the avatar server, the attachment routes, the custom head assets. The REST API itself is registered by the models, in front of server/apiMiddleware.js - body parsing, the WITH_API gate, bearer-token authentication, and the usage counting behind Admin Panel / Problems / API.

  • server/startup and the 00*.js files at the top - what runs before anything else, in name order: the startup checks, waiting for the database, the retry-on-busy wrapper, the error handlers.

  • statistics.js implements a Meteor server-only method for general-purpose information such as OS, memory, CPUs, PID of the process and so on.

  • migrations.js is where code that update sold databases to new schema is located. Anytime the schema of one of the collection changes in a non-backward compatible way a migration needs to be written in this file.

  • authentication.js add the Authenticationobject to Meteor that provides methods for checking access rights.

  • lib/utils.js defines some checks used by checklists.js** model. <span style="color:red">XXX: these methods are defined in server-only code by are used in models, which are visible by the client (in Checklists.allow)?</span>

  • notifications

    • notifications.js: defines the Notifications object that supports Activities and holds a list of functions to call when its notify() method is called along with convenience methods to subscribe, unsubscribe and a way to filter recipients according to user settings for notification;
      • email.js: makes use of the notification system to send an email to a user;
      • profile.js: stub; will allow associating notifications with user ids to be consumed by mobile apps;
    • notifications.js: adds the watch() Meteor server-only method that may watch boards, lists or cards using models/watchable.js;
    • outgoing.js: adds the outgoingWebhooks() Meteor server-only method that can call external API <span style="color:red">XXX: I guess</span>
  • publications defines sets of records that are published by the server and how clients can subscribe to those:

Models

The files in models directory mainly define collections; most of them have aldeed SimpleSchema for automatic validation of insert and update of collections. This is also where helpers, mutations, methods, hooks and bootstrap code is to be found. Server side code also implements json REST API.

models/lib is the other half of this directory, and by file count the larger one: the PURE modules a model, the server and the client all share - the event-log summary shape, the address classifier, the admin URLs and menus, the shared table page, the lockout state, the map links. They are plain CommonJS with no Meteor in them, which is what lets tests/*.test.cjs run them under bare node and test a decision as arithmetic rather than through a server.

Collections (mostly Mongo.Collection except as noted) are defined in:

Other files:

  • watchable.js: extends the schema, helpers and mutations of Boards, Lists and Cards.
  • export.js: has some code to support the REST API.
  • import.js: implements importBoard() method so that Trello (in trelloCreator.js) and Wekan (in wekanCreator.js) boards can be imported. <span style="color:red">XXX: Solid candidates for a directory of their own.</span>

Tools

Building, releasing and testing

  • build.sh / build.bat - the menu that installs dependencies, builds WeKan and runs the tests. Its Setup menu builds either the release bundle (what a release publishes, minus the .zip) or the development bundle (plain meteor build).
  • releases/ - one script per step of a release, and the same scripts the GitHub workflow runs, so a release can be reproduced locally:
  • tests/ - *.test.cjs suites run by run-node-suites.cjs (all of them, with every failure listed at the end), plus the Playwright browser tests and the e2e/import suites. Many of them READ THE SOURCE and pin a behaviour, which is what makes "and this mistake is nowhere else in the tree" checkable.
  • .github/workflows - release-all.yml is the release: the bundles for every platform, the Docker images, the snaps, and the GitHub Release they attach to.

Info


Contributions to this page

This page was contributed by TNick and xet7 when WeKan was at commit e2f768c, and it described the tree as it was then for a long time afterwards: fourteen of its links pointed at files that had moved or been deleted, and two thirds of the repository - imports/, packages/, releases/, tests/, docs/, migrations/, server/lib, server/methods, server/routes, models/lib, client/features - was not mentioned at all.

Please add new files, fixes and updates directly to this page. tests/docsLinksResolve.test.cjs fails when a link here points at something that is not in the tree, which is what let the fourteen rot unnoticed: a https://github.com/wekan/wekan/tree/main/... link looks fine in an editor and 404s only for the reader.