Home >
Technical & Creative Skills >
Programming, Servers & Scripts
FREE TOOL: Create Landers From Slack! Free CMS To Organise Your Lander Nightmare (4)
10-04-2016 12:03 PM
#1
caurmen (Administrator)
FREE TOOL: Create Landers From Slack! Free CMS To Organise Your Lander Nightmare
So, I've seen a lot of questions over the recent past about how to manage landers. Should you use Wordpress, Unbounce, or another content management system to manage them and make them easier to create?
Well, I really don't recommend Wordpress. And non-affiliate lander solutions tend to be slow and inflexible.
So, whilst I was preparing for Affiliate World Europe 2016, I put together a test-of-concept for an affiliate-centric content management system. I gave that CMS out, as one of many free scripts, as part of my talk on automation there.
And now as AWA comes toward us, I'm sharing the same content management system for landers here on STM, free to use for you.
Features
The short version: this is a content management system for your landers, like Wordpress. However, it's much faster than Wordpress, much more minimal, and lets you create landers in a single line right from Slack!

- It's Ridiculously Fast. This CMS leverages a very little-known feature in the web server Nginx to serve pages ridiculously fast. See the screenshot above. It'll serve your landers to visitors close to the server's physical location in 50ms.
- It's VERY Efficient. Again, see above. That's the smallest VPS that DigitalOcean will allow you to buy, serving just under the equivalent of 3 million visitors a day.
- Uses Lander Templates. Don't code each and every lander from scratch. Templates are easy to create, and once you've created them all landers you develop will automatically be available using all your templates. Want to split-test a coupon style, an app store style, and a minimalist style? It's 2 min work.
- Create Landers From Slack. Yes, that's right. The primary way to create landers in this system is with a one-line command in Slack. WARNING: this removes all excuses for not testing enough landers.
- Tame The Chaos. This CMS uses a database to hold all your landers, so you don't have the chaos of a million folders full of landers.
Note: this is a relatively early release, so There May Be Bugs.
(That's like There Will Be Blood, but with more 404 errors and less of Daniel Day Lewis looking sweaty.)
Let me know below if there are.
Also, the installation is not the simplest thing ever - if you want to use this tool, you'll probably either need some familiarity with Linux or a sysadmin to install it.
The Code
Here it is!
Detailed installation instructions below. In short, you'll need a server running
OpenResty and MySQL.
Create an nginx.conf file as so:
Code:
worker_processes 1;
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
server {
listen 80;
root /var/www;
location /images/ {
}
location /slack-upload/ {
content_by_lua '
ngx.req.read_body()
local args = ngx.req.get_post_args()
ngx.say("Lander will be " .. args["text"])
if args["token"] != "YOUR_TOKEN_HERE" then return end
local mysql = require "resty.mysql"
local db = mysql:new()
local ok, err, errcode, sqlstate = db:connect({host = "127.0.0.1", port = 3306, user="root", database = "cms",password = "password"})
if not ok then
ngx.say("failed to connect: ", err, ": ", errcode, " ", sqlstate)
return
end
local query = "insert into landers values " .. args["text"] .. ";"
local res, err, errcode, sqlstate = db:query(query)
';
}
location ~ ^/(?<lander>[^/]+)/(?<template>[^/]+)/ {
default_type text/html;
content_by_lua '
local template = io.open("templates//" .. ngx.var.template .. "/template.html")
local mysql = require "resty.mysql"
local db = mysql:new()
local ok, err, errcode, sqlstate = db:connect({host = "127.0.0.1", port = 3306, user="root", database = "cms",password = "password"})
if not ok then
ngx.say("failed to connect: ", err, ": ", errcode, " ", sqlstate)
return
end
local query = "select * from landers where id=/"" .. ngx.var.lander .. "/";"
local res, err, errcode, sqlstate = db:query(query)
local templatetext = template:read("*a")
templatetext = string.gsub(templatetext, "||HEADLINE||", res[1]["headline"])
templatetext = string.gsub(templatetext, "||SUBHEAD||", res[1]["subhead"])
templatetext = string.gsub(templatetext, "||CTA||", res[1]["cta"])
templatetext = string.gsub(templatetext, "||IMAGE||", "/images//" .. res[1]["image"])
ngx.say(templatetext)
template:close()
';
}
}
}
Installation
You'll need a VPS or dedicated server for this script. I might do an AWS version in the future but currently it won't work with S3 or other amazon web services aside from EC2.
If you're using a Linode server, you're in luck - our uber-sysadmin Goshev is working on a script to auto-install this for you. Watch this space for updates.
Otherwise, you'll need to do three things:
- Install OpenResty on your web server. Full installation instructions are here. This bit is a bit techie, but it's very doable.
- Create a directory to run your lander system from, and create the directories ./conf, ./logs, ./images and ./templates in there
- Install MySQL or MariaDB.
- Create a file called conf/nginx.conf and paste in the above code. Change the database information appropriately (in BOTH places it's used).
- Create at least one template - see "templates", below.
- Create a database. The database should be called "cms", and should have one table called "landers". That table should have 5 columns: id should be varchar, and headline, subhead, cta, and image should all be text. SQL below!
- Create at least one lander - see Slack Landers, below.
SQL to create your table:
Code:
create table landers (id VARCHAR(20), headline TEXT, subhead TEXT, image TEXT, cta TEXT);
And you're good to go!
Templates
Currently, the CMS's templates accept a
headline, an
image, a
subhead and a
Call To Action. (If you want to hack additional things into the script it's very easy to do.)
To create a template, just create a folder in your "templates" folder. Call it whatever you want - no spaces, though. (Underscores are fine).
Now, grab the code for your lander, and replace the following:
- Where the Headline is, replace the text with ||HEADLINE||
- Where the subhead is, replace the text with ||SUBHEAD||
- Where the image is, replace the URL with ||IMAGE||
- And where the CTA is, replace the text with ||CTA||
Don't change the actual CTA URL - I'm assuming you're using a modern tracker here so your CTA URL will always be the same.
Save that file as "template.html" in the folder you created.
Hooking Up Slack
You'll need to hook the script up to a private Slack channel. Anyone who has access to the channel will be able to create landers, so watch out.
To do that:
- Click the cog at the top right of your channel, choose "Add An App Or Integration", then choose "Build" at the top right, and choose "Something just for my team".
- Choose "Slash Commands".
- Call the command "lander" (or anything else you want).
- Set the URL for the slash command to the IP of your server, followed by /slack-upload/ . So if my IP is 193.141.231.1, I set the slash command to http://193.141.231.1/slack-upload/
- Copy the token and paste it into your nginx config, replacing "YOURTOKENHERE".
- Click "save integration" and you're done!
Adding Images
You'll need to upload any images you want to use. Just upload them into the /images/ folder under your web folder on your server.
Creating A Lander
You can now create a lander by just using the Slack command followed by a specific syntax.
Here's the syntax to use:
Code:
/lander ("name_of_lander", "headline", "subhead", "image_name", "cta")
So here's an example:
Code:
/lander ("iphone5_straightup", "You Could Win A New iPhone!", "Unbelievable? But true!", "iphone.jpg", "Will You Win?")
That would create a lander called iphone5_straightup.
(If you do use this CMS, please create a better lander than that!

)
Accessing Your Landers
You can now access your landers via the following URL:
Your_Domain_Name/lander_name/Template_name/
So, if you've created a template called "coupon" and a lander called "iphone5_straightup", you access it and send visitors to it at
http://www.yourdomain.com/iphone5_straightup/coupon/
If you have two other templates called "minimal" and "appstore", you can change the lander to use them by doing nothing else but sending visitors to
http://www.yourdomain.com/iphone5_straightup/minimal/
and
http://www.yourdomain.com/iphone5_straightup/appstore/
And That's It! Hope you find that script useful - if you have any problems, questions or comments, post 'em below!
10-04-2016 02:11 PM
#2
Mr Payne (Member)
Hey Caurmen, great write up. I will plan to test this soon.
Question: What speed test / benchmark site are you using in the screenshot above?
10-04-2016 02:20 PM
#3
wiifmdude ()

Originally Posted by
mrpayne
Hey Caurmen, great write up. I will plan to test this soon.
Question: What speed test / benchmark site are you using in the screenshot above?
blitz.io
10-04-2016 06:41 PM
#4
caurmen (Administrator)
Yup, it's Blitz.
I don't recommend them for super-thorough load testing (that's what Gatling is for), but it's a good way to get a quick insight into how a server's doing.
Home >
Technical & Creative Skills >
Programming, Servers & Scripts