Skip to content
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time



Slovo - Искони бѣ Слово


Install Slovo locally with all dependencies in less than two minutes

curl -L | perl - -M -q -n -l \
~/opt/slovo Slovo

Run slovo for the first time in debug mode

~/opt/slovo/bin/slovo daemon

Visit For help visit


Slovo is a simple to install and extensible Mojolicious CMS with nice core features like:

On the fly generation of static pages under Apache/CGI – perfect for cheap shared hosting and blogging – BETA
Multi-domain support - DONE;
Multi-language pages - DONE;
Cached published pages and content - DONE;
Multi-user support - DONE;
User onboarding - BETA;
User sign in - DONE;
Managing pages, content, domains, users - WIP;
Managing groups - BASIC;
Multiple groups per user - DONE;
Ownership and permissions management per page and it's content - DONE;
Automatic 301 and 308 (Moved Permanently) redirects for renamed pages and content - DONE;
Embedded fonts for displaying all Azbuka and Glagolitsa characters - DONE;
OpenAPI 2.0 (Swagger) REST API - BASIC;
Trumbowyg - A lightweight WYSIWYG editor; - The open source embeddable online markdown editor (component), based on CodeMirror & jQuery & Marked;
Example startup scripts for slovo and slovo_minion services for systemd, Apache 2.4 and NGINX vhost configuration files.
and more to come…

This is a usable release!

By default Slovo comes with SQLite database, but support for PostgreSQL or MySQL is about to be added when needed. It is just a question of making compatible and/or translating some limited number of SQL queries to the corresponding SQL dialects. Contributors are wellcome.

The word "slovo" (слово) has one unchanged meaning during the last millenium in all slavic languages. It is actually one language that started splitting apart less than one thousand years ago. The meaning is "word" – the God's word (when used with capital letter). Hence the self-naming of this group of people qr/sl(o|a)v(e|a|i)n(i|y|e)/ - people who have been given the God's word or people who can speak. All others were considered "mute", hense the naming (немци)...


All you need is a one-liner, it takes less than a minute.

$ curl -L | perl - -M -n -l ~/opt/slovo Slovo

We recommend the use of a Perlbrew environment.

If you already downloaded it and you have cpanm.

$ cpanm -l ~/opt/slovo Slovo-XXXX.XX.XX.tar.gz

Or even if you don't have cpanm, but you need to install dependencies first.

tar zxf Slovo-XXXX.XX.XX.tar.gz
cd  Slovo-XXXX.XX.XX
perl Makefile.PL INSTALL_BASE=~/opt/slovo && make && make test && make install


cd /path/to/installed/slovo
# ...and see various options


Slovo is a Mojolicious application which means that everything applying to Mojolicious applies to it too. Slovo main configuration file is in lib/Slovo/resourses/etc/slovo.conf. You can use your own by setting $ENV{MOJO_CONFIG} or by just copying slovo.conf to $ENV{MOJO_HOME} and modify it as you wish. New routes can be described in routes.conf. See Mojolicious::Plugin::RoutesConfig for details and examples.

$ENV{MOJO_HOME} (where you installed Slovo) is automatically detected and used. All paths, used in the application, are expected to be its children. You can add your own templates in $ENV{MOJO_HOME}/templates and they will be loaded and used with priority. You can theme your own instance of Slovo by just copying $ENV{MOJO_HOME}/lib/Slovo/resources/templates to $ENV{MOJO_HOME}/templates and modify them. You can add your own static files to $ENV{MOJO_HOME}/public.

You can have separate static files and templates per domain under $ENV{MOJO_HOME}/domove/your.domain/public, $ENV{MOJO_HOME}/domove/your.other.domain/templates, etc. See $ENV{MOJO_HOME}/domove/localhost for example.

Last but not least, you can add your own classes into $ENV{MOJO_HOME}/site/lib and (why not) replace entirely some Slovo classes or just extend them. $ENV{MOJO_HOME}/bin/slovo will automatically load them.

With all the above, you can upgrade Slovo by just installing new versions over it and your files will not be touched. And of course, we know that you are using versioning just in case anything goes wrong. See "home".


Slovo inherits all attributes from Mojolicious and implements the following new ones.


Slovo detects where home is not like Mojo::Home by where lib/ is but by where the script/ or bin/ folder resides starting from where lib/ is and going up the tree. If in one of these folders there is $app->moniker, then the upper folder is the home.


berov@Skylake:Slovo$ pwd
berov@Skylake:Slovo$ perl script/slovo eval 'say app->home'

berov@Skylake:Slovo$ cpanm . -n -l ~/opt/
--> Working on .
Configuring /home/berov/opt/dev/Slovo ... OK
Building Slovo-v2019.06.09 ... OK
Successfully installed Slovo-v2019.06.09
1 distribution installed$ pwd
/home/berov/opt/$ slovo/bin/slovo eval 'say app->home'
/home/berov/opt/$ pwd
/home/berov/opt/$ perl -Islovo/lib/perl5 -MSlovo -E 'say Slovo->new->home'


push @{$app->static->paths}, $app->resources->child('public');

Returns a Mojo::File instance for path "resources" in Slovo next to where is installed.


my $validator = $app->validator;
$app          = $app->validator(Slovo::Validator->new);

Validate values, defaults to a Slovo::Validator object.

# Add validation check
$app->validator->add_check(foo => sub {
  my ($v, $name, $value) = @_;
  return $value ne 'foo';

# Add validation filter
$app->validator->add_filter(quotemeta => sub {
  my ($v, $name, $value) = @_;
  return quotemeta $value;


Slovo inherits all methods from Mojolicious and implements the following new ones.


A convenient wrapper with check for "load_class" in Mojo::Loader. Loads a class and croaks if something is wrong. This could be a helper.


my $app = Slovo->new->startup;

Starts the application. Adds hooks, prepares $app->routes for use, loads configuration files and applies settings from them, loads plugins, sets default paths, and returns the application instance.


Slovo adds custom code to the following hooks.


On each request we determine the current host and modify the static and renderer paths accordingly. This is how the multi-domain support works.


On each request we check if we have logged in user and set the current user to guest if we don't. This way every part of the application (including newly developed plugins) can count on having a current user. It is used for determining the permissions for any resource in the application. The user is available as $c->user.


Slovo implements the following helpers.


We need to have our openapi API specification always at hand as a unified source of truth so here it is.

#anywhere via $app or $c, even not via a REST call
state $columns =


Please use issues at GitHub, fork the project and make pull requests.


Красимир Беров
berov на cpan точка org


Ordered by time of first commit.

  • MANWAR (Mohammad S Anwar)

  • KABANOID (Mikhail Katasonov)

  • 0xAF (Stanislav Lechev)


This program is free software licensed under the Artistic License 2.0.

The full text of the license can be found in the LICENSE file included with this module.

This distribution contains other free software which belongs to their respective authors.


Considerably improve the Adminiastration UI - now it is quite simplistic.

Consider using Mithril or Dojo or something light as frontend framework for building UI. We already use jQuery from Mojolicious.

Consider using DataTables jQuery plugin for the administrative panel.


Slovo::Plugin::TagHelpers, Slovo::Plugin::DefaultHelpers, Slovo::Validator, Mojolicious, Mojolicious::Guides

You can’t perform that action at this time.