Modify web-frontend & plugin-Baserow dependency

Hello, I’m creating my first plugins in Baserow and I have two questions that I would like someone who knows the subject to guide me:

  • Firstly, as explained in the Boilerplate tutorial, you start the environment from the plugin folder,
    while Baserow is installed as a dependency. So, if I create two different and independent plugins, should I create them in the same plugin-project so that they both run at the same time? Since I would not be able to run two different projects made with cookiecutter.

  • Secondly, when developing plugins, I wonder if there is a way to modify the frontend, but in the specific case of wanting to remove a component, instead of adding it, because as far as I understand, with a plugin, I couldn’t edit and remove components of a page.

Thank you very much!

Hi @DavidPoza ,

Excited to hear you are making some plugins :slight_smile:

  • To answer you first question, do you want to distribute your two plugins completely separately? If so then you should make two completely separate projects by running the cookiecutter twice with a different output folder each time. Is the problem that you then want to test both of your plugins at once in your dev environment?

  • Secondly: This is a good question. Right now using the interface exposed by web-frontend/modules/core/plugins.js:BaserowPlugin is the easiest way of adding/removing custom components. However this relies on us adding the required extension point to this interface and releasing a new version of Baserow for you to use it. This is probably the best way long term and so if you just let us know which exact component you want to have control over we can easily add it to this interface for the next release. However until then you might be able to get by with a hackier method, perhaps something like:

    • importing the parent component and directly modifying it somehow?
    • perhaps in your web-frontend/build.sh bash script literally cp your_overriden_plugin /baserow/web-frontend/path/to/component/to/replace.

Ideally we want to figure out a much easier way for the web-frontend plugins to hook into components and make changes, so please let us know if you have any suggestions. Perhaps we just need to add many many more extension methods to the BaserowPlugin interface and leave it at that? Not sure.

The two hacky methods I’ve proposed above will be painful in the longterm for both us as maintainers of Baserow (how do we know what plugins we are breaking when we make changes if plugins regularly go ahead and overwrite our components/code entirely?), for users as things will break more and as a plugin author as you’ll have to potentially fix problems with every Baserow upgrade.

Hi, thanks for the answer.

  • Yes, actually my question was focused to the fact of testing both plugins at once. If this is not possible I guess that all the development has to be in the same cookiecutter project.

  • Regarding the second answer, as you say, our idea is to continue developing and adapting Baserow at the same time as you bring Releases, so overwriting the code entirely in some components doesn’t seem to be the best idea. Your proposal for extensions is both practical and easy to implement as long as the right one is found.
    In our case, for example, the main objective in Baserow is to add fields, which are able in the backend to execute some Python function/script, and capable to extract information from certain rows in the form of a list (file). I have a question about this, so I’m going to post another entry with a different title.

Thank you very much.

Hey,

I think its completely possible to get a dev env working with multiple plugins loaded into it.

  1. Run the cookie cutter twice, create a separate plugin repo folder for each plugin you want. However put all of these plugin folders in the same folder. For example you want to end up with a structure looking like:
my_baserow_plugins/
      plugin_a/
             plugins/
                     plugin_a/
                             backend/
                             web-frontend/
     plugin_b/
            plugins/
                     plugin_b/
                             backend/
                             web-frontend/

Once you have this structure setup in your my_baserow_plugins create a new dev.Dockerfile and docker-compose.dev.yml in that top level folder next to the two plugin folders with the following contents. Please make sure to replace PLUGIN_NAME_A (plugin_a in the above structure) and PLUGIN_NAME_B with your plugin directory names

# This a dev image for testing your plugin when installed into the Baserow all-in-one image
FROM baserow/baserow:1.10.2 as base

FROM baserow/baserow:1.10.2

ARG PLUGIN_BUILD_UID
ENV PLUGIN_BUILD_UID=${PLUGIN_BUILD_UID:-9999}
ARG PLUGIN_BUILD_GID
ENV PLUGIN_BUILD_GID=${PLUGIN_BUILD_GID:-9999}

# Use a multi-stage copy to quickly chown the contents of Baserow to match the user
# that will be running this image.
COPY --from=base --chown=$PLUGIN_BUILD_UID:$PLUGIN_BUILD_GID /baserow /baserow

RUN groupmod -g $PLUGIN_BUILD_GID baserow_docker_group && usermod -u $PLUGIN_BUILD_UID $DOCKER_USER

# Install your dev dependencies manually.
COPY --chown=$PLUGIN_BUILD_UID:$PLUGIN_BUILD_GID ./PLUGIN_NAME_A/plugins/PLUGIN_NAME_A/backend/requirements/dev.txt /tmp/plugin-dev-PLUGIN_NAME_A-requirements.txt
RUN . /baserow/venv/bin/activate && pip3 install -r /tmp/plugin-dev-PLUGIN_NAME_A-requirements.txt

COPY --chown=$PLUGIN_BUILD_UID:$PLUGIN_BUILD_GID ./PLUGIN_NAME_B/plugins/PLUGIN_NAME_B/backend/requirements/dev.txt /tmp/plugin-dev-PLUGIN_NAME_B-requirements.txt
RUN . /baserow/venv/bin/activate && pip3 install -r /tmp/plugin-dev-PLUGIN_NAME_B-requirements.txt

COPY --chown=$PLUGIN_BUILD_UID:$PLUGIN_BUILD_GID ./PLUGIN_NAME_A/plugins/PLUGIN_NAME_A/ $BASEROW_PLUGIN_DIR/PLUGIN_NAME_A/
RUN /baserow/plugins/install_plugin.sh --folder $BASEROW_PLUGIN_DIR/PLUGIN_NAME_A --dev

COPY --chown=$PLUGIN_BUILD_UID:$PLUGIN_BUILD_GID ./PLUGIN_NAME_B/plugins/PLUGIN_NAME_B/ $BASEROW_PLUGIN_DIR/PLUGIN_NAME_B/
RUN /baserow/plugins/install_plugin.sh --folder $BASEROW_PLUGIN_DIR/PLUGIN_NAME_B --dev

ENV BASEROW_ALL_IN_ONE_DEV_MODE='true'
# MAKE SURE YOU HAVE SET THE REQUIRED VARIABLES IN the .env FILE.configs:

# This compose file starts up a dev version of the plugin with hot code reloading.
# It is accessible at http://localhost .

version: "3.4"
services:
  REPLACE_WITH_DESIRED_SERVICE_NAME:
    container_name: REPLACE_WITH_DESIRED_CONTAINER_NAME
    image: REPLACE_WITH_DESIRED_IMAGE_NAME_dev
    build:
      dockerfile: ./dev.Dockerfile
      context: .
      args:
        # We allow configuring the PLUGIN_BUILD_UID/PLUGIN_BUILD_GID here so you can run as the dev's actual user
        # reducing the chance the containers screw up the bind mounted folders.
        PLUGIN_BUILD_UID: $PLUGIN_BUILD_UID
        PLUGIN_BUILD_GID: $PLUGIN_BUILD_GID
    ports:
      - "80:80"
      - "443:443"
    environment:
      BASEROW_PUBLIC_URL: http://localhost
    volumes:
      - baserow_data:/baserow/data
      - ./plugins/PLUGIN_NAME_A/backend:/baserow/data/plugins/PLUGIN_NAME_A/backend
      # Override the for node_modules, so we use the node_modules built
      # directly into the image instead of whatever is on your local filesystem.
      - /baserow/data/plugins/PLUGIN_NAME_A/web-frontend/node_modules
      - ./plugins/PLUGIN_NAME_A/web-frontend:/baserow/data/plugins/PLUGIN_NAME_A/web-frontend
      - ./plugins/PLUGIN_NAME_B/backend:/baserow/data/plugins/PLUGIN_NAME_B/backend
      # Override the for node_modules, so we use the node_modules built
      # directly into the image instead of whatever is on your local filesystem.
      - /baserow/data/plugins/PLUGIN_NAME_B/web-frontend/node_modules
      - ./plugins/PLUGIN_NAME_B/web-frontend:/baserow/data/plugins/PLUGIN_NAME_B/web-frontend
    # Open stdin and tty so when attaching key input works as expected.
    stdin_open: true
    tty: true
volumes:
  baserow_data:

I hope this helps! Once again I haven’t manually tested this myself so I would expect some typos etc, but hopefully this shows you in a general way how this could be accomplished?

1 Like

And with regards to making a plugin that adds a new field type which executes python script in the backend this is 100% possible and you shouldn’t have to do any of the discussed patching/overriding of files. The example Nigel Gott / baserow_geo_plugin · GitLab shows exactly how to add a new field type which uses its own components to render itself etc which is all supported by our existing plugin extension points / field_type_registry system in the front and backends.