ihp icon indicating copy to clipboard operation
ihp copied to clipboard

Plugin API

Open mpscholten opened this issue 5 years ago • 10 comments

Plugin Ideas:

  • [ ] ihp-stripe: Useful to enable more money to be made in the IHP ecosystem
  • [x] ihp-sentry
  • [ ] ihp-prometheus
  • [ ] ihp-admin
  • [ ] ihp-dygraph

We need a way for Plugins to be hooked into an IHP app.

mpscholten avatar Nov 20 '20 15:11 mpscholten

Hey just put up a proto-type of an ihp style plugin I've factored out of an Bing maps app. The readme has some overall style ideas but the main points are:

  1. you could write all the API logic for the plugin independently and then expose it with the same Application/Helper/Controller.hs and Application/Helper/View.hs type patterns which would make plugin use simpler for end user and allow plugin developers to have their library still flexible for other uses. In this pattern ihp-users would just have to look to see which convenience functions are exposed for their views and controllers and keep working.

  2. The ihp nix formula could allow users to specify a list of plugins they want (from what I called a curry-house ;) and then those can be checked out into the nix store. This has additional advantage that nix would make it much simpler to keep all the plugins synchronized with IHP by specifying a nixpkgs image.

Montmorency avatar Nov 23 '20 16:11 Montmorency

you could write all the API logic for the plugin independently and then expose it with the same Application/Helper/Controller.hs and Application/Helper/View.hs type patterns which would make plugin use simpler for end user and allow plugin developers to have their library still flexible for other uses. In this pattern ihp-users would just have to look to see which convenience functions are exposed for their views and controllers and keep working.

👍 Later we could add some kind of installation tool, like add-plugin (e.g. add-plugin ihp-bing) that then also automatically adds all the imports to the app based on the available module names.

In the last refactoring I actually moved away from the Helper naming as I think the Helper word is not adding any meaning. You can see this e.g. in the new modal structure here: https://github.com/digitallyinduced/ihp/tree/master/IHP/Modal

Basically this is just a renaming, but it adds a lot more clarity:

X.Helper.Controller  -> X.ControllerFunctions
X.Helper.Types       -> X.Types (e.g. the Modal submodule of IHP previously didn't even have this file. It was all in the Controller Helper)
X.Helper.View        -> X.ViewFunctions

What do you think about this structure?

We should also add a standard name for exporting stuff that is used in Config/Config.hs (like bingAPIKey). Maybe X.Config?

The ihp nix formula could allow users to specify a list of plugins they want (from what I called a curry-house ;) and then those can be checked out into the nix store. This has additional advantage that nix would make it much simpler to keep all the plugins synchronized with IHP by specifying a nixpkgs image.

Great idea, here's some code example how I imagine this could look in the default.nix:


let
    ihp = builtins.fetchGit {
        url = "https://github.com/digitallyinduced/ihp.git";
        rev = "d02a0699220a87d32889ff2a7b87ad81f8bc8195";
    };
    haskellEnv = import "${ihp}/NixSupport/default.nix" {
        ihp = ihp;
        haskellDeps = p: with p; [
            cabal-install
            base
            wai
            text
            hlint
            p.ihp
        ];
        ihpPlugins = p: with p; [ ihp-bing ];
        otherDeps = p: with p; [
            # Native dependencies, e.g. imagemagick
        ];
        projectPath = ./.;
    };
in
    haskellEnv

Maybe we could use the new nix flakes for the curry-house :)

mpscholten avatar Nov 23 '20 17:11 mpscholten

In the last refactoring I actually moved away from the Helper naming as I think the Helper word is not adding any meaning.

I like the streamlined naming. I can see it being straightforward to use/extend if every plugin you want to use you can quickly see the controller/view-functions and the important types.

So maybe I could refactor layout like this?

ihp-plugin/
        PluginAPI/
        Main.hs
        Types.hs
        ControllerFunctions.hs
        ViewFunctions.hs
        Config.hs

We should also add a standard name for exporting stuff that is used in Config/Config.hs (like bingAPIKey). Maybe X.Config?

Yes that would be nice:

cat Config.hs
      data Config = Config { pluginAPIKey :: !Text
                                           , pluginAPIEndpoint :: !Text
                                           }

then I suppose option $ pluginAPIKey Bing.Config in the App/Config/Config.hs. Would make it easy and explicit for user to keep track of all their api configurations.

here's some code example how I imagine this could look in the default.nix:

Yep that looks perfect!

Not sure how to handle the import name resolutions. If there was a Plugins (CurryHouse;) dir I guess the tidiest import names would then look like:

import Plugins.Bing.ControllerFunctions
etc.

Also depends how you want to incorporate plugins in the Dev environment? Would it be interesting if there was a page with a list of plugins you can turn on/off?

Montmorency avatar Nov 23 '20 22:11 Montmorency

We should also have an IHP elm plugin :) Based on the ideas of @kodeFant's blog series https://driftercode.com/blog/passing-flags-from-ihp-to-elm/

mpscholten avatar Dec 19 '20 18:12 mpscholten

https://github.com/digitallyinduced/ihp/pull/725 adds the ihp-zip plugin :) Source for the plugin is at https://github.com/digitallyinduced/ihp-zip

I think it would be nice if we can put the plugins onto hackage aswell. This way the documentation would be easily googleable 👍

mpscholten avatar Jan 28 '21 09:01 mpscholten

Added a new ihp-sentry plugin at https://github.com/digitallyinduced/ihp-sentry

mpscholten avatar Jan 30 '21 13:01 mpscholten

Maybe we could make use of nix-flakes (+tutorial by tweag) for plugins (or in general)? That could remove the need to add plugins inside this repo. I've also made good experience with using nix-flakes+direnv instead of lorri (#339), so this could deal with two issues at the same time?

jeyj0 avatar May 20 '21 08:05 jeyj0

@jeyj0 Could you elaborate how flakes replace Lorri? It seems on NixOS you can do nixos-rebuild which allows you to replace Lorri, but not on other systems.

s0kil avatar Apr 26 '22 12:04 s0kil

Lorri is, at least to my knowledge, mainly useful for quickly loading a local environment, allowing you to enter and exit a nix-shell a lot faster than usual.

Since flakes are pure (https://nixos.wiki/wiki/Flakes#Making_your_evaluations_pure), there's a lot more possibilities for caching. This means entering a nix-shell created from a flake is a lot faster than entering a nix-shell otherwise.

If you want to try using flakes for your direnv integration today, the flakes docs actually have a section on "super fast nix-shell": https://nixos.wiki/wiki/Flakes#Super_fast_nix-shell.

The use_flake direnv function is now already included in direnv if I'm not mistaken, so creating that function is now not necessary anymore (I think).

If you do try this, I recommend not creating a separate shell.nix, as changes in that file will not be automatically reloaded by direnv (as mentioned here: https://nixos.wiki/wiki/Flakes#Optimize_the_reloads). Instead, simply define everything in the flake.nix file itself (alternatively, remember to touch flake.nix after any change to shell.nix).

jeyj0 avatar Apr 28 '22 07:04 jeyj0