diff --git a/docs/content/doc/development/cli.md b/docs/content/doc/development/cli.md index 9e9e6f2f3..c4238a89c 100644 --- a/docs/content/doc/development/cli.md +++ b/docs/content/doc/development/cli.md @@ -1,6 +1,6 @@ --- date: "2019-03-31:00:00+01:00" -title: "Adding new cli commands" +title: "Cli Commands" draft: false type: "doc" menu: diff --git a/docs/content/doc/development/config.md b/docs/content/doc/development/config.md new file mode 100644 index 000000000..1fe6af29b --- /dev/null +++ b/docs/content/doc/development/config.md @@ -0,0 +1,41 @@ +--- +date: "2019-02-12:00:00+02:00" +title: "Configuration Options" +draft: false +type: "doc" +menu: + sidebar: + parent: "development" +--- + +# Configuration options + +All configuration variables are declared in the `config` package. +It uses [viper](https://github.com/spf13/viper) under the hood to handle setting defaults and parsing config files. +Viper handles parsing all different configuration sources. + +## Adding new config options + +To make handling configuration parameters a bit easier, we introduced a `Key` string type in the `config` package which +you can call directly to get a config value. + +To add a new config option, you should add a new key const to `pkg/config/config.go` and possibly a default value. +Default values should always enable the feature to work or turn it off completely if it always needs +additional configuration. + +Make sure to also add the new config option to the default config file (`config.yml.sample` at the root of the repository) +with an explanatory comment to make sure it is well documented. +Then run `mage generate-docs` to generate the configuration docs from the sample file. + +## Getting Configuration Values + +To retreive a configured value call the key with a getter for the type you need. +For example: + +{{< highlight golang >}} +if config.CacheEnabled.GetBool() { + // Do something with enabled caches +} +{{< /highlight >}} + +Take a look at the methods declared on the type to see what's available. diff --git a/docs/content/doc/development/cron.md b/docs/content/doc/development/cron.md new file mode 100644 index 000000000..bb78d1ec9 --- /dev/null +++ b/docs/content/doc/development/cron.md @@ -0,0 +1,35 @@ +--- +title: "Cron Tasks" +date: 2021-07-13T23:21:52+02:00 +draft: false +menu: + sidebar: + parent: "development" +--- + +# How to add a cron job task + +Cron jobs are tasks which run on a predefined schedule. +Vikunja uses these through a light wrapper package around the excellent [github.com/robfig/cron](https://github.com/robfig/cron) package. + +The package exposes a `cron.Schedule` method with two arguments: The first one to define the schedule when the cron task +should run, and the second one with the actual function to run at the schedule. +You would then create a new function to register your the actual cron task in your package. + +A basic function to register a cron task looks like this: + +{{< highlight golang >}} +func RegisterSomeCronTask() { + err := cron.Schedule("0 * * * *", func() { + // Do something every hour + } +} +{{< /highlight >}} + +Call the register method in the `FullInit()` method of the `init` package to actually register it. + +## Schedule Syntax + +The cron syntax uses the same on you may know from unix systems. + +It is described in detail [here](https://pkg.go.dev/github.com/robfig/cron#hdr-CRON_Expression_Format). diff --git a/docs/content/doc/development/database.md b/docs/content/doc/development/database.md new file mode 100644 index 000000000..b63022837 --- /dev/null +++ b/docs/content/doc/development/database.md @@ -0,0 +1,40 @@ +--- +date: "2019-02-12:00:00+02:00" +title: "Database" +draft: false +type: "doc" +menu: + sidebar: + parent: "development" +--- + +# Database + +Vikunja uses [xorm](http://xorm.io/) as an abstraction layer to handle the database connection. +Please refer to [their](http://xorm.io/docs/) documentation on how to exactly use it. + +{{< table_of_contents >}} + +## Using the database + +When using the common web handlers, you get an `xorm.Session` to do database manipulations. +In other packages, use the `db.NewSession()` method to get a new database session. + +## Adding new database tables + +To add a new table to the database, create the struct and [add a migration for it]({{< ref "db-migrations.md" >}}). + +To learn more about how to configure your struct to create "good" tables, refer to [the xorm documentaion](http://xorm.io/docs/). + +In most cases you will also need to implement the `TableName() string` method on the new struct to make sure the table +name matches the rest of the tables - plural. + +## Adding data to test fixtures + +Adding data for test fixtures can be done via `yaml` files in `pkg/models/fixtures`. + +The name of the yaml file should match the table name in the database. +Adding values to it is done via array definition inside it. + +**Note**: Table and column names need to be in snake_case as that's what is used internally in the database +and for mapping values from the database to xorm so your structs can use it. diff --git a/docs/content/doc/development/db-migrations.md b/docs/content/doc/development/db-migrations.md index 98a247580..397828726 100644 --- a/docs/content/doc/development/db-migrations.md +++ b/docs/content/doc/development/db-migrations.md @@ -1,6 +1,6 @@ --- date: "2019-03-29:00:00+02:00" -title: "Database migrations" +title: "Database Migrations" draft: false type: "doc" menu: @@ -37,6 +37,11 @@ All migrations are sorted before being executed, since `init()` does not guarant When you're adding a new struct, you also need to add it to the `models.GetTables()` function to ensure it will be created on new installations. +### Generating a new migration stub + +You can easily generate a pre-filled migration stub by running `mage dev:make-migration`. +It will ask you for a table name and generate an empty migration similar to the example shown below. + ### Example {{< highlight golang >}} diff --git a/docs/content/doc/development/development.md b/docs/content/doc/development/development.md index 6bf1dd514..426b702db 100644 --- a/docs/content/doc/development/development.md +++ b/docs/content/doc/development/development.md @@ -12,56 +12,11 @@ menu: # Development -We use go modules to vendor libraries for Vikunja, so you'll need at least go `1.11` to use these. -If you don't intend to add new dependencies, go `1.9` and above should be fine. +We use go modules to manage third-party libraries for Vikunja, so you'll need at least go `1.11` to use these. To contribute to Vikunja, fork the project and work on the main branch. A lot of developing tasks are automated using a Magefile, so make sure to [take a look at it]({{< ref "mage.md">}}). -{{< table_of_contents >}} - -## Libraries - -We keep all libraries used for Vikunja around in the `vendor/` folder to still be able to build the project even if -some maintainers take their libraries down like [it happened in the past](https://github.com/jteeuwen/go-bindata/issues/5). - -## Tests - -See [testing]({{< ref "test.md">}}). - -#### Development using go modules - -If you're able to use go modules, you can clone the project wherever you want to and work from there. - -#### Development-setup without go modules - -Some internal packages are referenced using their respective package URL. This can become problematic. -To “trick” the Go tool into thinking this is a clone from the official repository, download the source code -into `$GOPATH/code.vikunja.io/api`. Fork the Vikunja repository, it should then be possible to switch the source directory on the command line. - -{{< highlight bash >}} -cd $GOPATH/src/code.vikunja.io/api -{{< /highlight >}} - -To be able to create pull requests, the forked repository should be added as a remote to the Vikunja sources, otherwise changes can’t be pushed. - -{{< highlight bash >}} -git remote rename origin upstream -git remote add origin git@git.kolaente.de:/api.git -git fetch --all --prune -{{< /highlight >}} - -This should provide a working development environment for Vikunja. Take a look at the Magefile to get an overview about -the available tasks. The most common tasks should be `mage test:unit` which will start our test environment and `mage build:build` -which will build a vikunja binary into the working directory. Writing test cases is not mandatory to contribute, but it -is highly encouraged and helps developers sleep at night. - -That’s it! You are ready to hack on Vikunja. Test changes, push them to the repository, and open a pull request. - -## Static assets - -Each Vikunja release contains all static assets directly compiled into the binary. -To prevent this during development, use the `dev` tag when developing. - -See the [mage docs](mage.md#statically-compile-all-templates-into-the-binary) about how to compile with static assets for a release. +Make sure to check the other doc articles for specific development tasks like [testing]({{< ref "test.md">}}), +[database migrations]({{< ref "db-migrations.md" >}}) and the [project structure]({{< ref "structure.md" >}}). diff --git a/docs/content/doc/practical-instructions/errors.md b/docs/content/doc/development/errors.md similarity index 98% rename from docs/content/doc/practical-instructions/errors.md rename to docs/content/doc/development/errors.md index dac3bb3e4..22fe9fa59 100644 --- a/docs/content/doc/practical-instructions/errors.md +++ b/docs/content/doc/development/errors.md @@ -5,7 +5,7 @@ draft: false type: "doc" menu: sidebar: - parent: "practical instructions" + parent: "development" --- # Custom Errors diff --git a/docs/content/doc/development/events-and-listeners.md b/docs/content/doc/development/events-and-listeners.md index 96e34118c..46f5c0896 100644 --- a/docs/content/doc/development/events-and-listeners.md +++ b/docs/content/doc/development/events-and-listeners.md @@ -28,11 +28,11 @@ This document explains how events and listeners work in Vikunja, how to use them Each event has to implement this interface: -```golang +{{< highlight golang >}} type Event interface { Name() string } -``` +{{< /highlight >}} An event can contain whatever data you need. @@ -75,7 +75,7 @@ To dispatch an event, simply call the `events.Dispatch` method and pass in the e The `TaskCreatedEvent` is declared in the `pkg/models/events.go` file as follows: -```golang +{{< highlight golang >}} // TaskCreatedEvent represents an event where a task has been created type TaskCreatedEvent struct { Task *Task @@ -86,11 +86,11 @@ type TaskCreatedEvent struct { func (t *TaskCreatedEvent) Name() string { return "task.created" } -``` +{{< /highlight >}} It is dispatched in the `createTask` function of the `models` package: -```golang +{{< highlight golang >}} func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err error) { // ... @@ -102,7 +102,7 @@ func createTask(s *xorm.Session, t *Task, a web.Auth, updateAssignees bool) (err // ... } -``` +{{< /highlight >}} As you can see, the curent task and doer are injected into it. @@ -122,13 +122,13 @@ A single event can have multiple listeners who are independent of each other. All listeners must implement this interface: -```golang +{{< highlight golang >}} // Listener represents something that listens to events type Listener interface { Handle(msg *message.Message) error Name() string } -``` +{{< /highlight >}} The `Handle` method is executed when the event this listener listens on is dispatched. * As the single parameter, it gets the payload of the event, which is the event struct when it was dispatched decoded as json object and passed as a slice of bytes. @@ -165,7 +165,7 @@ See the example below. ### Example -```golang +{{< highlight golang >}} // RegisterListeners registers all event listeners func RegisterListeners() { events.RegisterListener((&ListCreatedEvent{}).Name(), &IncreaseListCounter{}) @@ -183,13 +183,13 @@ func (s *IncreaseTaskCounter) Name() string { func (s *IncreaseTaskCounter) Handle(payload message.Payload) (err error) { return keyvalue.IncrBy(metrics.TaskCountKey, 1) } -``` +{{< /highlight >}} ## Testing When testing, you should call the `events.Fake()` method in the `TestMain` function of the package you want to test. This prevents any events from being fired and lets you assert an event has been dispatched like so: -```golang +{{< highlight golang >}} events.AssertDispatched(t, &TaskCreatedEvent{}) -``` +{{< /highlight >}} diff --git a/docs/content/doc/practical-instructions/feature.md b/docs/content/doc/development/feature.md similarity index 94% rename from docs/content/doc/practical-instructions/feature.md rename to docs/content/doc/development/feature.md index 0c50caf39..ca443e586 100644 --- a/docs/content/doc/practical-instructions/feature.md +++ b/docs/content/doc/development/feature.md @@ -1,11 +1,11 @@ --- date: "2019-02-12:00:00+02:00" -title: "Add a new api endpoint" +title: "New API Endpoints" draft: false type: "doc" menu: sidebar: - parent: "practical instructions" + parent: "development" --- # Add a new api endpoint/feature diff --git a/docs/content/doc/development/mage.md b/docs/content/doc/development/mage.md index 67541dbf1..d2d309f56 100644 --- a/docs/content/doc/development/mage.md +++ b/docs/content/doc/development/mage.md @@ -57,15 +57,13 @@ These tasks are automatically run in our CI every time someone pushes to main or mage build:build {{< /highlight >}} -Builds a `vikunja`-binary in the root directory of the repo for the platform it is run on. - -### Statically compile all templates into the binary +or {{< highlight bash >}} -mage build:generate +mage build {{< /highlight >}} -This generates static code with all templates, meaning no template need to be referenced at runtime. +Builds a `vikunja`-binary in the root directory of the repo for the platform it is run on. ### clean @@ -73,7 +71,7 @@ This generates static code with all templates, meaning no template need to be re mage build:clean {{< /highlight >}} -Cleans all build, executable and bindata files +Cleans all build and executable files ## Check @@ -173,6 +171,8 @@ mage dev:create-migration Creates a new migration with the current date. Will ask for the name of the struct you want to create a migration for. +See also [migration docs]({{< ref "mage.md" >}}). + ## Misc ### Format the code diff --git a/docs/content/doc/practical-instructions/metrics.md b/docs/content/doc/development/metrics.md similarity index 97% rename from docs/content/doc/practical-instructions/metrics.md rename to docs/content/doc/development/metrics.md index a05a971f5..854aaadc4 100644 --- a/docs/content/doc/practical-instructions/metrics.md +++ b/docs/content/doc/development/metrics.md @@ -5,7 +5,7 @@ draft: false type: "doc" menu: sidebar: - parent: "practical instructions" + parent: "development" --- # Metrics @@ -17,7 +17,7 @@ The `metrics` package provides several functions to create and update metrics. {{< table_of_contents >}} -## New metrics +## Exposing New Metrics First, define a `const` with the metric key in redis. This is done in `pkg/metrics/metrics.go`. diff --git a/docs/content/doc/development/migration.md b/docs/content/doc/development/migration.md index bcd3e6c3c..b05f5c0e9 100644 --- a/docs/content/doc/development/migration.md +++ b/docs/content/doc/development/migration.md @@ -63,7 +63,7 @@ if config.MigrationWunderlistEnable.GetBool() { } ``` -You should also document the routes with [swagger annotations]({{< ref "../practical-instructions/swagger-docs.md" >}}). +You should also document the routes with [swagger annotations]({{< ref "swagger-docs.md" >}}). ## Insertion helper method diff --git a/docs/content/doc/development/notifications.md b/docs/content/doc/development/notifications.md index ca39a64d3..14906f4c5 100644 --- a/docs/content/doc/development/notifications.md +++ b/docs/content/doc/development/notifications.md @@ -18,13 +18,13 @@ Vikunjs provides a simple abstraction to send notifications per mail and in the Each notification has to implement this interface: -```golang +{{< highlight golang >}} type Notification interface { ToMail() *Mail ToDB() interface{} Name() string } -``` +{{< /highlight >}} Both functions return the formatted messages for mail and database. @@ -35,7 +35,7 @@ For example, if your notification should not be recorded in the database but onl A list of chainable functions is available to compose a mail: -```golang +{{< highlight golang >}} mail := NewMail(). // The optional sender of the mail message. From("test@example.com"). @@ -54,7 +54,7 @@ mail := NewMail(). Action("The Action", "https://example.com"). // Another line of text. Line("This should be an outro line"). -``` +{{< /highlight >}} If not provided, the `from` field of the mail contains the value configured in [`mailer.fromemail`](https://vikunja.io/docs/config-options/#fromemail). @@ -75,14 +75,14 @@ It takes the name of the notification and the package where the notification wil Notifiables can receive a notification. A notifiable is defined with this interface: -```golang +{{< highlight golang >}} type Notifiable interface { // Should return the email address this notifiable has. RouteForMail() string // Should return the id of the notifiable entity RouteForDB() int64 } -``` +{{< /highlight >}} The `User` type from the `user` package implements this interface. @@ -93,7 +93,7 @@ It takes a notifiable and a notification as input. For example, the email confirm notification when a new user registers is sent like this: -```golang +{{< highlight golang >}} n := &EmailConfirmNotification{ User: update.User, IsNew: false, @@ -101,7 +101,7 @@ n := &EmailConfirmNotification{ err = notifications.Notify(update.User, n) return -``` +{{< /highlight >}} ## Testing diff --git a/docs/content/doc/development/structure.md b/docs/content/doc/development/structure.md index 675897bb1..ca1840b45 100644 --- a/docs/content/doc/development/structure.md +++ b/docs/content/doc/development/structure.md @@ -1,6 +1,6 @@ --- date: "2019-02-12:00:00+02:00" -title: "Project structure" +title: "Project Structure" draft: false type: "doc" menu: @@ -10,40 +10,7 @@ menu: # Project structure -In general, this api repo has the following structure: - -* `docker` -* `docs` -* `pkg` - * `caldav` - * `cmd` - * `config` - * `db` - * `fixtures` - * `files` - * `integration` - * `log` - * `mail` - * `metrics` - * `migration` - * `models` - * `modules` - * `migration` - * `handler` - * `wunderlist` - * `red` - * `routes` - * `api/v1` - * `static` - * `swagger` - * `user` - * `utils` - * `version` -* `REST-Tests` -* `templates` -* `vendor` - -This document will explain what these mean and what you can find where. +This document explains what each package does. {{< table_of_contents >}} @@ -52,18 +19,13 @@ This document will explain what these mean and what you can find where. The root directory is where [the config file]({{< ref "../setup/config.md">}}), [Magefile]({{< ref "mage.md">}}), license, drone config, application entry point (`main.go`) and so on are located. -## docker - -This directory holds additonal files needed to build and run the docker container, mainly service configuration to properly run Vikunja inside a docker -container. - ## pkg This is where most of the magic happens. Most packages with actual code are located in this folder. ### caldav -This folder holds a simple caldav implementation which is responsible for returning the caldav feature. +This folder holds a simple caldav implementation which is responsible for the caldav feature. ### cmd @@ -75,10 +37,15 @@ To learn more about how to use this cli, see [the cli usage docs]({{< ref "../us ### config -This package configures the config. It sets default values and sets up viper and tells it where to look for config files, -how to interpret which env variables for config etc. +This package configures handling of Vikunja's runtime configuration. +It sets default values and sets up viper and tells it where to look for config files, how to interpret which env variables +for config etc. -If you want to add a new config parameter, you should add default value in this package. +See also the [docs about adding a new configuration parameter]({{< ref "config.md" >}}). + +### cron + +See [how to add a cron task]({{< ref "cron.md" >}}). ### db @@ -102,17 +69,17 @@ This init is called in `main.go` after the config init is done. ### mail -This package handles all mail sending. To learn how to send a mail, see [sending emails]({{< ref "../practical-instructions/mail.md">}}). +This package handles all mail sending. To learn how to send a mail, see [notifications]({{< ref "notifications.md" >}}). ### metrics This package handles all metrics which are exposed to the prometheus endpoint. -To learn how it works and how to add new metrics, take a look at [how metrics work]({{< ref "../practical-instructions/metrics.md">}}). +To learn how it works and how to add new metrics, take a look at [how metrics work]({{< ref "metrics.md">}}). ### migration This package handles all migrations. -All migrations are stored and executed here. +All migrations are stored and executed in this package. To learn more, take a look at the [migrations docs]({{< ref "../development/db-migrations.md">}}). @@ -123,11 +90,35 @@ When adding new features or upgrading existing ones, that most likely happens he Because this package is pretty huge, there are several documents and how-to's about it: -* [Adding a feature]({{< ref "../practical-instructions/feature.md">}}) -* [Making calls to the database]({{< ref "../practical-instructions/database.md">}}) +* [Adding a feature]({{< ref "feature.md">}}) +* [Making calls to the database]({{< ref "database.md">}}) ### modules +Everything that can have multiple implementations (like a task migrator from a third-party task provider) lives in a +respective sub package in this package. + +#### auth + +Contains openid related authentication. + +#### avatar + +Contains all possible avatar providers a user can choose to set their avatar. + +#### background + +All list background providers are in sub-packages of this package. + +#### dump + +Handles everything related to the `dump` and `restore` commands of Vikunja. + +#### keyvalue + +A simple key-value store with an implementation for memory and redis. +Can be used to cache values. + #### migration See [writing a migrator]({{< ref "migration.md" >}}). @@ -142,20 +133,19 @@ to talk to redis. It uses the [go-redis](https://github.com/go-redis/redis) library, please see their configuration on how to use it. +**Note**: Only use this package directly if you have to use a direct redis connection. +In most cases, using the `keyvalue` package is a better fit. + ### routes This package defines all routes which are available for vikunja clients to use. -To add a new route, see [adding a new route]({{< ref "../practical-instructions/feature.md">}}). +To add a new route, see [adding a new route]({{< ref "feature.md">}}). #### api/v1 This is where all http-handler functions for the api are stored. Every handler function which does not use the standard web handler should live here. -### static - -All static files generated by `mage generate` live here. - ### swagger This is where the [generated]({{< ref "mage.md#generate-swagger-definitions-from-code-comments">}} [api docs]({{< ref "../usage/api.md">}}) live. @@ -179,23 +169,3 @@ See their function definitions for instructions on how to use them. The single purpouse of this package is to hold the current vikunja version which gets overridden through build flags each time `mage release` or `mage build` is run. It is a seperate package to avoid import cycles with other packages. - -## REST-Tests - -Holds all kinds of test files to directly test the api from inside of [jetbrains ide's](https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html). - -These files are currently more an experiment, maybe we will drop them in the future to use something we could integrate in the testing process with drone. -Therefore, this has no claim to be complete yet even working, you're free to change whatever is needed to get it working for you. - -## templates - -Holds the email templates used to send plain text and html emails for new user registration and password changes. - -## vendor - -All libraries needed to build Vikunja. - -We keep all libraries used for Vikunja around in the `vendor/` folder to still be able to build the project even if -some maintainers take their libraries down like [it happened in the past](https://github.com/jteeuwen/go-bindata/issues/5). - -When adding a new dependency, make sure to run `go mod vendor` to put it inside this directory. diff --git a/docs/content/doc/practical-instructions/swagger-docs.md b/docs/content/doc/development/swagger-docs.md similarity index 62% rename from docs/content/doc/practical-instructions/swagger-docs.md rename to docs/content/doc/development/swagger-docs.md index 3e6370476..37c9d33b7 100644 --- a/docs/content/doc/practical-instructions/swagger-docs.md +++ b/docs/content/doc/development/swagger-docs.md @@ -1,17 +1,19 @@ --- date: "2019-02-12:00:00+02:00" -title: "Modifying swagger api docs" +title: "Modifying Swagger API Docs" draft: false type: "doc" menu: sidebar: - parent: "practical instructions" + parent: "development" --- -# Adding/editing swagger api docs +# Modifying swagger api docs The api documentation is generated using [swaggo](https://github.com/swaggo/swag) from comments. +{{< table_of_contents >}} + ## Documenting structs You should always comment every field which will be exposed as a json in the api. @@ -45,3 +47,27 @@ type List struct { web.Rights `xorm:"-" json:"-"` } {{< /highlight >}} + +## Documenting api Endpoints + +All api routes should be documented with a comment above the handler function. +When generating the api docs with mage, the swagger cli will pick these up and put them in a neat document. + +A comment looks like this: + +{{< highlight golang >}} +// @Summary Login +// @Description Logs a user in. Returns a JWT-Token to authenticate further requests. +// @tags user +// @Accept json +// @Produce json +// @Param credentials body user.Login true "The login credentials" +// @Success 200 {object} auth.Token +// @Failure 400 {object} models.Message "Invalid user password model." +// @Failure 412 {object} models.Message "Invalid totp passcode." +// @Failure 403 {object} models.Message "Invalid username or password." +// @Router /login [post] +func Login(c echo.Context) error { + // Handler logic +} +{{< /highlight >}} diff --git a/docs/content/doc/development/test.md b/docs/content/doc/development/test.md index 1ed970be7..9666a9d43 100644 --- a/docs/content/doc/development/test.md +++ b/docs/content/doc/development/test.md @@ -10,7 +10,7 @@ menu: # Testing -You can run unit tests with [our `Magefile`]({{< ref "mage.md">}}) with +You can run unit tests with [mage]({{< ref "mage.md">}}) with {{< highlight bash >}} mage test:unit diff --git a/docs/content/doc/practical-instructions/database.md b/docs/content/doc/practical-instructions/database.md deleted file mode 100644 index 6f4231485..000000000 --- a/docs/content/doc/practical-instructions/database.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Database" -draft: false -type: "doc" -menu: - sidebar: - parent: "practical instructions" ---- - -# Database - -Vikunja uses [xorm](http://xorm.io/) as an abstraction layer to handle the database connection. -Please refer to [their](http://xorm.io/docs/) documentation on how to exactly use it. - -Inside the `models` package, a variable `x` is available which contains a pointer to an instance of `xorm.Engine`. -This is used whenever you make a call to the database to get or update data. - -This xorm instance is set up and initialized every time vikunja is started. - -{{< table_of_contents >}} - -## Adding new database tables - -To add a new table to the database, add a an instance of your struct to the `tables` variable in the -init function in `pkg/models/models.go`. Xorm will sync them automatically. - -You also need to add a pointer to the `tablesWithPointer` slice to enable caching for all instances of this struct. - -To learn more about how to configure your struct to create "good" tables, refer to [the xorm documentaion](http://xorm.io/docs/). - -## Adding data to test fixtures - -Adding data for test fixtures is done in via `yaml` files insinde of `pkg/models/fixtures`. - -The name of the yaml file should equal the table name in the database. -Adding values to it is done via array definition inside of the yaml file. - -**Note**: Table and column names need to be in snake_case as that's what is used internally in the database -and for mapping values from the database to xorm so your structs can use it. \ No newline at end of file diff --git a/docs/content/doc/practical-instructions/mail.md b/docs/content/doc/practical-instructions/mail.md deleted file mode 100644 index 5e7d4c941..000000000 --- a/docs/content/doc/practical-instructions/mail.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Mailer" -draft: false -type: "doc" -menu: - sidebar: - parent: "practical instructions" ---- - -# Mailer - -This document explains how to use the mailer to send emails and what to do to create a new kind of email to be sent. - -{{< table_of_contents >}} - -## Sending emails - -**Note:** You should use mail templates whenever possible (see below). - -To send an email, use the function `mail.SendMail(options)`. The options are defined as follows: - -{{< highlight golang >}} -type Opts struct { - To string // The email address of the recipent - Subject string // The subject of the mail - Message string // The plaintext message in the mail - HTMLMessage string // The html message - ContentType ContentType // The content type of the mail. Can be either mail.ContentTypePlain, mail.ContentTypeHTML, mail.ContentTypeMultipart. You should set this according to the kind of mail you want to send. - Boundary string - Headers []*header // Other headers to set in the mail. -} -{{< /highlight >}} - -### Sending emails based on a template - -For each mail with a template, there are two email templates: One for plaintext emails, one for html emails. - -These are located in the `templates/mail` folder and follow the conventions of `template-name.{plain|hmtl}.tmpl`, -both the plaintext and html templates are in the same folder. - -To send a mail based on a template, use the function `mail.SendMailWithTemplate(to, subject, tpl string, data map[string]interface{})`. -`to` and `subject` are pretty much self-explanatory, `tpl` is the name of the template, without `.html.tmpl` or `.plain.tmpl`. -`data` is a map you can pass additional data to your template. - -### Sending a mail with a template - -A basic html email template would look like this: - -{{< highlight go-html-template >}} -{{template "mail-header.tmpl" .}} -

- Hey there!
- This is a minimal html email example.
- {{.Something}} -

-{{template "mail-footer.tmpl"}} -{{< /highlight >}} - -And the corresponding plaintext template: - -{{< highlight go-text-template >}} -Hey there! - -This is a minimal html email example. - -{{.Something}} -{{< /highlight >}} -You would then call this like so: - -{{< highlight golang >}} -data := make(map[string]interface{}) -data["Something"] = "I am some computed value" -to := "test@example.com" -subject := "A simple test mail" -tpl := "demo" // Assuming you saved the templates as demo.plain.tmpl and demo.html.tmpl -mail.SendMailWithTemplate(to, subject, tpl, data) -{{< /highlight >}} - -The function does not return an error. If an error occures when sending a mail, it is logged but not returned because sending the mail happens asinchrounly. - -Notice the `mail-header.tmpl` and `mail-footer.tmpl` in the template. These populate some basic css, a box for your content and the vikunja logo. -All that's left for you is to put the content in, which then will appear in a beautifully-styled box. - -Remeber, these are email templates. This is different from normal html/css, you cannot use whatever you want (because most of the clients are wayyy to outdated). - diff --git a/docs/content/doc/practical-instructions/new-config-options.md b/docs/content/doc/practical-instructions/new-config-options.md deleted file mode 100644 index 0fb461fba..000000000 --- a/docs/content/doc/practical-instructions/new-config-options.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -date: "2019-02-12:00:00+02:00" -title: "Adding new config options" -draft: false -type: "doc" -menu: - sidebar: - parent: "practical instructions" ---- - -# Adding new config options - -Vikunja uses [viper](https://github.com/spf13/viper) to handle configuration options. -It handles parsing all different configuration sources. - -The configuration is done in sections. These are represented with a `.` in viper. -Take a look at `pkg/config/config.go` to understand how these are set. - -To add a new config option, you should add a default value to `pkg/config/config.go`. -Default values should always enable the feature to work somehow, or turn it off completely if it always needs -additional configuration. - -Make sure to add the new config option to [the config document]({{< ref "../setup/config.md">}}) and the default config file -(`config.yml.sample` at the root of the repository) to make sure it is well documented. - -If you're using a computed value as a default, make sure to update the sample config file and debian -post-install scripts to reflect that. - -To get a configured option, use `viper.Get("config.option")`. -Take a look at [viper's documentation](https://github.com/spf13/viper#getting-values-from-viper) to learn of the -different ways available to get config options. \ No newline at end of file