Restdb.io – Super Simple, Low Code CMS and Database Backend for Web Apps

If you need a quick and easy way to create a CMS (content management system) or a database backend for an app, then Restdb.io will amaze! Here are some features:

  • super developer-friendly with crystal clear documentation
  • affordable and even has a free plan
  • example code for popular programming languages, including client side JavaScript and server side NodeJS, which makes it quick to get up and running
  • webhooks whenever a record is created, updated or deleted
  • codehooks to run custom code before and after a record is created, updated or deleted, e.g. for data normalizing and validation. codehooks also support scheduled tasks like cron jobs.
  • auto-generate test data to seed a table
  • ability to import data from a CSV file
  • native and custom field validation
  • non-technical users can log in and add/edit/delete records using intuitive forms and controls without seeing any developer features
  • ability to upload and host images and files

Below is a tutorial on how to create a simple CRUD (Create, Read, Update, Delete) app using Restdb.io with a PHP backend.

1. Log in to Restdb.io account and create a table (collection)

After you log in, you’ll need to be in Developer Mode to create a table. When creating fields in the table, Restdb.io offers numerous field property options including native and custom field validation.

2. Add or import data

To populate the table, you can

  • Add data field by field, row by row
  • Import data from a CSV file
  • Auto-generate data by clicking on the Test Data tab

Using the Test Data option, I chose to generate 5 rows which gave me this.

3. Get sample CRUD code

Click on [Table] > API Docs and choose a language to see sample code for

  • getting records (using HTTP GET method)
  • creating a record (using HTTP POST method)
  • update a record (using HTTP PUT method)
  • delete a record using (HTTP DELETE method)

PHP

The sample PHP CRUD code provided by RestDB.io requires the use of the HttpRequest PEAR PECEL HTTP_Request extension. To avoid having to install this dependency, you can just use cURL which is included with PHP.

NodeJS

Below is a screenshot using NodeJS using the Request library.

JavaScript using jQuery AJAX

You can also perform CRUD actions using client-side JavaScript but you need to set up CORS (cross-origin resource sharing). The example below shows JavaScript using jQuery AJAX.

For client-side JavaScript, you need to generate a CORS API key. The screenshot below shows a CORS API key (redacted) that allows connections from any origin server but only allows the GET method to read data.

In the screenshot above, the API key would only work for the “people” table / collection. To have one key work for all tables / collections, use “/**” instead.

4. PHP: Create a file to test reading from the database

I created a test file called read-curl.php which uses cURL to connect to the remote database.

After uploading it to my web host, opening the file in a browser shows me the data in JSON format, as expected, which you can see live at http://zabuun.com/restdb.io/read-curl.php

You can also test the API by installing Postman (free), entering a query in the form of a REST URL, and entering your API key as an HTTP header.

4. JavaScript (jQuery + AJAX): Create a file to test reading from the database

I created a test file called read.html with the following code. This code uses the CORS key for cross-origin resource sharing.

After uploading it to my web host, opening the file in a browser shows me the data in JSON format, as expected, which you can see live at http://zabuun.com/restdb.io/read.html

If you have JSON data as in the example above, you can use Handlebars.JS to format the output in HTML.

5. Query data

When reading data from RestDB , you will often want to filter data based on conditions rather than retrieve an entire collection (all records). RestDB supports many MongoDB-like query syntax. Read the docs. Here’s an example of RestDB queries for equivalent relational DB SQL queries.

SQLRestDB
SELECT * FROM usershttps://<db-name>.restdb.io/rest/users?q={}
SELECT id, user_id, status FROM users/rest/users?q={}&h={"$fields": {"user_id": 1, "status": 1} }
SELECT * FROM users WHERE status = “A”/rest/users?q={ "status": "A" }
SELECT * FROM users WHERE status != “A”/rest/users?q={"status":{"$not":"A"}}
SELECT * FROM users WHERE status = “A” AND age = 50/rest/users?q={ "status": "A", "age": 50 }
SELECT * FROM users WHERE status = “A” OR age = 50/rest/users?q={ "$or": [ { "status": "A" } ,{ "age": 50 } ] }
SELECT * FROM users WHERE age > 25/rest/users?q={ "age": { "$gt": 25 } }
SELECT * FROM users WHERE age < 25/rest/users?q={ "age": { "$lt": 25 } }
SELECT * FROM users WHERE age > 25 AND age <= 50/rest/users?q={ "age": { "$gt": 25, "$lte": 50 } }
SELECT * FROM users WHERE user_id like “%bc%”/rest/users?q={ "user_id": {"$regex" :"bc"}}
SELECT * FROM users WHERE user_id like “bc%”/rest/users?q={ "user_id": {"$regex" :"^bc"}}
SELECT * FROM users WHERE status = “A” ORDER BY user_id ASC/rest/users?q={ "status": "A" }&sort=user_id&dir=1
SELECT * FROM users WHERE status = “A” ORDER BY user_id DESC/rest/users?q={ "status": "A" }&sort=user_id&dir=-1
SELECT COUNT(*) FROM users/rest/users?q={}&h={"$aggregate":["COUNT:"]}
SELECT COUNT(*) FROM users WHERE age > 30/rest/users?q={"age":{"$gt": 30}}&h={"$aggregate":["COUNT:"]}
SELECT * FROM users LIMIT 1/rest/users?q={}&max=1
SELECT * FROM users LIMIT 5 SKIP 10/rest/users?q={}&max=5&skip=10

You can also aggregate data, e.g. min, max, avg, count, groupby, etc, using aggregation and grouping functions. Read the docs.

If you already have an entire JSON dataset and you want to query against it, you can use JSONata. JSONata is a lightweight query and transformation language for JSON data. 

6. Auto-generate a web form

If you want to create a web form for public use, you can have restdb.io auto-generate one for you, complete with JavaScript validation and code to publish the data to your restdb.io database. See an example at

http://zabuun.com/restdb.io/form.html

7. Filesystem

Below is a screenshot of my remote filesystem on a shared GoDaddy server. The error.log file is auto-generated.

8. Create users with editor access

If you work with other developers or editors, you can give them role-based access to your restdb.io account to manage data. An editor, for example, will not see the developer features and can simply add records using a user-friendly web form like shown below.

Easily Highlight Text in a Screenshot Using Photoshop

Let’s say you’ve taken a screenshot of some text and you’d like to highlight part of the text. By using different blending modes, this becomes an easy task. Here’s how to do it.

1. Open the screenshot containing text in Photoshop and select the text you want to highlight

2. Create a new layer and fill it with yellow

3. Change the blending mode to darken or any other one you like to create the highlighted text.

Here, I’ve chose the Darken blend mode.

This is the result.

Sync Audio with Video in Corel VideoStudio Pro

Let’s say you want to make a music video of you lip syncing to a song. You have two files:

  • Video file of you lip syncing
  • Audio file of song

When you add these two files to VideoStudio Pro, you’ll need to adjust the start time of one so that the lip movement in the video file is in sync with the audio. One way to do this is as follows:

1. Add the audio file to the music track

2. Set a cue marker at first vocal point

Play the music track until you hear the first point in time when you hear the vocals. At that point set a marker by clicking on the bar underneath the timeline. A green triangle marker will appear. If you make a mistake in placing the marker, you can drag it to another position.

If you are having a hard time finding the first vocal point, set a preview range around the time of the first vocal point. Then, keep playing the preview range and update the marker position. To set a preview range,

  • Click on the timeline where the preview range would start. Then click the left bracket button [
  • Click on the timeline where the preview range would end. Then click the right bracket button ]

In the player control panel, you’ll see two yellow markers indicating the preview range relative to the entire project length.

In the timeline, you’ll see an orange bar indicating the preview ranger.

To play the preview range, make sure that “Project —” is selected / highlighted and not “Clip —”. Then click the play button. You can also click the loop button so the preview range plays repeatedly.

If the preview range appears very short, you can zoom in by clicking the + magnifying glass button.

Doing so allows you to see finer time increments in the timeline.

3. Add video to the Overlay 1 track

Don’t add the video to the Video track because doing so forces the video to begin from time 0 instead of a later time. Mute the audio in the Overlay 1 track by click the Mute icon.

4. Position the video to sync it with the audio

Drag the video track to the left and right and repeatedly play the preview range until the lip movement in the video is in sync with the vocal sound from the audio track.

Fix Images Using Adobe Lightroom Clone and Healing Brushes

If you’ve got a blemish or an unsightly object in an image, you can hide it by using either the cloning brush or the healing brush.

Cloning

Cloning is similar to copying some pixels elsewhere in an image and pasting it. This works in some situations but in others, it becomes obvious that you just copied and pasted.

Healing

The healing brush is similar to cloning except it tries to be smart so that the results look natural.

Here’s an example of a blemish in the sky.

And here’s the blemish gone with natural results using the healing brush.

With the healing brush, you tell Lightroom where the blemish is and then choose another area of the image to copy to fix the blemish.

Unsightly objects in the following images were removed using the healing brush.

Before
After
Before
After

Find Used CSS to Remove Unused CSS

When building websites, it’s inevitable that you’ll end up with a bunch of unused CSS as you make changes to the site. To remove unused CSS, you can use Sublime Text’s Get CSS Classes function to first find used CSS. Then, remove all CSS definitions that aren’t in that list.

  1. Open the HTML source in Sublime Text
  2. Click Edit > Tag > Get CSS Classes (this copies the used CSS classes to the clipboard)
  3. Paste the used CSS classes in a new file and sort alphabetically
  4. Go through each CSS definition and remove the ones not in the list of used CSS classes

How to Send a Responsive HTML Email from Outlook on the web and Gmail

  1. Open the email in a browser and copy it’s source code
  2. Inline the CSS using a tool such as https://www.campaignmonitor.com/resources/tools/css-inliner/
  3. In Outlook on the web or Gmail, create a new email message
  4. In the body of the email, type some text that can easily be found, e.g. a bunch of hash symbols.
  1. Inspect the text you just typed and in your inspector, edit it by replacing the text you typed with the CSS-inlined email source code.
  1. Your email body will now show the HTML email. Click send.

WordPress Website Tips

Posting content on WordPress can be time consuming without the right technique. By default, copying and pasting images isn’t possible. Images need to manually be uploaded, resized, and optimized for performance. And even if you do that, they’re still not optimized for global performance because they aren’t on a CDN (content delivery network). To simplify posting content on WordPress, I’ve found the following setup and workflow to be best.

Managed WordPress Hosting

You can be cheap and try to manage hosting a WordPress site yourself. But, you’ll likely get frustrated as you can’t keep up with vulnerabilities that can slow down or break your site. You can get affordable managed WordPress hosting on GoDaddy. They’ll take care of upgrades and remove insecure plugins for you.

Install the Free JetPack Plugin

This plugin is critical, especially for performance. Among other things, you can enable performance optimization to automatically resize, optimize and host all images and static files (CSS, JS) on WordPress’ content delivery network. A 3.5 MB image instantly gets optimized to a fraction of that size, e.g. 120 KB. This plugin is an absolute must.”

Continue reading WordPress Website Tips

Default Apache on Heroku Redirects From https to http for Links Without Trailing Slash

I recently set up a Heroku app using the Apache and PHP buildpack. The Apache configuration on Heroku was most likely the default which, if it receives a request to a URL without a trailing slash, e.g.

http://www.foobar.com/about

it’ll redirect to

http://www.foobar.com/about

That alone is fine. However, I was getting redirected from https to http, which was not fine. This is likely due to the presence of a load balancer in front of the Heroku app server with SSL/TLS being terminated at the load balancer. When a request to an https URL without a trailing slash like

https://www.foobar.com/about

the request was secure to the Heroku load balancer but from the load balancer to the Heroku app server, it must have been insecure, e.g.

http://www.foobar.com/about

At that point, Apache would redirect to

http://www.foobar.com/about

and the user would end up going from https to http. To resolve this, and as a best practice, just force https on all URLs. This is easily done on Heroku using a .htaccess file with a redirect rule, in case your chosen server is Apache.

JavaScript Promises

Using Promises

Say we have an API client with three methods, getItem(), updateItem(), and deleteItem(), each of which returns a Promise. There are only two functions you need to worry about: then() and catch().

Each call to then() creates another step in the Promise chain, and if there’s an error at any point in the chain, the next catch() block will be triggered. Both then() and catch() can either return a raw value or a new Promise, and the result will be passed to the next then() in the chain.

Convert callback to Promises

If a function doesn’t return a Promise but rather a callback, like Node’s fs.readile function,

https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback

then you can convert the call to a Promise as follows. The new function, called readFilePromise, converts the original function, called readFile, into a Promise.

To use the new promise function, do this.

To create Promises out of ordinary values, use Promise.resolve() and Promise.reject().

If you have a function that needs to return a Promise, like fs.readFile, but handle certain cases synchronously, you can use Promise.resolve() and Promise.reject() to create Promises out of ordinary values, like this.

Running concurrently

Promise.all is a convenient method for running an array of Promises concurrently, i.e. all at the same time. For instance, say we have a list of files we want to read from disk. Using the readFilePromise function we created above, it would look like this:

Here’s another example

And another example (from Kyle Simpson)

In the example above, we can use the new Promisified function in the chain as follows. We can also create a new Promise that returns a Promise of an ordinary value to keep the chain going.