How to Create a Mall Map with Real-time Data Using WRLD

As a web developer, you sometimes find yourself in a position where you are required to implement a map. Your first choice is to use Google Maps, right?

This looks okay. However, you may be required to overlay additional information over the map with the help of markers. You can use this method, or you can find a better solution that allows you to create markers inside an indoor 3D map! How cool is that? With indoor markers, you can provide unique experiences for users where they will be able to access information and interact with UIs right inside the map.

In this tutorial, we’ll create two demos illustrating the power of WRLD maps. You’ll learn how to create custom apps that can overlay real-time information over a 3D map. In the first demo, we’ll add interactive markers to an existing indoor map of a mall. In the second demo, we’ll place colored polygons over parking areas, indicating capacity.
You can find the completed project for both demos in this GitHub repository.
Prerequisites
For this article, you only need to have a fundamental understanding of the following topics:

JavaScript DOM
ES6 Syntax
ES6 Modules

I’ll assume this is your first time using WRLD maps. However, I do recommend you at least have a quick read of the article:

Building Dynamic 3D Maps

You’ll also need a recent version of Node.js and npm installed on your system (at the time of writing, 8.10 LTS is the latest stable version). For Windows users, I highly recommend you use Git Bash or any other terminal capable of handling basic Linux commands.
This tutorial will use yarn for package installation. If you prefer to use npm, please refer to this guide if you are unfamiliar with yarn commands.
Acquire an API Key
Before you get started, you’ll need to create a free account on WRLD. Once you’ve logged in and verified your email address, you’ll need to acquire an API key. For detailed instructions on how to acquire one, please check out the Getting Started section on Building Dynamic 3D Maps where it’s well documented.
Approach to Building the Map
The creation of WRLD maps is a major technological achievement with great potential benefits for many industries. There are two main ways of expanding the platform’s capabilities:

Using built-in tools, e.g. Map Designer and Places Designer
Building a custom app

Let me break down how each method can be used to achieve the desired results.
1. Using Map Designer and Places Designer
For our first demo, we can use Places Designer to create Store Cards. This will require us to create a Collection Set where all Point of Interest markers will be held. This set can be accessed both within the WRLD ecosystem, and externally via the API key. We can pass this data to a custom map created using the Map Designer. With this tool, we can share the map with others using its generated link. If you would like to learn more about the process, please watch the video tutorials on this YouTube playlist.

The beauty of this method is that no coding is required. However, in our case, it does have limitations:

Restrictive UI design – we can only use the UI that comes with Places Designer
Restrictive data set – we can’t display additional information beyond what is provided

In order to overcome these limitations, we need to approach our mall map challenge using the second method.
2. Building a Custom App
Building custom apps is the most flexible option. Although it takes some coding effort, it does allow us to comprehensively tap into the wealth of potential provided by the WRLD platform. By building a custom app, we can create our own UI, add more fields and access external databases in real-time. This is the method that we’ll use for this tutorial.
Building the App
Let’s first create a basic map, to which we’ll add more functionality later. Head over to your workspace directory and create a new folder for your project. Let’s call it mall-map.
Open the mall-map folder in your code editor. If you have VSCode, access the terminal using Ctrl + ` and execute the following commands inside the project directory:
# Initialize package.json
npm init -f

# Create project directories
mkdir src
mkdir src/js src/css

# Create project files
touch src/index.html
touch src/js/app.js
touch src/css/app.css
touch env.js

This is how your project structure should look:

Now that we have our project structure in place, we can begin writing code. We’ll start with index.html. Insert this code:

<html lang=”en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./css/app.css" />
<title>Shopping Mall</title>
</head>
<body>
<div id="map"></div>
<script src="js/app.js"></script>
</body>
</html>

Next, let’s work on css/app.css. I’m providing the complete styling for the entire project so that we don’t have to revisit this file again. In due time you’ll understand the contents as you progress with the tutorial.
@import "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.1/leaflet.css";
@import "https://cdn-webgl.wrld3d.com/wrldjs/addons/resources/latest/css/wrld.css";
@import "https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.0/semantic.min.css";

html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}

#map {
width: 100%;
height: 100%;
background-color: #000000;
}

/* ——– POPUP CONTENT ——– */
.main-wrapper > .segment {
padding: 0px;
width: 300px;
}

.contacts > span {
display: block;
padding-top: 5px;
}

Now we need to start writing code for app.js. However, we need a couple of node dependencies:
yarn add wrld.js axios

As mentioned earlier, we’ll be taking advantage of modern JavaScript syntax to write our code. Hence, we need to use babel to compile our modern code to a format compatible with most browsers. This requires installing babel dependencies and configuring them via a .babelrc file. Make sure to install them as dev-dependencies.
yarn add babel-core babel-plugin-transform-runtime babel-runtime –dev
touch .babelrc

Copy this code to the .babelrc file:
{
"plugins": [
[
"transform-runtime",
{
"polyfill": false,
"regenerator": true
}
]
]
}

We’ll also need the following packages to run our project:

Parcel bundler – it’s like a simplified version of webpack with almost zero configuration
JSON Server – for creating a dummy API server

Install the packages globally like this:
yarn global add parcel-bundler json-server

# Alternative command for npm users
npm install -g parcel-bundler json-server

That’s all the node dependencies we need for our project. Let’s now write some JavaScript code. First, supply your WRLD API key in env.js:
module.exports = {
WRLD_KEY: ‘<put api key here>’,
};

Then open js/app.js and copy this code:
const Wrld = require(‘wrld.js’);
const env = require(‘../../env’);

const keys = {
wrld: env.WRLD_KEY,
};

window.addEventListener(‘load’, async () => {
const map = await Wrld.map(‘map’, keys.wrld, {
center: [56.459733, -2.973371],
zoom: 17,
indoorsEnabled: true,
});
});

The first three statements are pretty obvious. We’ve put all our code inside the window.addEventListener function. This is to ensure our code is executed after the JavaScript dependencies, that we’ll specify later in index.html, have loaded. Inside this function, we’ve initialized the map by passing several parameters:

map – the ID of the div container we specified in index.html
keys.wrld – API key
center – latitude and longitude of the Overgate Mall located in Dundee, Scotland
zoom – elevation
indoorsEnabled – allow users to access indoor maps

Let’s fire up our project. Go to your terminal and execute:
parcel src/index.html

Wait for a few seconds for the project to finish bundling. When it’s done, open your browser and access localhost:1234. Depending on your Internet speed, the map shouldn’t take too long to load.

Beautiful, isn’t it? Feel free to click the blue icon. It will take you indoors. Navigate around to see the different stores. However, you’ll soon realize that you can’t access other floors. There’s also no button for exiting the indoor map. Let’s fix that in the next chapter.
Create Indoor Controls
To allow users to switch between different floors, we’ll provide them with a control widget that will allow them to do this. Simply add the following scripts to the head section of the public/index.html file:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdn-webgl.wrld3d.com/wrldjs/addons/indoor_control/latest/indoor_control.js"></script>

Still within the html file, add this div in the body section, right before the #map div:
<div id="widget-container" class="wrld-widget-container"></div>

Now let’s update js/app.js to initialize the widget. Place this code right after the map initialization section:
const indoorControl = new WrldIndoorControl(‘widget-container’, map);

Now refresh the page, and click the ‘Enter Indoors’ icon. You should have a control widget that will allow you to switch between floors. Just drag the control up and down to fluidly move between floors.

Amazing, isn’t it? Now let’s see how we can make our map a little bit more convenient for our users.
Enter Indoors Automatically
Don’t you find it a bit annoying that every time we need to test our map, we need to click the ‘Indoors’ icon? Users may start navigating to other locations which is not the intention of this app. To fix this, we need to navigate indoors automatically when the app starts without any user interaction. First, we require the indoor map id to implement this feature. We can find this information from the indoormapenter event. You can find all Indoor related methods here.
Add the following code in the js/app.js file.

// Place this code right after the Wrld.map() statement
map.indoors.on(‘indoormapenter’, async (event) => {
console.log(event.indoorMap.getIndoorMapId());
});

Refresh the page then check out your console. You should get this ID printed out: EIM-e16a94b1-f64f-41ed-a3c6-8397d9cfe607. Let’s now write the code that will perform the actual navigation:
const indoorMapId = ‘EIM-e16a94b1-f64f-41ed-a3c6-8397d9cfe607’;

map.on(‘initialstreamingcomplete’, () => {
map.indoors.enter(indoorMapId);
});

After saving the file, refresh the page and see what happens.
The indoor mall map should navigate automatically. Next, we’ll look at how we can create cards for each store. But first, we need to determine where to source our data.
Mall Map Planning
To create store cards for our map, we need several items:

Exact Longitude/Latitude coordinates of a store
Store contact information and opening hours
Design template for the store card

Store Card Coordinates
To acquire Longitude/Latitude coordinates, we need to access maps.wrld3d.com. Wait for the map to finish loading then enter the address 56.459733, -2.973371 in the search box. Press enter and the map will quickly navigate to Overgate Mall. Click the blue indoor icon for Overgate Mall and you should be taken to the mall’s indoor map. Once it’s loaded, locate the ‘Next’ store and right-click to open the context menu. Click the ‘What is this place? option. The coordinate popup should appear.

Click the ‘Copy Coordinate’ button. This will give you the exact longitude/latitude coordinates of the store. Save this location address somewhere temporarily.
Store Card Information
You’ll also need to gather contact information from each store which includes:

image
description
phone
email
web
Twitter
opening times

You can source most of this information from Google. Luckily, I’ve already collected the data for you. For this tutorial, we’ll only deal with four stores on the ground floor. To access the information, just create a folder at the root of the project and call it data. Next save this file from GitHub in the data folder. Make sure to save it as db.json. Here is a sample of the data we’ll be using:
{
"id":1,
"title": "JD Sports",
"lat": 56.4593425,
"long": -2.9741433,
"floor_id": 0,
"image_url": "https://cdn-03.belfasttelegraph.co.uk/business/news/…image.jpg",
"description":"Retail chain specialising in training shoes, sportswear & accessories.",
"phone": "+44 138 221 4545",
"email": "customercare@jdsports.co.uk",
"web": "https://www.jdsports.co.uk/",
"twitter": "@jdhelpteam",
"tags": "sports shopping",
"open_time":[
{ "day": "Mon",
"time": "9:30am – 6:00pm"
},]
}

The data is stored in an array labeled ‘pois’. POI stands for Places of Interest. Now that we have the data available, we can easily make it accessible via an API REST point by running the JSON server. Just open a new terminal and execute the command:
json-server –watch data/db.json

It should take a few seconds for the API to start. Once it’s fully loaded, you can test it with your browser at localhost:3000/pois. You can also fetch a single POI using this syntax:
– localhost:3000/pois/{id}
For example, localhost:3000/pois/3 should return a poi record with ID 3 in JSON format.
Store Card Design
We’ll use a clean elegant theme to neatly display contact information and opening times using a couple of tabs. We’ll create markers that will display a popup when clicked. This popup will have the following UI.

The code for this HTML design is a bit long to put here. You can view and download the file from this link. The design only has three dependencies:

Semantic UI CSS
jQuery
Semantic UI JS

Now that we have the data required and the design, we should be ready to start working on our indoor map.
Implementing Store Cards in Indoor Map
First let’s create a service that will allow us to access data from the JSON REST APIs. This data will be used for populating the Store Cards with the necessary information. Create the file js/api-service.js and copy this code:
const axios = require(‘axios’);

const client = axios.create({
baseURL: ‘http://127.0.0.1:3000’,
timeout: 1000,
});

module.exports = {
getPOIs: async () => {
try {
const response = await client.get(‘/pois’);
return response.data;
} catch (error) {
console.error(error);
}
return [];
},
getPOI: async (id) => {
try {
const response = await client.get(`/pois/${id}`);
return response.data;
} catch (error) {
console.error(error);
}
return {};
},
}

Here we are making use of the library axios to request data from the JSON server.
Next, we’ll convert our static HTML design for the Store Card to a format that will allow us to render data. We’ll be using JsRender for this. We’ll break down our static design into three templates:

Base Template – has containers for menu, info and time tabs.
Info Template – tab for store contact information.
Time Template – tab for store opening hours.

First, open index.html and add these scripts to the head section, right after the jQuery and indoor control scripts:
<head>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jsrender/0.9.90/jsrender.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.0/semantic.min.js"></script>

</head>

Next, copy this section of code right before the widget-container div:

<!– Menu Tabs UI –>
<script id="baseTemplate" type="text/x-jsrender">
<div class="main-wrapper">
<div class="ui compact basic segment">
<div class="ui menu tabular"> </div>
<div id="infoTab" class="ui tab active" data-tab="Info"></div>
<div id="timeTab" class="ui tab" data-tab="Time"></div>
</div>
</div>
</script>

<!– Info Data Tab –>
<script id="infoTemplate" type="text/x-jsrender">
<div class="ui card">
<div class="image">
<img src=>
</div>
<div class="content">
<div class="header"></div>
<div class="description">

</div>
</div>
<div class="extra content contacts">
<span>
<i class="globe icon"></i>
<a href="" target="_blank"></a>
</span>
<span>
<i class="mail icon"></i>

</span>
<span>
<i class="phone icon"></i>

</span>
</div>
</div>
</script>

<!– Opening Times Data Tab –>
<script id="timeTemplate" type="text/x-jsrender">
<table class="ui celled table">
<thead>
<tr>
<th>Day</th>
<th>Time</th>
</tr>
</thead>
<tbody>

<tr>
<td></td>
<td></td>
</tr>

</tbody>
</table>
</script>

This is how the full code for index.html should look.
Next, let’s create another service that will manage the creation of Popups. Create the file js/popup-service.js and copy this code:
const Wrld = require(‘wrld.js’);
const { getPOI } = require(‘./api-service’);

const baseTemplate = $.templates(‘#baseTemplate’);
const infoTemplate = $.templates(‘#infoTemplate’);
const timeTemplate = $.templates(‘#timeTemplate’);

const popupOptions = {
indoorMapId: ‘EIM-e16a94b1-f64f-41ed-a3c6-8397d9cfe607’,
indoorMapFloorIndex: 0,
autoClose: true,
closeOnClick: true,
elevation: 5,
};

Let me explain each block step by step:

Block 1: WRLD is required for creating the Popup, getPOI function is required for fetching data
Block 2: The templates that we discussed earlier are loaded using jsrender
Block 3: Parameters that will be passed during Popup instantiation. Here is the reference documentation.

Next, let’s add tab menus that will be used for switching tabs. Simply add this code to js/popup-service.js:
const createMenuLink = (linkName, iconClass) => {
const link = document.createElement(‘a’);
link.className = ‘item’;
const icon = document.createElement(‘i’);
icon.className = `${iconClass} icon`;
link.appendChild(icon);
link.appendChild(document.createTextNode(` ${linkName}`));
link.setAttribute(‘data-tab’, linkName);
link.addEventListener(‘click’, () => {
$.tab(‘change tab’, linkName);
$(‘.item’).toggleClass(‘active’);
});
return link;
};

const createMenu = (menuParent) => {
const infoLink = createMenuLink(‘Info’, ‘info circle’);
infoLink.className += ‘ active’;
menuParent.appendChild(infoLink);
const timeLink = createMenuLink(‘Time’, ‘clock’);
menuParent.appendChild(timeLink);
};

You might be wondering why we are using a complicated method of creating menu links. Ideally, we should be able to create them using HTML, then add a small JavaScript script to activate the tabs. Unfortunately, this doesn’t work within the context of a Popup. Instead, we need to create clickable elements using DOM manipulation methods.
The post How to Create a Mall Map with Real-time Data Using WRLD appeared first on SitePoint.

Link: https://www.sitepoint.com/how-to-create-a-mall-map-with-real-time-data-using-wrld/

The Four Big Ways Jetpack Helps with Image Performance

We’ve been working with Jetpack around here as a sponsor. It’s a great match because as someone with a bunch of self-hosted WordPress sites, Jetpack is one of those no-brainer plugins for me. Jetpack can do a ton of good things for any site in a variety of very different ways. Here’s one way to think about it: it brings the power of WordPress’ own massive servers to you.
For now, let’s just focus on one angle of what …
The post The Four Big Ways Jetpack Helps with Image Performance appeared first on CSS-Tricks.

Link: https://css-tricks.com/the-four-big-ways-jetpack-helps-with-image-performance/

JSON Schema Validation & Expressive Query Syntax in MongoDB 3.6

This article was originally published on MongoDB. Thank you for supporting the partners who make SitePoint possible.
One of MongoDB’s key strengths has always been developer empowerment: by relying on a flexible schema architecture, MongoDB makes it easier and faster for applications to move through the development stages from proof-of-concept to production and iterate over update cycles as requirements evolve.
However, as applications mature and scale, they tend to reach a stable stage where frequent schema changes are no longer critical or must be rolled out in a more controlled fashion, to prevent undesirable data from being inserted into the database. These controls are especially important when multiple applications write into the same database, or when analytics processes rely on predefined data structures to be accurate and useful.
MongoDB 3.2 was the first release to introduce Document Validation, one of the features that developers and DBAs who are accustomed to relational databases kept demanding. As MongoDB’s CTO, Eliot Horowitz, highlighted in Document Validation and What Dynamic Schemas Means:

Along with the rest of the 3.2 “schema when you need it" features, document validation gives MongoDB a new, powerful way to keep data clean. These are definitely not the final set of tools we will provide, but is rather an important step in how MongoDB handles schema.

Announcing JSON Schema Validation Support
Building upon MongoDB 3.2’s Document Validation functionality, MongoDB 3.6 introduces a more powerful way of enforcing schemas in the database, with its support of JSON Schema Validation, a specification which is part of IETF’s emerging JSON Schema standard.
JSON Schema Validation extends Document Validation in many different ways, including the ability to enforce schemas inside arrays and prevent unapproved attributes from being added. These are the new features we will focus on in this blog post, as well as the ability to build business validation rules.
Starting with MongoDB 3.6, JSON Schema is the recommended way of enforcing Schema Validation. The next section highlights the features and benefits of using JSON Schema Validation.
Switching from Document Validation to JSON Schema Validation
We will start by creating an orders collection (based on an example we published in the Document Validation tutorial blog post):
db.createCollection("orders", {
validator: {
item: { $type: "string" },
price: { $type: "decimal" }
}
});

With this document validation configuration, we not only make sure that both the item and price attributes are present in any order document, but also that item is a string and price a decimal (which is the recommended type for all currency and percentage values). Therefore, the following element cannot be inserted (because of the "rogue" price attribute):
db.orders.insert({
"_id": 6666,
"item": "jkl",
"price": "rogue",
"quantity": 1 });

However, the following document could be inserted (notice the misspelled "pryce" attribute):
db.orders.insert({
"_id": 6667,
"item": "jkl",
"price": NumberDecimal("15.5"),
"pryce": "rogue" });

Prior to MongoDB 3.6, you could not prevent the addition of misspelled or unauthorized attributes. Let’s see how JSON Schema Validation can prevent this behavior. To do so, we will use a new operator, $jsonSchema:
db.runCommand({
collMod: "orders",
validator: {
$jsonSchema: {
bsonType: "object",
required: ["item", "price"],
properties: {

item: {
bsonType: "string"
},
price: {
bsonType: "decimal"
}
}
}
}
});

The JSON Schema above is the exact equivalent of the document validation rule we previously set above on the orders collection. Let’s check that our schema has indeed been updated to use the new $jsonSchema operator by using the db.getCollectionInfos() method in the Mongo shell:
db.getCollectionInfos({name:"orders"})

This command prints out a wealth of information about the orders collection. For the sake of readability, below is the section that includes the JSON Schema:

"options" : {
"validator" : {
"$jsonSchema" : {
"bsonType" : "object",
"required" : [
"item",
"price"
],
"properties" : {
"item" : {
"bsonType" : "string"
},
"price" : {
"bsonType" : "decimal"
}
}
}
},
"validationLevel" : "strict",
"validationAction" : "error"
}

Now, let’s enrich our JSON schema a bit to make better use of its powerful features:
db.runCommand({
collMod: "orders",
validator: {
$jsonSchema: {
bsonType: "object",
additionalProperties: false</strong>,
required: ["item", "price"],
properties: {
<strong>_id: {}</strong>,
item: {
bsonType: "string",
description: "’item’ must be a string and is required"
},
price: {
bsonType: "decimal",
description: "’price’ must be a decimal and is required"
},
quantity: {
<strong>bsonType: ["int", "long"]</strong>,
minimum: 1,
maximum: 100,
exclusiveMaximum: true,
description:
"’quantity’ must be short or long integer between 1 and 99"
}
}
}
}
});

Let’s go through the additions we made to our schema:

First, note the use of the additionalProperties:false attribute: it prevents us from adding any attribute other than those mentioned in the properties section. For example, it will no longer be possible to insert data containing a misspelled pryce attribute. As a result, the use of additionalProperties:false at the root level of the document also makes the declaration of the _id property mandatory: whether our insert code explicitly sets it or not, it is a field MongoDB requires and would automatically create, if not present. Thus, we must include it explicitly in the properties section of our schema.
Second, we have chosen to declare the quantity attribute as either a short or long integer between 1 and 99 (using the minimum, maximum and exclusiveMaximum attributes). Of course, because our schema only allows integers lower than 100, we could simply have set the bsonType property to int. But adding long as a valid type makes application code more flexible, especially if there might be plans to lift the maximum restriction.
Finally, note that the description attribute (present in the item, price, and quantity attribute declarations) is entirely optional and has no effect on the schema aside from documenting the schema for the reader.

With the schema above, the following documents can be inserted into our orders collection:
db.orders.insert({
"item": "jkl",
"price": NumberDecimal(15.50),
"quantity": NumberInt(99)
});

db.orders.insert({
"item": "jklm",
"price": NumberDecimal(15.50),
"quantity": NumberLong(99)
});

However, the following documents are no longer considered valid:
db.orders.insert({
"item": "jkl",
"price": NumberDecimal(15.50),
<strong>"quantity": NumberInt(100)</strong>
});
db.orders.insert({
"item": "jkl",
"price": NumberDecimal(15.50),
<strong>"quantity": "98"</strong>
});
db.orders.insert({
"item": "jkl",
<strong>"pryce": NumberDecimal(15.50),</strong>
"quantity": NumberInt(99)
});

You probably noticed that our orders above are seemingly odd: they only contain one single item. More realistically, an order consists of multiple items and a possible JSON structure might be as follows:
{
_id: 10000,
total: NumberDecimal(141),
VAT: 0.20,
totalWithVAT: NumberDecimal(169),
lineitems: [
{
sku: "MDBTS001",
name: "MongoDB Stitch T-shirt",
quantity: NumberInt(10),
unit_price:NumberDecimal(9)
},
{
sku: "MDBTS002",
quantity: NumberInt(5),
unit_price: NumberDecimal(10)
}
]
}

With MongoDB 3.6, we can now control the structure of the lineitems array, for instance with the following JSON Schema:
The post JSON Schema Validation & Expressive Query Syntax in MongoDB 3.6 appeared first on SitePoint.

Link: https://www.sitepoint.com/json-schema-validation-expressive-query-syntax-in-mongodb-3-6/

​Truly understand your site visitors’ behavior

(This is a sponsored post.)
Hotjar is a quick and easy way to truly understand your visitors and identify opportunities for improvement and growth.
Try the all-in-one analytics and feedback tool for free.
Direct Link to Article — Permalink…
The post ​Truly understand your site visitors’ behavior appeared first on CSS-Tricks.

Link: https://synd.co/2t7z6uF

​​Build live comments with sentiment analysis using Nest.js

(This is a sponsored post.)
Interestingly, one of the most important areas of a blog post is the comment section. This plays an important role in the success of a post or an article, as it allows proper interaction and participation from readers. This makes it inevitable for every platform with a direct comments system to handle it in realtime.
In this post, we’ll build an application with a live comment feature. This will happen in realtime as …
The post ​​Build live comments with sentiment analysis using Nest.js appeared first on CSS-Tricks.

Link: https://synd.co/2xFDDtI

​Headless CMS: Fresh Air for Developers

(This is a sponsored post.)
Your current CMS sucks! You know that for some time already but have not decided yet what your next solution should be.
You’ve noticed all the buzz around headless CMS but you’re still not sure what is in it for you and how it can solve all your woes.
What is the difference between traditional on-premise CMS with REST API and true API-first cloud based CMS? How does headless CMS fit to your scenarios? …
The post ​Headless CMS: Fresh Air for Developers appeared first on CSS-Tricks.

Link: http://bit.ly/2J3hc2X

What’s Next for Hybrid App Developers? (Sponsored)

The story of hybrid application development is a never-ending one. Each framework has to continuously strive and innovate to remain relevant, and the discussion of which framework to use is a question often asked. Most hybrid applications are built using a combination of HTML, CSS, and JavaScript. These applications can range from WebView-based solutions (such […]
The post What’s Next for Hybrid App Developers? (Sponsored) appeared first on David Walsh Blog.

Link: https://davidwalsh.name/whats-hybrid-app-developers

​Customize payment solutions with our enhanced platform

(This is a sponsored post.)
We’ve upped our game by using developers’ feedback to improve the Authorize.Net payment platform. Check out our new, streamlined API, better sample code and SDKs, and use them to provide your merchants with a secure, scalable payment solution. You’ll see that it’s a seamless and efficient way to make sure you and your merchants get paid!
Start playing
Direct Link to Article — Permalink…
The post ​Customize payment solutions with our enhanced platform appeared first on CSS-Tricks.

Link: https://synd.co/2KOQvzB

OpenRates Currency API (Sponsored)

Creating your own APIs can be a total nightmare: worrying about uptime, load balancing, data accuracy, caching, and all of the other risks would keep me up at night.  And if your API relates to money in any way?  If you get that wrong you could be costing yourself, your employer, or your client a […]
The post OpenRates Currency API (Sponsored) appeared first on David Walsh Blog.

Link: https://davidwalsh.name/openrates

​Build a realtime polling web app with Next.js

(This is a sponsored post.)
Learn to build a webapp that accepts user votes, using Next.js and Chart.js. Users can vote for their favorite pet, and the results are displayed in realtime on a graph in their browser using Pusher Channels.
Direct Link to Article — Permalink…
The post ​Build a realtime polling web app with Next.js appeared first on CSS-Tricks.

Link: https://synd.co/2kpl03M