We'll take notes as we make a new plugin. We're working in the context of a dockerized local farm. (For non-docker versions, you might check the twins above.)
We'd like to share other web sites via wiki. HTML offers the <iframe> tag for this purpose. We'll build a Frame Plugin.
# Get Started
**Make up a name** for the plugin. Names will become complicated someday. Now they are simple. We'll call ours Frame.
Try the Make Plugin Script
# local directory tree wiki-tls fedwiki └── wiki-plugin-frame ├── client ├── pages ├── server ├── status └── test
**Configure** the local farm to include our experimental plugin.
Include a local directory (`fedwiki`) into our containerized farm where we can develop one or many plugins.
# docker-compose.override.yml services: farm: volumes: - ../fedwiki:/home/app/fedwiki
Inside our running containerized farm, we `npm link` the development plugin.
cd wiki-tls # start wiki and supporting services docker-compose up -d docker-compose exec farm bash # now inside the farm's container cd lib/node_modules/wiki export NPM_CONFIG_PREFIX=$HOME npm link ../../../fedwiki/wiki-plugin-frame exit
**Build the javascript**. The Make Plugin Script includes a `gruntfile.js` for us. We launch a separate container for running `grunt`:
cd fedwiki/wiki-plugin-frame docker run --rm -it \ -v $PWD:/$(basename $PWD) \ -w /$(basename $PWD) \ dobbs/farm:0.50.0 \ bash # now inside the container... npm install node_modules/grunt/bin/grunt build node_modules/grunt/bin/grunt watch
With this container running, grunt will detect changes as we edit the coffeescript files and automatically compile them into javascript for use by the browser.
**Restart** the farm container:
docker-compose restart farm
This will load our newly linked, experimental plugin with wiki.
**Create an item** of this type. Create a new page. Add a simple item. You should see `Frame` among the options in the Factory. (the Make Plugin Script added a `factory.json` file to our plugin directory and recreating the `farm` service will have reloaded all the plugins.
**Experiment.** Change `emit` to use different html. Add functions to parse parameters out of `item.text` and substitute them into the html different ways.
Tip: our text formatting convention is to indent by two spaces using spaces, not tabs.
Tip: place your utility functions above the `emit` and `bind` functions.
Tip: use `wiki.textEditor` to provide a user-editable text field to your item.
Tip: report errors by emitting `p.error` tags.
Keep Building
Factor Logic from emit/bind functions and expose them as a node.js style module.
Tip: use conditions to export the right functions the right way at the right time:
window.plugins.frame = {emit, bind} if window? module.exports = {parse, expand} if module?
**Write Tests** that pass in the simplest way. Follow examples from other plugins like `wiki-plugin-report/test/test.coffee` or `wiki-plugin-calendar/test/test.coffee`
Tip: use `guard watch` to notice changes in your code and automatically run the tests.
Work Examples using other plugins for input or output or event sources and sinks.
Tip: Study the input and output protocols of other plugins, especially recently created ones. There is not yet a standard but there are emerging practices.
Tip: Look to emerging practices in Node.js for models of distributed computation. We do.
New Tip: Look for other system interactions. Sitemap/search pulls text out of items. If this isn't html safe then somehow emit has to get involved. How?
Build Server-Side
Open Connections using WebSocket servers (server.coffee) that are launched when the Express server launches. These are built as their own npm applications with their own package.json files.
Tip: Program the client plugin to look to remote servers for connections.
$page = $item.parents('.page:first') host = $page.data('site') or location.host socket = new WebSocket("ws://#{host}/plugin/...")
Tip: Show connection status in the emitted dom. Find a way to be useful even when connections are not available.
Tip: Test the code that interprets data moving back and forth. Share all but the code that touches the dom.
Finish Up
**Update Menu** that the Factory plugin offers as alternatives to `paragraphs`. The Make Plugin Script created a `factory.json` file to describe your plugin. The server rolls these up into `factories.json` fetched by the Factory plugin. See Factory Plugin Menu.
Write Documentation as one or more wiki pages. Command-I in the editor will look for a page following our "about" convention. See Plugin Documentation
Share Your Source as a community project with a public repository. We prefer GitHub where we save our plugins as projects named wiki-plugin-{name}. github
**Publish on npmjs.org** which allows your plugin to be included in other servers by name using the node package manager or the Plugmatic plugin. See About Plugmatic Plugin. npm
cd fedwiki/wiki-plugin-frame docker run --rm -it \ -v $HOME/.npmrc:/$(basename $PWD)/.npmrc \ -v $HOME/.gitconfig:/$(basename $PWD)/.gitconfig \ -v $PWD:/$(basename $PWD) \ -w /$(basename $PWD) \ node:10 \ bash # now inside the container... npm whoami # double-check npm login # update authors node_modules/grunt/bin/grunt update-authors node_modules/grunt/bin/grunt update-contributors # git commit the changes to authors npm version patch npm publish
**Host the new plugin on your own server**. `npm` can install the plugin from your github page, if you are not ready to publish on npmjs.org. We suggest committing the built javascript files to a specific branch and installing that _branch_:
npm install git+https://github.com/dobbs/wiki-plugin-frame#include-js
restart your wiki to see the plugin live