So over the years, we all learn more and more about what we like and use often in MySQL. Currently, I step in and out of a robust about of different systems. I love it being able to see how different companies use MySQL. I also see several aspect and settings that often get missed. So here are a few things I think should always be set and they not impact your MySQL database. At a high level:
>Move the Slow log to a table
Set report_host_name
Set master & slaves to use tables
Turn off log_queries_not_using_indexes until needed
Side note — USE ALGORITHM=INPLACE
Side note — USE mysql_config_editor
Side note — USE mysql_upgrade –upgrade-system-tables
Move the Slow log to a table
This is a very simple process with a great return. YES you can use Percona toolkit to analyze the slow logs. However, I like being able to query against the table and find duplicate queries or by times and etc with a simple query call.
mysql> select count(*) from mysql.slow_log; +----------+ | count(*) | +----------+ | 0 | +----------+ 1 row in set (0.00 sec)
Now you can truncate it or dump it or whatever you like to do with this data easily also. Note variable values into your my.cnf file to enable upon restart.
Set report_host_name
This is a simple my.cnf file edit in all my.cnf files but certainly the slaves my.cnf files. On a master.. this is just set for when it ever gets flipped and becomes a slave.
report_host = <hostname> <or whatever you want to call it>
mysql> show variables like '%repository'; +---------------------------+-------+ | Variable_name | Value | +---------------------------+-------+ | master_info_repository | FILE | | relay_log_info_repository | FILE | +---------------------------+-------+
mysql_slave> stop slave; mysql_slave> SET GLOBAL master_info_repository = 'TABLE'; mysql_slave> SET GLOBAL relay_log_info_repository = 'TABLE'; mysql_slave> start slave;
Make sure you add to my.cnf to you do not lose binlog and position at a restart. It will default to FILE otherwise.
master-info-repository =TABLE
relay-log-info-repository =TABLE
mysql> show variables like '%repository'; ---------------------+-------+ | Variable_name | Value | +---------------------------+-------+ | master_info_repository | TABLE | | relay_log_info_repository | TABLE | +---------------------------+-------+
All data is available in tables now and easily stored with backups
mysql> desc mysql.slave_master_info; +------------------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------------+---------------------+------+-----+---------+-------+ | Number_of_lines | int(10) unsigned | NO | | NULL | | | Master_log_name | text | NO | | NULL | | | Master_log_pos | bigint(20) unsigned | NO | | NULL | | | Host | char(64) | YES | | NULL | | | User_name | text | YES | | NULL | | | User_password | text | YES | | NULL | | | Port | int(10) unsigned | NO | | NULL | | | Connect_retry | int(10) unsigned | NO | | NULL | | | Enabled_ssl | tinyint(1) | NO | | NULL | | | Ssl_ca | text | YES | | NULL | | | Ssl_capath | text | YES | | NULL | | | Ssl_cert | text | YES | | NULL | | | Ssl_cipher | text | YES | | NULL | | | Ssl_key | text | YES | | NULL | | | Ssl_verify_server_cert | tinyint(1) | NO | | NULL | | | Heartbeat | float | NO | | NULL | | | Bind | text | YES | | NULL | | | Ignored_server_ids | text | YES | | NULL | | | Uuid | text | YES | | NULL | | | Retry_count | bigint(20) unsigned | NO | | NULL | | | Ssl_crl | text | YES | | NULL | | | Ssl_crlpath | text | YES | | NULL | | | Enabled_auto_position | tinyint(1) | NO | | NULL | | | Channel_name | char(64) | NO | PRI | NULL | | | Tls_version | text | YES | | NULL | | | Public_key_path | text | YES | | NULL | | | Get_public_key | tinyint(1) | NO | | NULL | | +------------------------+---------------------+------+-----+---------+-------+ 27 rows in set (0.05 sec)
mysql> desc mysql.slave_relay_log_info; +-------------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------------+---------------------+------+-----+---------+-------+ | Number_of_lines | int(10) unsigned | NO | | NULL | | | Relay_log_name | text | NO | | NULL | | | Relay_log_pos | bigint(20) unsigned | NO | | NULL | | | Master_log_name | text | NO | | NULL | | | Master_log_pos | bigint(20) unsigned | NO | | NULL | | | Sql_delay | int(11) | NO | | NULL | | | Number_of_workers | int(10) unsigned | NO | | NULL | | | Id | int(10) unsigned | NO | | NULL | | | Channel_name | char(64) | NO | PRI | NULL | |
Turn off log_queries_not_using_indexes until needed
This was shown above also. This is a valid variable .. but depending on application it can load a slow log with useless info. Some tables might have 5 rows in it, you use it for some random drop down and you never put an index on it. With this enabled every time you query that table it gets logged. Now.. I am a big believer in you should put an index on it anyway. But focus this variable when you are looking to troubleshoot and optimize things. Let it run for at least 24hours so you get a full scope of a system if not a week.
mysql> SET GLOBAL log_queries_not_using_indexes=0; Query OK, 0 rows affected (0.00 sec)
To turn on
mysql> SET GLOBAL log_queries_not_using_indexes=1;
Query OK, 0 rows affected (0.00 sec)
Note variable values into your my.cnf file to enable upon restart. Side note — USE ALGORITHM=INPLACE
OK this is not a variable but more of a best practice. You should already be using EXPLAIN before you run a query, This shows you the query plan and lets you be sure all syntax is valid. I have seen more than once a Delete query executed without an WHERE by mistake. So 1st always use EXPLAIN to double check what you plan to do. Not the other process you should always do is try to use an ALGORITHM=INPLACE or ALGORITHM=COPY when altering tables.
mysql_config_editor set --login-path=local --host=localhost --user=root --password Enter password: # mysql_config_editor print --all [local] user = root password = ***** host = localhost
# mysql ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
# mysql --login-path=local Welcome to the MySQL monitor.
# mysql --login-path=local -e 'SELECT NOW()';
Side note — USE mysql_upgrade –upgrade-system-tables
Don’t forget to use mysql_upgrade after you actually upgrade.
This is often forgotten and leads to issues and errors at start up. You do not have to run upgrade across every table that exists though. The focus of most upgrade are the system tables. So at the very least focus on those.
MySQL 8.0 brings a lot of new features. These features make MySQL database much more secure (like new authentication, secure password policies and management, …) and fault tolerant (new data dictionary), more powerful (new redo log design, less contention, extreme scale out of InnoDB, …), better operation management (SQL Roles, instant add columns), many (but really many!) replication enhancements and native group replication… and finally many cool stuff like the new Document Store, the new MySQL Shell and MySQL InnoDB Cluster that you should already know if you follow this blog (see these TOP 10 for features for developers and this TOP 10 for DBAs & OPS).
Not anymore a drop in replacement !
We saw in this previous post how to migrate from MariaDB 5.5 (default on CentOS/RedHat 7) to MySQL. This was a straight forward migration as at the time MariaDB was a drop in replacement for MySQL…but this is not the case anymore since MariaDB 10.x !
Lets get started with the migration to MySQL 8.0 !
Options
Two possibilities are available to us:
Use logical dump for schemes and data
Use logical dump for schemes and transportable InnoDB tablespaces for the data
Preparing the migration
Option 1 – full logical dump
It’s recommended to avoid to have to deal with mysql.* tables are they won’t be compatible, I recommend you to save all that information and import the required entries like users manually. It’s maybe the best time to do some cleanup.
As we are still using our WordPress site to illustrate this migration. I will dump the wp database:
# mysqldump -B wp > wp.sql
MariaDB doesn’t provide mysqlpump, so I used the good old mysqldump. There was a nice article this morning about MySQL logical dump solutions, see it here.
These operation above need to be repeated for all the tables ! If you have a large amount of table I encourage you to script all these operations.
Replace the binaries / install MySQL 8.0
Unlike previous version, if we install MySQL from the Community Repo as seen on this post, MySQL 8.0 won’t be seen as a conflicting replacement for MariaDB 10.x. To avoid any conflict and installation failure, we will replace the MariaDB packages by the MySQL ones using the swap command of yum:
This new yum command is very useful, and allow other dependencies like php-mysql or postfix for example to stay installed without breaking some dependencies
The result of the command will be something similar to:
Now the best is to empty the datadir and start mysqld:
# rm -rf /var/lib/mysql/* # systemctl start mysq
This will start the initialize process and start MySQL.
As you may know, by default MySQL is now more secure and a new password has been generated to the root user. You can find it in the error log (/var/log/mysqld.log):
2019-03-26T12:32:14.475236Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: S/vfafkpD9a
At first login with the root user, the password must be changed:
# mysql -u root -p mysql> set password='Complicate1#'
Adding the credentials
Now we need to create our database (wp), our user and its credentials.
Please, note that the PHP version used by default in CentOS might now be yet compatible with the new default secure authentication plugin, therefor we will have to create our user with the older authentication plugin, mysql_native_password. For more info see these posts:
Yes, this is required for all tables, this is why I encourage you to script it if you choose this option.
Conclusion
So as you could see, it’s still possible to migrate from MariaDB to MySQL but since 10.x, this is not a drop in replacement anymore and requires several steps including logical backup.
While working on a completely different project I discovered something curious on Amazon. That product was moldable thermoplastic pellets. Shaped in balls like smaller-than-usual airsoft pellets, moldable thermoplastic melts at just 140F, can be formed like clay, and then increases in hardness as it approaches room temperature. There are seemingly endless uses for this product, but I had a pet… more
via Recoil Make Gun Tools That Don’t Exist with Moldable Thermoplastic
Laravel 5.8 is recently released with many improvements so we’ll be learning, throughout this tutorial how to create an example CRUD application from scratch. The application we’ll be building is a simple CRM with a MySQL database.
You can see this Upgrade Guide for instructions on how to upgrade an existing web application from Laravel 5.7 to Laravel 5.8
Tutorial Prerequisites
This tutorial has some prerequisites
You have at least PHP 7.1.3 installed on your development machine,
Working experience of PHP. The OpenSSL, PDO, Mbstring, Tokenizer, XML, Ctype, JSON and BCMath PHP extensions installed with your PHP version.
The MySQL database management system,
Composer (A PHP dependency management for PHP) installed on your machine. You can head to the official website for instructions how to download install it.
If you have these prerequisites, let’s get started by creating our first Laravel 5.8 project.
Creating a Laravel 5.8 Project with PHP Composer
Let’s use Composer to create a project based on Laravel 5.8. Open a new terminal and run the following command:
$ composer create-project –prefer-dist laravel/laravel laravel-crud
This command will automatically start installing the latest version of Laravel provided that you have the required dependencies of PHP for Laravel 5.8 installed on your system:
After finishing the installation process, navigate to the project’s folder:
$ cd ./laravel-crud
Next, serve your application using the artisan serve command:
$ php artisan serve
This will start a Laravel development server on the http://127.0.0.1:8000. Just leave it open as any changes we’ll be making will automatically get reloaded.
Configuring the MySQL Database
We’ll be using MySQL, the most popular database system used by PHP and Laravel developers so make sure you have created a database for your project. You can simply use the mysql client. Open a new terminal window and run the following command:
$ mysql -u root -p
You will get prompted for a password. Enter the one you submitted when you configured your MySQL installation and hit Enter.
When the mysql clients starts, enter the following SQL instruction to create a database:
mysql> create database l58db;
Note: You can also use phpMyAdmin to create and work with MySQL databases. phpMyAdmin is a free web interface tool created in PHP, intended to handle the administration of MySQL over the Web. It’s beginners friendlier tool that’s commonly used by PHP developers.
Now, let’s let Laravel know about our created database. Open the .env file in the root of your project and update the MySQL credentials with your own values: DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=l58db DB_USERNAME=root DB_PASSWORD=<YOUR_DATABASE_PASSWORD>
This will allow your application to connect to your MySQL database.
You can also configure the database connection in the config/database.php.
The database configuration for your application is located at config/database.php. In this file you may define all of your database connections, as well as specify which connection should be used by default. Examples for most of the supported database systems are provided in this file. The official docs
Next, let’s create the database tables using the following command:
$ php artisan migrate
Note: Until now, we didn’t create any models but Laravel makes use of multiple tables so we need to run the previous command to create them in our database. After we create our own models, we can run the artisan migrate command again to update the database structure.
This is the output of the command:
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table
You can see that our project has already the users and password_resets tables.
The Application We’ll Be Building
We’ll be building a simple CRM application that allows sales managers to manage contacts, accounts, leads, opportunities, tasks and related activities. For the sake of simplicity we’ll try to add few interfaces as we can in our application. The main interface is a dashboard which contains the table of contacts and their status (lead, opportunity and customer). We’ll not add login and authentication in this tutorial as we’ll be the subject of another tutorial.
In our CRM database we’ll be making use of the following tables:
contacts — contains information about contacts/customers such as name, address, company/account, ,
activities — contains activities (phone calles, meetings and emails etc.) about the contacts,
accounts — contains information about contact companies,
users — contains information about the application users
We’ll also be using the following JOIN tables:
contact_status — contains contact status such as lead, opportunity or customer which indicates the stage in the sales cycle
activity_status — the activity status can be either pending, ongoing or completed,
contact_source — contains contact source.
The contacts table has the following fields:
id
title,
first name,
last name,
email,
phone,
address,
source_id,
date of first contact,
account_id,
status_id,
user_id,
The contact_status table has the following fields:
id,
status = (lead, proposal, customer, archived)
The contact_source table:
id,
name
The accounts table has the following fields:
id,
name,
description
The activities table has the following fields:
id,
date,
description,
contact_id
status_id The activity_status table has the following fields:
id,
status
Creating Laravel 5.8 Models
According to the database structure above, we’ll need to create the followng Eloquent models:
Contact
Account
Activity
ContactStatus
ContactSource
ActivityStatus
Head back to your terminal and run the following commands:
$ php artisan make:model Contact –migration
$ php artisan make:model Account –migration
$ php artisan make:model Activity –migration
$ php artisan make:model ContactStatus –migration
$ php artisan make:model ContactSource –migration
$ php artisan make:model ActivityStatus –migration
This will create models with the corresponding migrations files. The models exist in the app folder and you can find the migration files in the database/migrations folder.
The -m flag will also create the corresponding migration file for the model.
Next, in your terminal, run the following command to create the base tables:
$ php artisan migrate
You will get the following output:
Migration table created successfully.
Migrating: 2019_03_12_223818_create_contacts_table
Migrated: 2019_03_12_223818_create_contacts_table
Migrating: 2019_03_12_223832_create_accounts_table
Migrated: 2019_03_12_223832_create_accounts_table
Migrating: 2019_03_12_223841_create_activities_table
Migrated: 2019_03_12_223841_create_activities_table
Migrating: 2019_03_12_223855_create_contact_statuses_table
Migrated: 2019_03_12_223855_create_contact_statuses_table
Migrating: 2019_03_12_223904_create_contact_sources_table
Migrated: 2019_03_12_223904_create_contact_sources_table
Migrating: 2019_03_12_223912_create_activity_statuses_table
Migrated: 2019_03_12_223912_create_activity_statuses_table
In Laravel, you can specify the structure (table fields) in the migration files. Let’s start with the contacts table. Open the database/migrations/2019_03_12_223818_create_contacts_table.php file (the date prefix for the file will be different for you) and add the following changes:
public function up()
{
Schema::create(‘contacts’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘title’);
$table->string(‘first_name’);
$table->string(‘last_name’);
$table->string(’email’);
$table->string(‘phone’);
$table->string(‘address’);
$table->date(‘date’);
$table->biginteger(‘user_id’)->unsigned(); $table->foreign(‘user_id’)->references(‘id’)->on(‘users’); });
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_accounts_table.php file and change accordingly:
public function up()
{
Schema::create(‘accounts’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘name’);
$table->description(‘description’); });
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_activities_table.php file and change accordingly:
public function up()
{
Schema::create(‘activities’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘description’);
});
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_contact_statuses_table.php file and change accordingly:
public function up()
{
Schema::create(‘contact_statuses’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘status’);
});
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_contact_sources_table.php file and change accordingly:
public function up()
{
Schema::create(‘contact_sources’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘name’);
});
}
Next, open the database/migrations/<YOUR_TIMESTAMP>_create_activity_statuses_table.php file and change accordingly:
public function up()
{
Schema::create(‘activity_statuses’, function (Blueprint $table) {
$table->bigIncrements(‘id’);
$table->timestamps();
$table->string(‘status’); });
}
You can see that we didn’t create any foreign keys between the tables. That’s because we need to avoid any issues to creating a foreign key to a table that doesn’t exist yet. The order of the migrations is important so you either make sure that the tables that are being referenced are created first or create the tables without any foreign keys and then add a migration to update the tables with the required relationships after the tables are created. Now, let’s create the update_contacts_table migration by running the following command:
$ php artisan make:migration update_contacts_table –table=contacts
Created Migration: 2019_03_12_235456_update_contacts_table
Open the database/migrations/<YOUR_TIMESTAMP>_update_contacts_table.php file and update accordingly:
public function up()
{
Schema::table(‘contacts’, function (Blueprint $table) {
$table->biginteger(‘source_id’)->unsigned(); $table->foreign(‘source_id’)->references(‘id’)->on(‘contact_sources’); $table->biginteger(‘account_id’)->unsigned(); $table->foreign(‘account_id’)->references(‘id’)->on(‘accounts’); $table->biginteger(‘status_id’)->unsigned(); $table->foreign(‘status_id’)->references(‘id’)->on(‘contact_statuses’);
});
}
We create three foreign key relationships to the contact_sources, accounts and contact_statuses tables.
Next, let’s create the update_activities_table migration by running the following command:
$ php artisan make:migration update_activities_table –table=activities
Created Migration: 2019_03_13_002644_update_activities_table
Open the database/migrations/<YOUR_TIMESTAMP>_update_activities_table.php file and update accordingly:
public function up()
{
Schema::table(‘activities’, function (Blueprint $table) {
$table->biginteger(‘contact_id’)->unsigned(); $table->foreign(‘contact_id’)->references(‘id’)->on(‘contacts’); $table->biginteger(‘status_id’)->unsigned(); $table->foreign(‘status_id’)->references(‘id’)->on(‘activity_statuses’); });
}
We create two foreign keys to the contacts and activity_statuses table.
Now, run the following command to migrate your database:
$ php artisan migrate
Implementing the Models
The Eloquent ORM included with Laravel provides a beautiful, simple ActiveRecord implementation for working with your database. Each database table has a corresponding "Model" which is used to interact with that table. Models allow you to query for data in your tables, as well as insert new records into the table. The official docs
We can interact with our database tables using the corresponding Eloquent models so we need implement the required methods in each model.
Defining the Relationships between Models
A contact belongs to a source, a status, an account and to a user and has many activities.
An account belongs to a user (i.e created by a user) and has many contacts.
An activity belongs to a status, a contact and to a user.
A contact status has many contacts.
A contact source has many contacts.
An activity status has many activities
Open the app/Account.php file and change accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Account extends Model
{
public function contacts(){
return $this->hasMany(‘App\Contact’);
}
public function user(){
return $this->belongsTo(‘App\User’);
}
}
Next, open the app/Activity.php file and change accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Activity extends Model
{
public function contact(){
return $this->belongsTo(‘App\Contact’);
}
public function status(){
return $this->belongsTo(‘App\ActivityStatus’);
}
public function user(){
return $this->belongsTo(‘App\User’);
}
}
Next, open the app/ActivityStatus.php file and change accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ActivityStatus extends Model
{
public function activities(){
return $this->hasMany(‘App\Activiy’);
}
}
Next, open the app/Contact.php file and update accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Contact extends Model
{
protected $fillable = [
‘title’,
‘first_name’,
‘last_name’,
’email’,
‘phone’,
‘address’,
‘date’ ];
public function source(){
return $this->belongsTo(‘App\ContactSource’);
}
public function status(){
return $this->belongsTo(‘App\ContactStatus’);
}
public function account(){
return $this->belongsTo(‘App\Account’);
}
public function user(){
return $this->belongsTo(‘App\User’);
}
public function activities(){
return $this->hasMany(‘App\Contact’);
}
}
Next, open the app/ContactSource.php file and update accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ContactSource extends Model
{
public function contacts(){
$this->hasMany(‘App\Contact’);
}
}
Next, open the app/ContactStatus.php file and update accordingly:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ContactStatus extends Model
{
//
public function contacts(){
$this->hasMany(‘App\Contact’);
}
}
Finally, open the app/User.php file and update as follows:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
‘name’, ’email’, ‘password’,
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
‘password’, ‘remember_token’,
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
’email_verified_at’ => ‘datetime’,
];
public function contacts(){
$this->hasMany(‘App\Contact’);
}
public function activities(){
return $this->hasMany(‘App\Activiy’);
}
public function accounts(){
return $this->hasMany(‘App\Account’);
}
}
Next we’ll be creating the REST API controllers.
via Planet MySQL Laravel 5.8 REST CRUD API Tutorial – Build a CRM [PART 1]: Eloquent Models and Relationships
DocuSign, best known for its digital signature business, is releasing new tools that focus on the entire process of drawing up and completing agreements.
It’s part of a broader effort by the company to expand beyond its core offering of e-signatures, in the face of growing competition in that space from Adobe and other rivals. Going forward, DocuSign wants to convince customers it is more than just an e-signature company, a move that opens up new fronts of competition against global companies like Oracle as well as Pacific Northwest startups like Icertis, all while attempting to get on a path of long-term profitability.
The three new tools are part of an ongoing evolution to owning what the company calls the “agreement cloud.” By providing tools to not only sign documents but create and manage them, DocuSign believes it will double its market opportunity, CEO Dan Springer said in an interview with GeekWire.
“E-signature was the first step to unlocking the modernization and automation of (customers’) system of agreement,” Springer said. “But now we are coming to what feels like the natural fruition of the start of that journey by saying we have a full agreement cloud solution. You can go back through your entire system as a customer and modernize that and automate that process and get rid of the paper and get rid of the manual processes to allow you to have a much more cost efficient and effective system that’s also a lot friendlier for the environment.”
DocuSign originally started in Seattle and later relocated its headquarters to the San Francisco Bay Area, though more than a third of the company’s 3,100 employees remain in its original hometown. With 1,074 employees and contractors, the Seattle office is DocuSign’s largest, followed by San Francisco with 816 people.
Here is a look at the new tools, which will debut in DocuSign’s ’19 Release:
DocuSign Gen for Salesforce, available on Salesforce AppExchange, lets sales reps and other users automatically generate signature-ready contracts within Salesforce with a few clicks.
DocuSign Click lets organizations set up a single-click process for getting consent on standard agreement terms on websites, such as a privacy policy.
DocuSign ID Verification digitizes and automates verifying government identification in sensitive transactions, like opening a bank account, which would normally require someone to present a physical ID.
In addition to these new tools, DocuSign continues to invest in document creation and storage through the integration of SpringCM, the Chicago-based company that DocuSign acquired for $220 million last year.
Springer compared DocuSign’s evolution to when Salesforce branched out beyond sales to focus on broader services approximately a decade ago. He downplayed competition in the company’s new realm, arguing that no one else is providing services to shake up the entire agreement process, and instead said the biggest challenge is getting customers to recognize that DocuSign is not just a signature company.
DocuSign pegged the value of its original market of e-signatures at roughly $25 billion. But the market opportunity in the full system of agreement is twice as large, at $50 billion, the company says.
DocuSign, which was the long-time leader on the GeekWire 200 list of the top Pacific Northwest startups, went public last April. Its stock shot up 30 percent out of the gate, with investors showing serious appetite for the enterprise software company. The stock has since climbed 43 percent, rising faster than the Nasdaq Stock Exchange it is listed on, though it is down 5.7 percent today.
DocuSign’s surge on the public markets is part of an interesting trend of unprofitable growth companies faring much better among investors than companies that focus more on profits. DocuSign did eek out a small non-GAAP profit for the first time last year, though it has traditionally prioritized growth over profit.
Springer expects DocuSign to post operating profits of about 20 to 25 percent in three to five years, up from the 5 percent profits projected for this year. Springer thinks the company’s focus on growth and scale will ramp up profits in the coming years.
“If we find choices and tradeoffs, we are growth company, so we will make the investments in growth and not have the increased profitability come as fast,” said Springer. “But at this current point we believe we’ll be doing both, keeping the high growth point and improving profitability.”
DocuSign capped its first year as a public company by besting analyst expectations for revenue and profits in the fourth quarter. For the full year, DocuSign posted $701 million in revenue, up 35 percent over year-over-year. This year, the company expects revenue of $910 million to $915 million, which would represent 29.8 to 30.5 percent growth over last year. DocuSign finished the year with 477,000 customers.
Infrastructure remains one of DocuSign’s largest costs as it delves further into the “agreement cloud.” Rather than working with a public cloud provider like Amazon or Microsoft, DocuSign has its own “rings” of data centers, with three a piece in the U.S. and Europe.
Springer says DocuSign has very high standards for redundancy and making sure its systems are always running smoothly. He gave an example of a customer using its e-signature services, T-Mobile, to show the importance of reliability and why it runs its own data centers.
“Whether you go into a store, whether you call into a call center, whether you go onto the website, every route you go it goes through DocuSign,” Springer said. “So if we were down, they are down for business.”
The cloud is capable of hosting virtually any application. However, certain development and design considerations can help optimize cloud deployment in a way that facilitates present performance and future growth. Therefore, both cloud providers and application owners must have a clear picture of what a cloud-ready application looks like. They can then facilitate the services and infrastructure needed to maximize performance.
Building a cloud-ready application isn’t something every techie inherently understands. Instead, it’s a skill that requires meticulous planning and seamless execution. When developers don’t build cloud applications for the cloud, those applications fail to deliver the value they should. Fortunately, programmers can easily learn how to create applications that are a perfect fit for the cloud.
Here are three of the most
important tips you should consider when building a cloud-ready application.
1.
A Collection of Services
Don’t build a cloud application as a monolith. Instead, deploy it as an aggregation of APIs. Therefore, start by defining the data. Next, create the cloud services needed to manage this data. Finally, combine these APIs into either higher-level composite services or complete compound applications. This, in a nutshell, is the principle of service-based application architecture.
While this is a widely understood concept in the developer community, a surprising number of programmers still create unwieldy, tightly coupled software. Moreover, their designs seem more focused on a spectacular user interface than they are on efficiently blending the underlying services. However, API-based and loosely coupled applications make it easier to tap into the distribution power of cloud infrastructure.
Additional advantages of API-based software include the potential for reuse by other applications and much better granularity. Granularity can be especially handy where an application is made up of hundreds or thousands of underlying services that can be readily isolated. That way, application developers don’t have to reinvent the wheel each time they set out to create a new application.
Perhaps the best example of how convenient API
reuse can be is the credit-check service that a wide range of applications use.
If you have this as a reusable API, you can cut down on your development time.
2.
Decoupling the Data
Decoupling an application’s components is one thing. However, decoupling the data is another. Moreover, the latter is every bit as important as the first. That’s because when your data is too deeply tied into an application, it won’t be a good fit for the cloud. Application architecture that separates data and processing will be more at home in cloud environments.
Moreover, when you decouple data, you gain the ability to store and process it on a server instance of your choosing. For instance, some organizations prefer that their data remain on their local in-house servers while the applications run in the cloud. This would be hard to do if the developer hasn’t sufficiently decoupled the data from the application.
All the same, developers must balance decoupling against performance requirements. If there’s too large a gap between the data and the software, latency could weigh down overall performance. Ultimately, developers must make sure data remains separate from the application but that it does not sit too far away for the application to easily leverage it.
One way to do that is to employ a caching system. This can bolster performance by storing locally the most commonly accessed data sets. Therefore, this reduces the number of read requests that have to be relayed back to the database. However, caching systems must be built into the application itself and tested for efficiency.
3.
Model for Scale
One of the main reasons a growing number of governments and large corporations have opted to run their applications in the cloud is the ease of scaling. Additionally, some cloud providers offer auto-scaling provisioning to accommodate rapid changes in network, database, and application loads. But such scaling capacity won’t matter much if the applications themselves aren’t built from the ground up with scaling in mind.
Designing for scaling means thinking about how the application performs under a growing load. Do the application and the back-end database behave the same way irrespective of whether 10 or 1,000 users simultaneously log into it? If such perfectly consistent behavior isn’t possible, is the deterioration in performance small enough to go largely unnoticed by end users?
Building an application that’s ready for cloud scaling means understanding its regular workload and defining a path for scaling it during workload surges. Such architecture must go hand-in-hand with robust monitoring mechanisms that leverage the appropriate performance and access management tools.
Building a Cloud-Ready Application Requires Attention to Detail
Building a cloud-ready application requires you to pay attention to several aspects of the architecture. However, the above three are the most important. If you haven’t tried to build a cloud-ready application before, you can expect to make a couple of mistakes at the beginning. However, with practice you’ll eventually understand what works.
No IFAK, Go Bag, or Range Bag is complete without a tourniquet.
Period.
Whether you’re prepping for when SHTF, or simply looking to build a comprehensive first-aid kit for your home, you’ll need tourniquets.
But knowing what type to get and which model isn’t as easy as it should be. That’s why we’re going to take a hard look at tourniquets!
There seems to be a lot of myths regarding tourniquets out there, including the risks they involve, how they are used, and which the best ones. Today, we’re going to set the record straight and explain what you need to know about this handy, life-saving tool.
Are Tourniquets Dangerous?
It’s a common myth that tourniquets are unsafe to use. The truth is–no, not if they are applied correctly. A modern tourniquet is very safe to use. There seems to be a debate that goes back and force regarding nerve damage and tourniquets.
However, if you are deploying a tourniquet nerve damage is one of the last things you need to worry about. Someone dying from blood loss likely won’t mind some nerve damage from a tourniquet if it means surviving.
The only way a TQ is dangerous is if you attach it to the neck to stop the bleeding of a head wound. For obvious reasons, this will cause other significant complications, like asphyxiation.
The Big Two TQs
Tourniquets have been around for hundreds of years, and they’ve evolved considerably from early versions. While many people are familiar with the old belt-and-stick survivalist-type of tourniquet, the reality is that a professional-grade TQ just isn’t that hard to carry and can easily be on hand.
Now the trick is to find which tourniquet is the right one for you to carry. If anyone knows about using a TQ it’s the guys in tactical and emergency medicine–who all suggest two tourniquets and two tourniquets only: the CAT and the SOFTT.
Both tourniquets are similar in design, and both are in use by the United States military. They also are both designed to be used with one hand, which is critical when it comes to self-care.
Let’s take a closer look at both designs, and discuss the pros and cons of each.
By far one of the most popular tourniquet options out there, CAT stands for Combat Application Tourniquet. These TQs typically cost anywhere from 26 to 35 dollars, making them an affordable addition to your just-in-case supplies.
The CAT uses an adjustable strap that latches down and is secured by plenty of velcro, as well as a plastic windlass that is easily rotated to tighten the TQ to stop the bleeding.
This type of tourniquet also features a red tip to make the end of the velcro strap easy to find and a white velcro strap that serves double duty to secure the windlass and provide a place to write the time down that the tourniquet was applied.
Writing the application time directly onto the TQ allows hospitals to identify how long the tourniquet has been there and will help them prioritize treatment.
The windlass locks into one of two hooks on the side of the TQ, which is then secured by that white strap.
CAT tourniquets are compact, foldable, and easy to apply to yourself or another person with only one hand. For this reason, they’re incredibly popular with civilian first-aid kits, emergency medical staff, and the military.
If you’re looking for an alternative to the CAT, the SOFTT by Tactical Medical Solutions is a great one. It’s very similar to the CAT in the sense that it can be applied with one hand. Older SOFTT models had some issues, but the modern SOFTT Wide model has solved much of these and become standard.
Unlike the CAT, the SOFTT uses a metal windlass that is heavily textured. A metal windlass is able to stand up to more abuse than a plastic windlass so it’s a great choice for durability. The heavily textured handle is also beneficial if you’re wearing gloves or are covered in blood.
A great benefit to the SOFTT is a metal latch on the strap that makes it easier to open and place around a trapped arm or leg. The adjusting strap has a friction buckle to prevent the strap from loosening–which would obviously defeat the point of a TQ.
The SOFTT also has a safety set screw that allows the user to lock the windlass down completely. This will prevent the TQ from becoming loose when moving the patient. The SOFTT is an excellent tourniquet and is gaining ground in the tactical medicine world.
Beware of Frauds
As with any popular product, there are knockoffs of the leading TQ brands which can look more appealing than they really are. Let’s face it–when your life is on the line, you don’t want to see your cheap TQ fail. There’s a reason to invest in getting the real thing.
Unfortunately, the internet is full of fake or low-quality tourniquets, especially when it comes to the CAT’s design. If you’re checking out your favorite online mega-retailer for a TQ, be sure to check the prices. A $14 “CAT” tourniquet is a dead giveaway that you’re looking at a fake.
Don’t forget to take a look at the manufacturer, as well. North American Rescue makes CAT tourniquets and Tactical Medical Solutions is the favorite maker of SOFTT tourniquets. Both types will cost more than $25 per tourniquet–which is well worth it in a life or death situation.
How To Use One
Before you can save a life with your tourniquet, you have to learn to use it! Here’s a video from Mass General Hospital showing you just how to apply a tourniquet to a limb.
While you can learn how to use a tourniquet from a video, nothing beats hands-on instruction. If you’re interested in learning how to apply tourniquets and perform other life-saving emergency first-aid, it’s well worth the investment to take a class.
Check out the Red Cross training site to see what first-aid classes are offered in your area!
Practice Applying your TQ
Once you’ve learned how to apply a tourniquet, it’s important to continue to practice the technique. If a tourniquet is needed, you have a matter of seconds to act, so you need to keep your skills sharp.
While you can train with your emergency TQ, you might want to get one specifically for practice. Repeated use of your tourniquet can wear it out, and you want your tourniquet to be in great condition and ready to use when you need it.
There are purpose-built training TQs, but you also can use a cheap knock off to practice. Just don’t forget to mark it in some way so you know at a glance which is which.
Best Tourniquet Holders
Carrying a TQ as part of your EDC is pretty easy. Unlike a gun or even a knife, you don’t have to conceal it. It doesn’t matter if someone sees your TQ. You can shove one in your pocket, but a belt pouch is likely the better choice.
Companies like Wilder tactical, HSGI, and North American Rescue all produce high-quality belt mounted TQ pouches, so you have lots of options. You also can stash one in your vehicle, backpack, or medical kit easily.
Wherever you choose to carry your tourniquet, be sure you can access it very quickly. It doesn’t do you any good if you need to dig around just to find the thing–not to mention get it out, on the injured person, and secured.
Here are a few different TQ carriers to keep your tourniquet accessible and ready to rock when you need it.
5.11 Tactical 3×6 Med Kit
A combination tourniquet holder and med kit, this option is a great way to securely carry your TQ and other necessary medical supplies–without getting in your way.
A convenient, simple method to attach your tourniquet to a MOLLE system. It’s designed to work with CAT and SOFTT tourniquets and can be attached to the top of the Blue Force Gear IFAK kits.
Wilder Evolution Series Universal Tourniquet Pouch
This system is available with a number of attachment options, including MOLLE, Tek-Lok, and Quick Clips, and works with both CAT and SOFTT tourniquets.
North American Rescue Rigid Gen 7 C-A-T Tourniquet Case
Made by one of the leading CAT tourniquet manufacturers, this case is a durable holder for your CAT tourniquet. It easily attaches to a belt with the Blade-Tech Telkom Belt Attachment.
Are tourniquets a must have? I think so. About 50% of combat deaths were due to blood loss in wars past, and I would hazard a guess that too many people in the civilian world have died due to a preventable hemorrhage.
A TQ is a very cheap investment and for less than $50, you have a potentially life-saving tool. Of course, it’s useless if you don’t learn how to use it.
Brushing up on your emergency first-aid knowledge with a class can be a little costly, but if it means you have the knowledge and practice to save your own life or the life of another, it’s well worth the price.
What are your experiences with tourniquets? Do you feel like the RATs or the ratcheting tourniquets are good to go? If so let us know below. Don’t forget to check out our reviews of the best IFAK kits out there to keep building your emergency medical kit.
John Wick seemingly cashes in all of his goodwill while being given more heads and torsos to destroy at point-blank range in the second trailer for John Wick: Chapter 3 – Parabellum. Premieres 5/17/19.
While perusing YouTube recently, I spotted a teaser screen which said, “Do not focus on the front sight!” Naturally, I decided to check it out.
The video is from NOIR Training, a service founded by Navy SEALs which “provides world class firearms and tactical training to Military, Law Enforcement, and Civilians.”
Like the video itself, the description is direct and to the point:
All about standard pistol sights. This is required viewing before any NOIR Training pistol course.
If you have any interest in shooting handguns with iron sights, view the entire video. It contains some of the best and most-understandable explanations and descriptions you’ll find, given by a narrator as we see a series of images to coincide with his words. For example, he does a good job explaining why it can be perfectly acceptable to fire at a target without a perfect sight picture, depending on the size and proximity of the target.
Around the 3:40 mark, things get even more interesting.
This is one area we differ from conventional shooting doctrine: We advocate shooting with your eyes focused on the threat, rather than the front sight.
The reason for this is, in a real life-threatening situation, your eyes will naturally focus on the threat. Since you can shoot perfectly accurately while focusing on the threat, we believe front sight focus is an unnatural and unnecessary complication.
He then goes on to explain the difference between front sight and target focus. While front sight focus can and will allow you to shoot accurately, he says, it’s “unnatural and unnecessary.” By contrast when you focus on the target, which is the natural thing to do when faced with a threat, you can still see both front and rear sights well enough to line them up to aim.
Interesting.
He then goes on to explain why we should all learn to shoot our handguns with both eyes open — because in a real life-threatening situation, we need to keep both peepers peeled.
I hope you find this as interesting as I did. Yes, it’s basic… but even the most experienced shooters can benefit from a fresh look at the basics.
A Detailed Comparison Between WordPress And October CMS
Leonardo Losoviz
Three months ago, WordPress finally released React-powered Gutenberg to power its default content editing experience, triggering many people who are not happy with this change to look for alternatives. Some folks decided to fork and release pre-Gutenberg WordPress, however, for me this doesn’t make much sense since it still carries 15 years worth of technical debt. If I were to find an alternative to WordPress, I would try to avoid being stuck in the past, and aim for a clean cut through some mature platform built on modern foundations.
This article compares WordPress to the arguably similar yet more modern October CMS on a wide arrange of both technical and non-technical topics. The goal of the article is not to convince people to stick to WordPress or to switch to October CMS, but simply to demonstrate what aspects must be taken into account before concluding the move to a different platform. The same comparison could (and should) also be done with other platforms before making a sensible decision.
Why October CMS
I found out about October CMS when it won an award, after which I went into research mode and spent a good deal of time digging deep into this CMS — from the perspective of both a user and a developer. As I gained knowledge on this CMS, I felt confident that I could provide an objective evaluation of its features as contrasted to WordPress. I chose this CMS for the comparison over alternative options such as Grav, Statamic, ButterCMS, Joomla, Drupal, Jekyll, Hugo, and others, for the following reasons:
I know how this CMS works (unlike Grav);
It is free and open source (unlike Statamic and ButterCMS);
At five years, it is “relatively” new (unlike Joomla and Drupal);
It is a dynamic (not static) content generator and based in PHP (unlike Jekyll and Hugo).
I believe that October CMS is a good candidate because it is based on Laravel which is a framework used for building modern applications. After seven years of existence, it has received positive approval from developers (as evidenced by its sizeable community and ecosystem), and marks a distinct contrast over coding in WordPress, i.e. WordPress is mostly procedural programming while Laravel is decidedly object-oriented programming.
What’s The Difference Between The Two?
Below I will compare WordPress and October CMS on different categories and highlight what, I believe, is good and not so good about them. However, I will not pick a winner, since that’s not the objective of the article and, in any case, there is no “best” or even “better” CMS: each CMS has its own set of strengths and weaknesses that will make it more or less suitable for each task, project, company, team, and anything else. Moreover, a project may benefit from using more than one CMS, such as using some CMS to manage and provide data, and another CMS to render the view. To decide which of the dozens of CMSs out there is most suitable for your own needs is entirely up to you.
In addition, this article could never draw definitive conclusions since it is only concerned with a subset of all possibilities. For instance, we can also find online comparisons such as “WordPress vs Drupal vs Joomla”, “WordPress vs Static Site Generators” and even “WordPress vs Medium”. Because none of these articles sees the full picture, then none of these comparisons can ever be conclusive, and should not be treated as such.
Let’s start with the comparison.
Philosophy And Target Group
It is no coincidence that WordPress powers nearly 1 in 3 websites. Ever since its inception, it has strived to be extremely user-friendly and has done so successfully, removing friction for technical and non-technical users alike as well as for people from all backgrounds — irrespective of their education and economic levels. WordPress’ founder Matt Mullenweg expressed that WordPress’ motto of “Democratize Publishing” for the current era meant the following:
“People of all backgrounds, interests, and abilities should be able to access Free-as-in-speech software that empowers them to express themselves on the open web and to own their content.”
WordPress is easy to use for everyone and its inclusivity is evidenced on the development side too: It’s not uncommon to find people without a programming background (such as marketers, designers, bloggers, sales people, and others) tinkering with their WordPress installations, designing their own themes and successfully launching their own websites. WordPress is user-centric, and the needs of the users trump those of the developers. In WordPress, the user is king (or queen).
“October makes one bold but obvious assumption: clients don’t build websites, developers do. The role of a client is to manage the website and convey their business requirements. The web developer, and the industry itself, revolves around mediating these factors.”
In the words of its founders, the CMS’ mission is to “prove that making websites is not rocket science.” Being based on Laravel, October CMS can claim to have strong foundations of reusable, modular code that can produce properly-architected applications, maintainable in the long term and fully customizable without requiring hacks — the type which attracts serious programmers. October CMS can also provide a great user experience, however, it is not as simple or frictionless as that provided by WordPress. Users may need to be explained how to use certain functionality before being able to use it. For instance, embedding a form from some plugin has a lengthy explanation on how to do it, which is more cumbersome than the self-evident, drag-and-drop functionality provided by several form plugins in WordPress.
Installation
WordPress is famous for its 5-minute installation, even though many people point out that (taking into consideration all the plugins that must be installed) a typical installation requires 15 minutes or more. In addition, WordPress also offers the Multisite feature, which allows us to create a network of multiple virtual sites under a single installation. This feature makes it easy for an agency to administer the sites of multiple clients — among other user cases.
Installing October CMS is also very smooth: The Wizard installation itself takes even less than five minutes, and if you install it through the Console installation, it is even faster. You can do the latter by simply navigating to the target directory and then executing curl -s https://octobercms.com/api/installer | php (after which we need to input the database configuration, otherwise it behaves as a flat-file CMS). Once the installation has been completed, we will have a fully functioning website, but still quite bare (if you add the time needed to install and configure the required plugins, you can expect it to take at least 15 minutes).
Security
WordPress has been accused of being insecure due to the high amount of vulnerabilities that are constantly found. This forces users to have the software for the CMS and all installed plugins always up to date to avoid security exploits. Among the main issues is WordPress’ support for older versions of PHP which are not supported by the PHP development community anymore (WordPress currently supports PHP 5.2.4, while the latest fully supported PHP version is 5.6). However, this problem should be resolved in April 2019 when WordPress will officially start supporting PHP versions 5.6 and upwards.
Otherwise, WordPress is not necessarily insecure because of itself, but because of its high popularity, which makes it a primal target for hackers. However, this plays both ways: WordPress ubiquity means that its security team must really take their job seriously by constantly looking for exploits and fixing them as soon as possible, otherwise up to a third of the web is at risk. The stakes are just too high.
October CMS, on the other hand, doesn’t have a reputation of being insecure. However, since there are roughly 27,000 live sites that use October as compared with WordPress’ millions, we can’t judge the two of them on the same terms. Nevertheless, the team behind October CMS does take security seriously, as evidenced by the Wizard installation’s prompt to input the CMS backend URL, set as /backend by default but changeable to anything else, as to make it more difficult for hackers to target the site. In contrast, changing WordPress’ login and backend URLs from /wp-login.php and /wp-admin respectively to something else must be done through a plugin. In addition, October CMS can function as a flat-file CMS (i.e. without a database) and avoid database-related vulnerabilities such as SQL injection.
Technology Stack
Both WordPress and October CMS run on the traditional LAMP stack: Linux, Apache, MySQL, and PHP. (However, only PHP is fixed: we can also use Windows, Nginx, MariaDB, and others.) October CMS can also behave as a flat-file CMS, meaning that it can do without a database, however, at the cost of forgoing many functionalities (such as blog posts and users) the only functionality that is guaranteed is pages, which is considered to be the basic unit for the creation and publishing of content and shipped as a core feature.
Concerning the language stack, sites built with both WordPress and October CMS are based on HTML, CSS, and JavaScript (note that PHP is used to generate the HTML). October CMS also makes it easy to use LESS and SASS files.
Programming Paradigm
WordPress follows a functional programming paradigm, based on calculating computations by calling functions devoid of application state. Even though WordPress developers do not need to stick to functional programming (for instance, for coding their themes and plugins), the WordPress core code inherits this paradigm from 15 years of preserving backwards compatibility, which has been one of the pillars to WordPress’ success but which has the unintended consequence of accumulating technical debt.
Programming in WordPress could be characterized as HDD which stands for “Hook-Driven Development”. A hook is a mechanism that allows changing a default behavior or value and allowing other code to execute related functionality. Hooks are triggered through “actions” which allow executing extra functionality, and “filters” that allow modifying values.
Hooks, which are widespread across the WordPress codebase, are one of the concepts that I most like from coding in WordPress. They allow plugins to interact with other plugins (or with a core or theme) in a clean way, providing some basic support of Aspect-Oriented Programming.
Good news is that Laravel (and in consequence October CMS) also supports the concept of hooks, which is called “events”. Events provide a simple observer implementation, enabling code to subscribe and listen for events that occur in the application and react as needed. Events make it possible to split a complex functionality into components, which can be installed independently yet collaborate with each other, thus enabling the creation of modular applications.
Dependence on JavaScript Libraries
The latest version of WordPress incorporates React-powered Gutenberg for its default content creation experience. Hence, WordPress development now relies by and large on JavaScript (predominantly through React), even though it is also possible to use other frameworks or libraries (as evidenced by Elementor Blocks for Gutenberg which is based on Marionette). In addition, WordPress still relies on Backbone.js (for the Media Manager) and jQuery (legacy code), however, we can expect the dependence on these libraries to wither away as Gutenberg is consolidated as the new norm.
October CMS depends on jQuery, which it uses to implement its optional AJAX framework to load data from the server without a browser page refresh.
Pages, Themes and Plugins
Both WordPress and October CMS treat a page as the basic unit for creating and publishing content (in WordPress case, in addition to the post), support changing the site’s look and feel through themes, and allow to install and extend the site’s functionalities through plugins. Even though the concepts are the same in both CMSs, there are a few differences in implementation that produce somewhat different behavior.
In WordPress, pages are defined as content and stored in the database. As a result, page content can be created through the CMS only (e.g. in the dashboard area), and switching from one theme to another doesn’t make an existing page become unavailable. This produces an overall frictionless experience.
In October CMS, on the other hand, pages are static files stored under the theme directory. On the positive side from this architectural decision, page content can be created from an external application, such as text editors like Sublime or Visual Studio Code. On the negative side, when switching from one theme to another, it is required to manually recreate or copy the pages from the current to the new theme, or otherwise, they will disappear.
Significantly, October CMS resolves routing through pages, hence pages are used not just as containers for content but also for functionality. For instance, a plugin for blogging depends on a page for displaying the list of blog posts under a chosen URL, another page to display a single blog post under another chosen URL, and so on. If any of these pages disappear, the associated functionality from the plugin becomes unavailable, and that URL will produce a 404. Hence, in October CMS themes and plugins are not thoroughly decoupled, and switching themes must be done carefully.
Core vs Plugin Functionality
WordPress attempts to deliver a minimal core functionality which is enhanced through plugins. WordPress relies on the “80⁄20 rule” to decide if to include some functionality in its core experience or not. If it benefits 80% of the users it goes in, otherwise, it belongs to plugin-land. When adding plugins to a site, they can lead to bloat if too many plugins are installed. Plugins may also not work well with one another, or execute similar code or load similar assets, resulting in suboptimal performance. Hence, whereas launching a WordPress site is relatively easy, a bigger challenge is its general maintenance and being able to preserve an optimal and performant state when adding new features.
Likewise, October CMS also attempts to deliver a minimal core functionality, but on steroids: the only guaranteed functionality is the creation and publication of pages, and for everything else we will need to install one plugin or another, which is expressed as:
“Everything you need, and nothing you don’t.”
The objective is clear: most simple sites are only composed of pages, with possibly no blog posts, users or login area. So why should the application load resources for these when they are not needed? As a consequence, functionalities for blogging, user management, translation and several others are released through the plugin directory.
October CMS also includes certain features in its core which (even though they are not always needed) can enhance the application significantly. For instance, it provides out-of-the-box support to upload media files to Amazon S3 and accesses them through the Rackspace CDN. It also includes a Media Manager which is mostly used through plugins, e.g. for adding images into a blog post. (Pages can also use the Media Manager to embed media files, however, the CMS also ships with an Assets section to upload media files for these which seems more suitable.)
I believe that October’s opinionatedness can perfectly enable us to produce an application that is as lean as possible — mostly concerning simple sites. However, it can also backfire and encourage bloat, because the line of what is needed and what is not is an arbitrary one, and it’s difficult to be set in advance by the CMS. This difficulty can be appreciated when considering the concept of a “user”: In WordPress, website users and website admins belong to the same user entity (and through roles and privileges we can make a user become an admin). In October CMS, these two are implemented separately, shipping in core the implementation for the website administrator which can log in to the backend area and modify the settings, and through a plugin the implementation of the website user. These two types of users have a different login process and a different database table for storing their data, thus arguably breaching the DRY (Don’t Repeat Yourself) principle.
This problem arises not only concerning the behavior of an entity but also what data fields it must contain. For instance, should the website user data fields be predefined? Is a telephone field required? What about an Instagram URL field, considering that Instagram got kind of cool only recently? But then, when building a professional website shouldn’t we use a LinkedIn URL field instead? These decisions clearly depend on the application and can’t be decided by either CMS or plugin.
The October CMS plugin called User implements users but without any user field, on top of which plugin User Plus adds several arbitrary user fields, which are possibly not enough, so plugin User Plus+ adds yet other user fields. When, where and how do we stop this process?
Another problem is when there is no room to add new capabilities to an entity, which leads to the creation of another, extremely similar entity, just to support those required capabilities. For instance, October CMS ships with pages, and allows to create “static pages” through a plugin. Their nature is the same: both pages and static pages are saved as static files. The only difference between them (as far as I can tell) is that static pages are edited with a visual editor instead of the HTML editor, and can be added to menus. In my opinion, only structural differences, such as having one entity saved as a static file and the other one stored in the database, could justify creating a second entity for a page (there is a pull request to do this), but for simple features, as is the case currently, it constitutes development bloat.
In summary, a well implemented October CMS application can be very lean and efficient (e.g. by removing the database when not needed), but on the contrary it can also become unnecessarily bloated, forcing developers to implement several solutions for similar entities, and which can be very confusing to use (“Should I use a page or a static page?”). Because neither WordPress or October CMS has found a perfect solution for removing bloat, we must design either application architecture with care to avoid down-the-road pain.
Content Creation
Gutenberg makes two important contributions to WordPress: It uses components as the unit for building sites (which offers several advantages over coding blobs of HTML), and it introduces an entity called a “block” which, once Gutenberg Phase 2 is completed (presumably in 2019), will provide a unified way to incorporate content into the site, thus enabling a simpler user experience as opposed to the more chaotic process of adding content through shortcodes, TinyMCE buttons, menus, widgets, and others.
Because Gutenberg blocks can produce and save static HTML as part of the blog post, then installing many Gutenberg blocks doesn’t necessarily translate into bloat on the website on the user side, but can be kept restricted to the admin side. Hence, Gutenberg can arguably be considered a good approach to produce websites in a modular way, with a simple yet powerful user experience for creating content. Possibly the biggest drawback is the (unavoidable, but not easily so) requirement to learn React, whose learning curve is rather steep.
If React components are the basic unit for creating content in WordPress, October CMS is based on the premise that knowing good old HTML is enough for building sites. Indeed, when creating a page, we are simply presented an HTML (Markup) editor:
If the page were solely static HTML, then there would be no need for a CMS. Instead, October CMS pages are written using Twig templates which are compiled to plain optimized PHP code. They can select a layout to include the scaffolding of the page (i.e. repetitive elements, such as the header, footer, and so on), can implement placeholders, which are defined on the layout to allow the page to customize content, and can include partials, which are reusable chunks of code. In addition, pages can include content blocks, which are either text, HTML or Markdown files that can be edited on their own and can attach components which are functionalities implemented through plugins. And finally, for whenever HTML is not enough and we need to produce dynamic code, we can add PHP functions.
The editor is all about HTML. There is no TinyMCE textarea for adding content in a visual manner — at least not through the default experience (this functionality belongs to plugin-land). Hence, having knowledge of HTML could be considered a must for using October CMS. In addition, the several different inputs for creating content (pages, layouts, placeholders, partials, content blocks, components, and PHP functions) may be very effective, however, it is certainly not as simple as through the unified block interface from WordPress. It can even get more complex since other elements can also be added (such as static pages and menus, and snippets), and some of them, such as pages and static pages, seemingly provide the same functionality, making it confusing to decide when to use one or the other.
As a result, I dare say that while pretty much anyone can use a WordPress site from the admin side, October CMS is more developer-friendly than non-technical user-friendly, so programmers may find it a joy to use, but certain other roles (marketers, sales people, and the like) may find it non-intuitive.
Media Manager
Both WordPress and October CMS are shipped with a Media Manager which allows adding media files to the site effortlessly, supporting the addition of multiple files simultaneously through a drag-and-drop interface and displaying the images within the content area. They look and behave similarly; the only notable differences I found are that WordPress’ Media Manager allows to embed image galleries, and October’s Media Manager allows to manually create a folder structure where to place the uploaded files.
Since the introduction of Gutenberg, though, WordPress’ media capabilities have been enhanced greatly, enabling to embed videos, pictures and photo galleries in place as compared to within a TinyMCE textarea (which only provides a non-accurate version of how it will look like in the site), and unlocking powerful, yet easy-to-use features as shown in this video.
Internationalization
WordPress core uses gettext to enable the translation of themes and plugins. Starting from a .pot file containing all strings to translate, we need to create a .po file containing their translation to the corresponding language/locale, and this file is then compiled to a binary .mo file suitable for fast translation extraction. Tools to perform these tasks include GlotPress (online) and Poedit (downloadable application). Conveniently, this mechanism also works for client-side localization for Gutenberg.
WordPress currently doesn’t ship any solution in core to translate content, and will not do so until Phase 4 of Gutenberg (targeted for year 2020+). Until then, this functionality is provided by plugins which offer different strategies for storing and managing the translated content. For example, while plugins such as Polylang and WPML store each translation on its own row from a custom database table (which is clean since it doesn’t mix content together, but slower since it requires an additional INNER JOIN of two tables when querying the database), plugin qTranslate X stores all translations on the same field from the original database table (faster for querying the data, but content mixed all together can produce wreckage on the site if disabling the plugin). Hence, we can shop around and decide the most suitable strategy for our needs.
October CMS doesn’t ship the multilingual functionality through its core, but as a plugin created by the October CMS team that guarantees a faultless integration into the system. From a functional point of view, this plugin delivers what it promises. From a development point of view, it is not quite ideal how this plugin actually works. In WordPress, a page is simply a post with post type “page” and there is a single translation mechanism for them, but in October CMS, there are entities “page”, “static page” and “blog post” and, even though quite similar, they require three different implementations for their translations! Then, the content from a “page” can include message codes (e.g. codes called nav.content, header.title, and so on), each of which contains its translations for all locales as a serialized JSON object in database table rainlab_translate_messages. The content from a “static page” is created into a new static file per locale, however, all translated URLs for all locales are stored not in their corresponding file but instead on the default language’s file. The content for the “blog post” is stored as a serialized JSON object with one row per locale in database table rainlab_translate_attributes and the translated URL is stored with one row per locale in database table rainlab_translate_indexes. I don’t know if this complexity is due to how the plugin was implemented or whether it is due to October CMS’ architecture. Whichever the case, this is another instance of undesired bloat on the development side.
Plugin Management
Both WordPress and October CMS offer a sophisticated plugin manager which allows to search for plugins, install new plugins, and update currently-installed plugins to their latest version — all from within the backend.
Dependency Management
October CMS uses Composer as the package manager of choice, enabling plugins to download and install their dependencies when being installed, thus delivering a painless experience.
WordPress, on the opposite side, hasn’t officially adopted Composer (or any PHP dependency manager) because the community can’t agree if WordPress is a site or a site dependency. Hence, if they require Composer for their projects, developers must add it on their own. With the switch to Gutenberg, npm has become the preferred JavaScript dependency manager, with a popular developer toolkit depending on it, and the client-side libraries being steadily released as autonomous packages in the npm registry.
Interaction With The Database
WordPress provides functions to retrieve database data (such as get_posts) and store it (such as wp_insert_post and wp_update_post). When retrieving data, we can pass parameters to filter, limit and order the results, in order to indicate if the result must be passed as an instance of a class or as an array of properties and others. When the function doesn’t fully satisfy our requirements (e.g. when we need to do an INNER JOIN with a custom table) then we can query the database directly through global variable $wpdb. When creating a plugin with a custom post type, the code will most likely be executing custom SQL queries to retrieve and/or save data into custom tables. In summary, WordPress attempts to provide access to the database through generic functions in the first stage, and through low-level access to the database in the second stage.
October CMS employs a different approach: Instead of connecting to the database straight away, the application can use Laravel’s Eloquent ORM to access and manipulate database data through instances of classes called Models, making the interaction with the database also be based on Object-Oriented Programming. It is high-level access; just by following the rules on how to create tables and set-up relationships among entities, a plugin can retrieve and/or save data without writing a line of SQL. For instance, the code below retrieves an object from the database through model Flight, modifies a property, and stores it again:
$flight = Flight::find(1);
$flight->name = 'Darwin to Adelaide';
$flight->save();
Upgrading The Data Model
Another reason for WordPress’ success (in addition to not breaking backward compatibility) has been its database architecture, which was engineered to enable applications to grow over time. This objective is accomplished through “meta” properties, i.e. properties that can be loosely added to a database object at any moment. These properties are not stored in a column from the corresponding entity table (either wp_posts, wp_users, wp_comments or wp_terms), but instead as a row in the corresponding “meta” table (wp_postmeta, wp_usermeta, wp_commentmeta or wp_termmeta) and retrieved doing an INNER JOIN. Hence, even though retrieving these meta values is slower, they provide unlimited flexibility, and the application’s data model rarely needs to be re-architected from scratch in order to implement some new functionality.
October CMS doesn’t use meta properties but instead can store several arbitrary values, which are not directly mapped as columns in the database tables, as a serialized JSON object. Otherwise, when an object needs some new property, we need to add a new column on the corresponding table (which is the reason behind plugins User Plus and User Plus+, mentioned earlier on). To update the application’s database schema, October CMS relies on Laravel’s Migrations, which are sets of instructions to execute against the schema (such as add or drop a column, rename an index, etc) and which are executed when upgrading the software (e.g. when installing a plugin’s new version).
Headless Capabilities
Both WordPress and October CMS can be used as headless, i.e. treating the CMS as a content management system that makes content accessible through APIs, which allows to render the website on the client-side and can power other applications (such as mobile apps). Indeed, WordPress is steadily heading towards headless, since the Gutenberg content editor itself treats WordPress as a headless CMS (and, as a consequence, Gutenberg can also work with any other CMS too, as Drupal Gutenberg demonstrates).
A headless system needs to implement some API to return the data, such as REST and GraphQL. WordPress supports REST through WP REST API (merged in core), exposing endpoints under some predefined route /wp-json/wp/v2/...; October CMS supports REST through plugins RESTful and API Generator, which allow to create custom endpoints and, as a consequence, support versioning as part of the endpoint URL and can offer a better security against bots. Concerning GraphQL, WordPress supports it through WPGraphQL, while October CMS currently has no implementations for it.
Quite importantly, a headless system needs to offer powerful content management capabilities. As mentioned earlier on, WordPress has a very solid database architecture, offering a plethora of data entities (users, posts and custom posts, pages, categories, tags and custom taxonomies, comments) over which the application can be reasonably well modelled, meta properties to extend these data entities (enabling the application to upgrade its data model accordingly and without major changes), and with plugin Advanced Custom Fields filling the gap to construct relationships among the data entities. In addition, plugin VersionPress allows to version control the database content using Git. Hence, WordPress is undoubtedly a good fit for managing content, as demonstrated in severalprojectsinthewild.
On its part, and as mentioned earlier on, October CMS can omit the database and behave as a flat-file system, or it can have a database and behave as a hybrid, storing the content from pages as static files and blog posts (and others) on the database. As a consequence, content is not centralized, and its management involves a different approach. For instance, while we can use Git to version control pages, there is no support to version control the database per se; the solution to this is to populate data into the database through Seeders which, being code, can be put under version control and executed upon deployment. In addition, October CMS doesn’t offer a baked-in database model featuring predefined data entities that can support the needs of most applications. Hence, more likely than not the application will need custom development to implement its data model, which means more work, but also means that it can be more efficient (e.g. accessing a property from a column is faster than from a row in another table through an INNER JOIN, which is the case with WordPress’ meta properties).
CLI Support
Both WordPress and October CMS can be interacted with from the console through a Command Line Interface (CLI): WordPress through WP-CLI and October CMS through Laravel’s Artisan. In addition to Laravel’s commands, October CMS implements several custom commands for updating the system, migrating the database, and others. These tools make it very convenient to access the site from outside a browser, for instance for testing purposes.
Managed Hosting
It is not a problem finding a managed hosting provider for a WordPress site: given WordPress’ market share, there are dozens (if not hundreds) of providers out there vying with each other for the business, constituting a very dynamic market. The only problem is finding the most suitable provider for our specific sites based on all of their offerings, which can vary based on price, quality, type (shared or dedicated services), bandwidth and storage size, customer support, location, frequency of renewal of equipment, and other variables which we can navigate mainly through reviews comparing them (such as this one, this one or this one).
Even though nothing near as many as WordPress, October CMS still enjoys the offering from several hosting providers, which allows for some consideration and selection. Many of them are listed as October Partners, and several others are found DuckDuckGoing, but since I haven’t found any independent review of them or article comparing them, the task of finding out the most suitable one will take some effort.
Marketplace, Ecosystem And Cost
WordPress’ commercial ecosystem is estimated to be USD $10 billion/year, evidencing how many people and companies have managed to make a living by offering WordPress products and services, such as the creation of sites, hosting, theme and plugin development, support, security, and others. Indeed, its size is so big it is even bloated, meaning that it is very common to find different plugins solving the same problem, plugins that underdeliver, underperform or have not been updated for years, and themes which seem to look-alike each other. However, when creating a new site, the size and variety of the ecosystem also means that we will most likely find at least one plugin implementing each of the required functionalities, enabling us to save money by not having to develop the functionality ourselves, and the availability of customizable themes enables to produce a reasonably distinctive-looking site with minimal effort. As a consequence, we can easily create and launch a WordPress site for less than USD $100, making WordPress a sensible option for projects of any budget.
Being relatively new (only five years so far), OctoberCMS certainly doesn’t enjoy anything near WordPress’ marketplace and ecosystem sizes, however, it has been growing steadily so its size is bound to become bigger. Currently, its marketplace boasts 600+ plugins, and only a handful of themes. Concerning plugins, the October CMS team is requesting the community to put their effort into the creation of original plugins, delivering functionality not yet provided by any other plugin.
Hence, even though 600+ plugins doesn’t sound like much, at least these translate into 600+ different functionalities. This way, even though it is not possible to choose among several vendors, at least we can expect to have those basic website features (such as blogging, comments, forum, integration with social media, e-commerce, and others) to be covered. Also, since October’s founders are personally reviewing all submitted plugins and judging them according to quality guidelines, we can expect these plugins to perform as expected. As another plus, October plugins can incorporate elements from Laravel packages (even though not all of them are compatible with October, at least not without some hacks). Concerning themes, the low number of offerings implies we will most likely need to develop our own theme by hiring a developer for the task. In fact, I dare say that the theme in October CMS will most likely be a custom development, since themes and plugins are not thoroughly decoupled (as explained earlier), with the consequence that a market for easily-swappable themes is more difficult to arise. (This is a temporary problem though: once this pull request is resolved, pages will be able to be stored in the database, and swapping themes should not disrupt functionality.)
In my opinion, because of the smaller offerings of themes and plugins, creating a simple site with OctoberCMS will be more expensive than creating a simple WordPress site. For complex sites, however, October’s better architecture (Object-Oriented Programming and Model-View-Controller paradigms) makes the software more maintainable and, as a consequence, potentially cheaper.
Community
Being a part of and having access, WordPress’ community represents one of the most compelling reasons for using WordPress. This is not simply as a matter of size (powering nearly one third of all websites in the world, there are so many stakeholders involved with WordPress, and its community is representatively big) but also as a matter of diversity. The WordPress community involves people from many different professions (developers, marketers, designers, bloggers, sales people, and so on), from all continents and countries, speaking countless languages, from different social, educational and economic backgrounds, with or without disabilities, from corporate, not-for-profit and governmental organizations, and others. Hence, it is quite likely that, for whatever problem we encounter, somebody will be able to help on any of the support forums. And contributing to WordPress is pretty straightforward too: The Make WordPress group congregates stakeholders interested in supporting different projects (accessibility, design, internationalization, and many others) and organizes how and how regularly they communicate — mostly through some dedicated channel on its Slack workspace.
Furthermore, the WordPress community is real and tangible: it doesn’t exist just online, but it gathers offline in WordCamps and meetups all over the world; in 2018, there were a total of 145 WordCamps in 48 countries with over 45,000 tickets sold, and a total of 5,400 meetup events from 687 meetup groups. Hence, it is likely that there is a local chapter nearby which anyone can join to ask for help, learn how to use the platform, keep learning on a regular basis, and teach others as well. In this sense, WordPress is not just a CMS but, more importantly, it’s also people, and considering to leave WordPress should never be done only on its technical merits but on the power of its community, too.
October CMS’ community is nothing near in size or diversity as WordPress’, even though it has been growing steadily following the increasing popularity of the software. October provides a support forum to ask for help, however, it is not very active. A Slack workspace exists which is pretty active and where, quite importantly, October’s founders participate regularly, helping make sure that all enquiries are properly addressed. This channel is a great source for learning low-level tips and tricks about the software, however, it is geared towards developers mainly: There are no channels concerning accessibility, design, internationalization, and other topics as in the WordPress community, at least not yet. Currently, there are no conferences concerning October CMS, but there is Laracon, the conference for the Laravel community.
Maintainers And Governance
Can we trust that the software will be maintained in the long term, so that if we decide to start a project today, we will not need to migrate to some other platform down the road? How many people are taking care of developing the software? And who is deciding in what direction the software moves towards?
Powering one-third of all sites in the world, WordPress is not short of stakeholders contributing to the software; hence we need not fear that the software will fall into decay. However, WordPress is going through internal deliberations concerning its governance model, with many members of the community expressing that decisions concerning WordPress’s direction are being taken unilaterally by Automattic, the company running WordPress.com. Center stage of this perception was the decision to launch Gutenberg, which many members disagreed with, and which suffered a lack of proper communication by the project leads during its development and release. As a consequence, many community members are questioning the role of “benign dictator”, which has been historically granted to WordPress’ founder and Automattic’s CEO Matt Mullenweg, and researching different governance models to find a more suitable one for the future of WordPress. It is yet to be seen if this quest produces any result, or if the status quo perseveres.
Decisions concerning October CMS’ direction are mainly taken by founders Alexey Bobkov and Samuel Georges and developer and community manager Luke Towers, which keep the project going strong. October CMS doesn’t have the luxury of having a governance problem yet: Its current concern is how to make the project sustainable by generating income for the core software’s maintainers.
Documentation
WordPress documentation in its own site is not extremely comprehensive, but it does the job reasonably well. However, when taking all of the documentation about WordPress into account from all sources, such as general sites (Smashing Magazine, CSS tricks, and many others), specialized sites (WPShout, WPBeginner, and many others), personal blogs, online courses, and so on, there is practically no aspect of dealing with WordPress that hasn’t already been covered.
October CMS doesn’t enjoy anything near the many third-party courses, tutorials or blog posts about it as much as WordPress does, however, the documentation on its site is reasonably comprehensive and certainly enough to start coding. October founders also regularly add new documentation through tutorials. One aspect that I personally enjoyed is the duplication of Laravel’s documentation into October’s documentation for everything of relevance, so the reader must not fill the gaps by him/herself and having to guess what is October’s domain and what is Laravel’s. However, this is not 100% perfect. October’s documentation uses terms originating from Laravel, such as middleware, service containers, facades and contracts, without adequately explaining what these are. Then, reading Laravel’s documentation in advance can be helpful (luckily, Laravel’s documentation is decidedly comprehensive, and Laravel’s screencasts, Laracasts, are another great source of learning, not just concerning Laravel but web development in general).
Conclusion
I set out to discover what features may be enticing for developers looking for alternatives to WordPress by comparing WordPress to a similar CMS, which I defined as being free and open source, based in PHP and producing dynamic content, and enjoying the support from some community. From the CMSs fulfilling these conditions, I chose October CMS for the comparison because of the knowledge I got about it, and because I appreciated its clean and modular coding approach as provided by Laravel, which could offer a fresh and modern perspective for building sites.
This article did not intend to pick a winner, but simply analyze when it makes sense to choose one or the other CMS, highlighting their strengths and weaknesses. There is no “best” CMS: only the most suitable CMS for a specific situation. Furthermore, anyone looking for a CMS to use on a particular project with a specific team and given a certain budget, should do some research and compare all the offerings out there to find out which one is most suitable for the particular context. It’s important not to limit to a few CMSs as I’ve done here in this article, but instead give a chance to all of them.
On a personal note, as a developer, what I found in October CMS is really appealing to me, mostly its ability to build modular applications as provided through Laravel. I would certainly consider this CMS for a new website. However, in the process of writing this article I also “rediscovered” WordPress. Being so popular, WordPress receives more than its fair share of criticisms, mostly concerning its old codebase and, since recently, the introduction of Gutenberg; however, WordPress also has certain excellent features (such as its super-scalable database model) which are seldom praised but should be taken into account too. And most importantly, WordPress should not be considered on its technical aspects alone: in particular, the size of its community and ecosystem places it a level or two above its alternatives. In a nutshell, some projects may benefit from sticking to WordPress, while others may better rely on October CMS or another platform.
As a final note, I would like to remark that exploring how another CMS works is a very rewarding activity on its own, independent of the decision reached concerning whether to use that particular CMS or not. In my case, I had been working for years on WordPress alone, and delving into October CMS was very refreshing since it taught me many things (such as the existence of PHP Standards Recommendations) which I had not been exposed to through WordPress. I may now decide to switch CMSs, or stick to WordPress knowing how to produce better code.