organice organizes Org files nicely!
Maintainability (Codeclimate):
organice is an implementation of Org mode without the dependency of Emacs. It is built for mobile and desktop browsers and syncs with Dropbox, Google Drive and WebDAV.
At 200ok, we run an instance of organice at https://organice.200ok.ch, which is open for anyone to use! organice does not have a back-end (it’s just a front-end application, which uses either Dropbox, Google Drive or WebDAV as back-end storage). We don’t store any kind of data on our servers - we also don’t use analytics on organice.200ok.ch.
Emacs is great, but it’s desktop software. For users who want to access or edit their Org mode files whilst on the go, organice is a great choice.
“Current” means we’re working hard on removing the following restrictions and expectations.
- organice understands only a few in-buffer settings (
#+TODO:
and#+TYP_TODO:
).- Other in-buffer settings are imported and re-exported but are not editable with organice.
- Other content before the first headline is imported and re-exported, but invisible and currently not editable with organice.
- In treating all the rest of the content beyond the first headline organice is actually very robust in reading and editing your Org file and not breaking any of it. We’ve had users with 10k LOC Org files with all kinds of native Org features (of which organice only has partial understanding) and they just work fine!
Generally, when working with distributed Org files, we’re recommending to put them under version control and to check for bugs and racing conditions between clients.
Please file an issue if you find additional restrictions, expectations or bugs that you you wouldn’t have expected.
organice has a custom parser for Org files. It works quite fine and has unit tests to prove it. However, writing a parser for a complex syntax like Org mode in custom code is hard. Therefore, we are in the process of implementing a proper BNF based parser and a set of tests behind that. If you’re interested, please check it out: https://gitlab.200ok.ch/200ok/org-parser
organice can run as a PWA and does have offline Support. On iOS and Android, you can install the web app to your home screen [tutorial]. From your home screen, organice will start up in full screen and it will use a Service Worker to cache the application. On a desktop browser, the Service Worker will be used automatically. This is implemented using the Create React App Progressive Web App functionality which enables the following features:
- All static assets are cached so that organice loads fast on subsequent visits, regardless of network connectivity.
- Updates are downloaded in the background.
- organice works regardless of network state, even if offline.
- On mobile devices, organice can be added directly to the user’s home screen, app icon and all.
Following that, if you start modifying your Org file when offline, organice will recognize that you are offline and queue up the synchronization until you are online again.
organice also understands when it’s local Org file is outdated compared to the upstream file and will ask you want you want to do - pull the one from the synchronization back-end, push the one from organice or cancel. This happens when you made changes to your file on at least two machines at the same time without synchronizing them in the meantime. For this, we recommend to put your Org file under version control which is the idiomatic solution for changing text based files on multiple machines in parallel.
organice is built with React and Redux. It was bootstrapped with Create React App.
To install the necessary packages, run:
yarn install
To test against your own Dropbox account, you’ll need to
create a .env
file by copying .env.sample to just .env
.
cp .env.sample .env
To run the app, run:
yarn start
<<synchronization_back-ends>>
Note that logging in to Dropbox will only work if you’re running the
app on http://localhost:3000
, because all redirect URIs must be
specified ahead of time on the Dropbox developer console.
To configure your own application on Dropbox, please go here and then
configure this app key in the .env
file. Make sure to add your own
URL as Redirect URI
.
To configure your own application on Google Drive, please generate an API key as described on this page.
With WebDAV support, organice can potentially be used with a multitude of synchronization backends: Client/Server services ownCloud, Nextcloud and Seafile, but also self hosted dedicated WebDAV servers like Apache or Nginx.
Since organice is a front-end application, it will login with JavaScript from within the browser - in turn the Cross-Origin Resource Sharing (CORS) headers must be set appropriately. If they are not set, you will not be able to login to your service from a browser. Alternatively, if you’re using a server like Apache or Nginx, you can simply get around CORS by hosting organice on the same domain as your service.
Please note, that when your back-end does not set the correct CORS headers, organice cannot show you a really semantic error message on that. The reason is that browsers hide this information from JavaScript. You will simply get a network error. However, you can easily debug it yourself by looking into the JavaScript console. No worries, you don’t have to be a (JavaScript) developer to find out about that - here’s a screencast in the Wiki to show you how to do it.
In the Wiki, there’s a screencast of how organice works when logging in to a WebDAV server.
For testing purposes, here are the instructions to setup WebDAV locally on your machine using Apache2 using Debian. These instructions are not meant to be used in production, though.
Initial package installation
sudo apt -y install apache2-utils apache2
Set up a new vhost for webdav
/etc/apache2/sites-available/webdav.conf
Alias /webdav /srv/dav/ RewriteEngine On RewriteCond %{REQUEST_METHOD} OPTIONS RewriteRule ^(.*)$ $1 [R=200,L] <Location /webdav> Options Indexes DAV On AuthType Basic AuthName "webdav" AuthUserFile /srv/dav/.htpasswd Require valid-user Header always set Access-Control-Allow-Origin "*" Header always set Access-Control-Allow-Methods "GET,POST,OPTIONS,DELETE,PUT,PROPFIND" Header always set Access-Control-Allow-Headers "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,X-CSRF-Token,Depth" Header always set Access-Control-Allow-Credentials true Require all granted </location>
Enable Apache modules
sudo a2enmod headers
sudo a2enmod dav*
sudo a2enmod rewrite
sudo a2ensite webdav
Setup folder, password and rights
sudo mkdir /srv/dav
sudo htpasswd -c /srv/dav/.htpasswd webdav
sudo chmod 770 /srv/dav; sudo chown www-data. /srv/dav
sudo service apache2 restart
Test webdav access using a commandline tool
sudo apt -y install cadaver
cadaver http://localhost/webdav/
Please see our contributer guidelines and our code of conduct.
Since organice is a front-end only application, it can easily be deployed to any server capable of serving a static application.
Please note: If you want the hosted application to connect to Dropbox or Google Drive, please read the section on Synchronization back-ends.
First create the production build locally: yarn run build
Note: Creating a build will actually make your REACT_APP_*
variables
from the .env
file available under process.env
even though it’ll
be a front-end application.
And then upload to your web-server. Here’s a script for your convenience:
HOST='your_ftp_server_host'
USER='ftp_user'
PASSWD='ftp_password'
lftp $HOST <<END_SCRIPT
user $USER $PASSWD
mirror -R build/
quit
END_SCRIPT
exit 0
Assuming, you have an account and have installed the command line tools, deployment is as easy as:
heroku create
heroku config:set ON_HEROKU=1
git push heroku master
Whilst organice is a true SPA and therefore has no back-end
whatsoever, this does have an implication for deployment with regard
to routing. For routes like example.com/foo
to work, we need a
little something extra. Within the context of a running SPA, /foo
would be matched by the React Router and the proper page would be
rendered by JavaScript. When initially requesting a route like that
from the web server itself, the SPA is not running yet and the web
server itself wouldn’t find a file called /foo
. It would return
a 404. The whole topic is explained in depth in this SO answer:
https://stackoverflow.com/a/36623117
For https://organice.200ok.ch we’ve opted to:
- Use the modern HTML5 history API with BrowserRouter
- Not configure a back-end for isomorphic routing, because it would complicate application and deployment unnecessarily (SEO is a non-issue for organice)
- Use good old Apache Webserver for hosting the compiled static assets
Therefore configuring a catchall is as easy as setting up a
.htaccess
file in the root of the organice folder containing:
RewriteEngine On RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d RewriteRule ^ - [L] RewriteRule ^ /index.html [L]
organice supports capture templates by implementing a flexible mechanism using URL parameters. These three of the following parameters are required and must be URL encoded:
captureTemplateName
: the name of the capture template to use. This capture template must already exist in Settings > Capture templates.captureFile
: thepath
(for Dropbox) orid
(for Google Drive) of the file in which to execute the capture template.captureContent
: the content you’d like to capture. This content will be placed at the cursor position if specified in the capture template (with%?
), or at the end of the template if its not specified.
You can also specify additional custom variables for use in your
templates. They should be in the format captureVariable_<your custom
variable>
, and should also be URL encoded. In your capture template
they’d show up as %<your custom variable>
.
Say, you want to capture thoughts/todos as they occur to you. You might want to have a capture template to just get these things out of your head.
This makes for a good “Inbox” capture template:
Capture Template
* TODO %? %U
Example URL
Result
* TODO Read up on capture templates [2019-09-08 Sun 20:54]
<<media_capture>>
If you want to add web pages to a reading queue (with a title, a capture date and a URL), this would be a good starting point:
Capture Template
* %? %u - URL: %mediaURL
Example URL
Result
* Play Emacs like an instrument [2019-09-08 Sun] - URL: https://200ok.ch/posts/2018-04-27_Play_Emacs_like_an_Instrument.html
Since organice is a web application, you can use the capture templates feature to create bookmarklets, of course! For example, if you want a bookmarklet to add the current page (title, capture date and URL) to your reading queue using this capture template, all you need is a little bit of JavaScript:
javascript:(function() {
const {title} = document;
const url = `https://organice.200ok.ch?captureTemplateName=Media&captureContent=${title}&captureFile=/org/media.org&captureVariable_mediaURL=${
window.location.href
}`;
window.open(url, "_blank");
})()
The organice capture mechanism integrates very nicely with the Siri Shortcuts feature in iOS, allowing you to use Siri to execute capture templates.
You can use this sample Shortcut to get started with this right away in iOS 12 or newer. Open the link on your iOS device and click “Get Shortcut”. Then open up the Shortcuts app and edit the template by following the directions in the comments. Then record a Siri trigger and you’re good to go!
Before starting work on organice, I did use Beorg and donated to it multiple times, because I was very happy to have a good option to access Org files on my phone with it.
The important differences to me are:
- organice is FOSS which is very much in the spirit of Org whilst Beorg is proprietary
- organice is web based, so there is no lock-in to a specific device or OS
- Beorg currently has better offline support
organice has a shared history with org-web. In fact, it is a friendly fork.
organice differs from org-web in that:
- It’s a community driven project. See our
- It has the commitment of a Swiss company behind it to continually
work on it.
- This company is 200ok llc: https://200ok.ch/
- It has many bug fixes (for example on parsing and exporting org files) compared to its ancestry.
- It continues to evolve independently with it’s own feature set.
- For example: organice has WebDAV support.
- It is a project with equal focus on mobile as desktop browsers.
- org-web tracks users with Google Analytics. organice does not.
To see how organice differs from org-web, please consult the changelog which contains the user visible changes since forking.
We are extraordinarily grateful to DanielDe the original creator!
We forked the project, because we have different visions on how to go forward. He envisions a mobile only solution, we think it’s great to have organice be available to any browser to enable anyone on the go or any non-Emacs user easy access to Org files. Also, DanielDe thinks of org-web as his pet project whereas organice has the full power of 200ok llc behind it whilst building a strong self-sufficient community around it.
Thank you for all, DanielDe!
Illustration credit: Vecteezy.com