View type

A view is an abstraction that defines how table data is displayed to a user. More information about this can be found on the database plugin page. This is a tutorial about how to create your own custom table view type for Baserow via a plugin. We are going to create a calendar view that doesn’t really do anything. In the end the user can create a new calendar view that only shows a hello world message. We expect that you are using the plugin boilerplate.

Backend

We are going to start by creating a CalendarView model that extends the View model. Every time the user creates a new calendar view a new instance of the CalendarView will be created. If there are any unique properties that the user must be able to configure per view they can be set here. Even though we are not going to add unique properties in this tutorial you could for example store which field is the date field, or if there are fields that must be hidden.

plugins/my_baserow_plugin/backend/src/my_baserow_plugin/models.py

from baserow.contrib.database.views.models import View


class CalendarView(View):
    pass

Next we need a to create a CalendarViewType class. All the view type configuration, hooks and other related things are in here. More information about the possibilities can be found in the Baserow repository at backend/src/baserow/contrib/database/views/registries.py::ViewType.

plugins/my_baserow_plugin/backend/src/my_baserow_plugin/view_types.py

from baserow.contrib.database.views.registries import ViewType

from .models import CalendarView


class CalendarViewType(ViewType):
    type = 'calendar'
    model_class = CalendarView

Finally we need to register the view type in the registry.

plugins/my_baserow_plugin/backend/src/my_baserow_plugin/config.py

from django.apps import AppConfig

from baserow.core.registries import plugin_registry
from baserow.contrib.database.views.registries import view_type_registry


class PluginNameConfig(AppConfig):
    name = 'my_baserow_plugin'

    def ready(self):
        from .plugins import PluginNamePlugin
        from .view_types import CalendarViewType

        plugin_registry.register(PluginNamePlugin())
        view_type_registry.register(CalendarViewType())

Don’t forget to create and apply the migrations because we have created a new model.

# Set these env vars to make sure mounting your source code into the container uses
# the correct user and permissions.
export PLUGIN_BUILD_UID=$(id -u)
export PLUGIN_BUILD_GID=$(id -g)
docker-compose -f docker-compose.dev.yml run --rm my-baserow-plugin backend-cmd manage makemigrations
docker-compose -f docker-compose.dev.yml run --rm my-baserow-plugin backend-cmd manage migrate

Web frontend

Because the backend and web-frontend are two separate applications that only communicate via a REST API with each other, the web-frontend does not yet know about the existence of the calendar view type. We can add this in a similar way. Add/modify the following files in the web-frontend part of the plugin.

plugins/my_baserow_plugin/web-frontend/components/CalendarView.vue

<template>
  <div>Hello World</div>
</template>

<script>
export default {
  name: 'CalendarView',
  props: {
    primary: {
      type: Object,
      required: true,
    },
    fields: {
      type: Array,
      required: true,
    },
    view: {
      type: Object,
      required: true,
    },
    table: {
      type: Object,
      required: true,
    },
    database: {
      type: Object,
      required: true,
    },
  },
}
</script>

You can inspect the web-frontend/modules/database/viewTypes.js::ViewType for all the methods and properties that can be overridden here. The component that is returned by the getComponent method is will be added to the body of the page when a view of this type is selected.

plugins/my_baserow_plugin/web-frontend/viewTypes.js

import { ViewType } from '@baserow/modules/database/viewTypes'
import CalendarView from '@my-baserow-plugin/components/CalendarView'

export class CalendarViewType extends ViewType {
  static getType() {
    return 'calendar'
  }

  getIconClass() {
    return 'iconoir-calendar'
  }

  getName() {
    return 'Calendar'
  }

  getComponent() {
    return CalendarView
  }
}

plugins/my_baserow_plugin/web-frontend/plugin.js

import { PluginNamePlugin } from '@my-baserow-plugin/plugins'
import { CalendarViewType } from '@my-baserow-plugin/viewTypes'

export default (context) => {
  const { app } = context
  app.$registry.register('plugin', new PluginNamePlugin(context))
  app.$registry.register('view', new CalendarViewType(context))
}

Once you have added this code you should be able to click on the “Calendar” button in the views context menu next to “Add a view”. A popup should appear and if you fill out the form the calendar view should be created. You can then click on the newly created view and in the body of the page you should see “Hello World”.