Update previously stored list of datetimes in a combobox, in a cycle for

Hi, how can I make sure that all the datetime stored previously by user input will be updated in a cycle for?
I explain better the structure
Combobox2 <----- is where list of datatime are previously stored
Combobox3 <------- is where remaining time is given by a substraction of two dates, stored in days remaing.
The fact, is now that these values are only stored and doesn't change with time passing by.
This is my code

Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click

        For i = 0 To ListBox1.Items.Count
            Dim d As DateTime = DateTime.Now
            Dim d2 As DateTime = ComboBox2.SelectedItem(i)
            Dim dysdiff As String = (d - d2).Days.ToString()
            ComboBox3.SelectedItem(i) = 365 - dysdiff & " Days"
        Next
    End Sub

Simplify Java persistence using Quarkus and Hibernate Reactive

This tutorial shows how you can simplify reactive Java applications that persist data using the Hibernate ORM with Panache extension in Quarkus.

Business applications preserve valuable business data in persistence stores such as relational databases. The application's presentation layer usually showcases the data for multiple uses, such as inventory, shopping, subscription, and monitoring. Java provides a core feature, the Java Persistence API (JPA), to manage persistent objects using object-relational mapping (ORM) with databases such as PostgreSQL, MySQL, and Microsoft's SQL Server. However, even when using JPA annotations, you must implement the JPA specifications to handle data transactions.

Creating Speech Balloons With the WordPress Block Editor

I do not know how I overlooked LIQUID SPEECH BALLOON. The plugin is less than a month shy of being three years old, and I follow block-related projects religiously. This one slipped through the cracks, at least until I haphazardly stumbled upon it when searching for something else entirely.

It is also relatively popular for a single-block plugin. There are not that many with more than 10,000 active installs. I had to know what it was doing to draw such a crowd.

In the comments on yesterday’s post about Automattic’s Livro theme, Nick Hamze wanted to know where all the fun theme designs were. Perhaps it was fortuitous timing that I also happened to be playing around with a plugin that might fit the bill. Sure, it is not a theme, but it can definitely be used to spruce up an otherwise boring or plain design.

So, I spun up a few Speech Balloon blocks and just had fun creating a chat with a some cartoon animals:

Four rows of speech balloons with cartoon animals making sounds.  Includes a cat, lion, chimp, and panda.
Inserting and customizing multiple Speech Balloon blocks.

I tend to gravitate toward clean, open-canvas themes because they allow me to add all the fun elements via the post content. That is why I love finding plugins like LIQUID SPEECH BALLOON. They add that visual flair to pages that can sometimes be boring.

Using the plugin’s Speech Balloon block is straightforward. It presents users with a single section for inserting rich text content.

A speech balloon with a default user avatar and placeholder text, "Speech," in the WordPress block editor.
Default Speech Balloon block.

In the block options sidebar, users can choose an avatar. They can also make several design adjustments, including background and text colors.

The block is falling slightly behind the times, though. Since the plugin’s release nearly three years ago, WordPress has added several new design components that could be used to make its block even better, such as padding, border, and typography controls.

The plugin can also be used for testimonials or other types of reviews. It works well enough for more business-friendly layouts if that is the sort of thing you are after.

Two columns of testimonials. Both show a user avatar on the left and a text review in the box on their right.
Creating testimonials with the Speech Balloon block.

The plugin’s biggest failure is in how it handles avatars. It is also why it does not make for the best option for testimonials. Users cannot add avatars directly via the block. Instead, they must register them via an entirely separate admin screen. Then, they can select from their saved avatars list within the block.

Under the Settings > LIQUID SPEECH BALLOON page, the plugin presents users with several rows of fields. They can add a name and image URL for each avatar.

10 rows of input fields in a settings form.  Each row has a Name field and an Image URL field.
Plugin’s avatar settings.

This is where the user experience falls apart a bit. There is no way to upload avatars on this screen. Instead, users must upload them via their media library, copy the URL, and paste it into the image URL field.

The plugin provides the necessary documentation and links to work through this process. The overall experience is simply lackluster.

However, if users only need a limited number of avatars, the system works well enough once everything is uploaded. The images are always available whenever inserting the Speech Bubble block — no need to search through the media library or upload a new one.

I am not sure if this will go in my plugin toolbox. Outside of a few stylistic elements, such as the speech bubble’s tail, users could readily recreate something similar with a few blocks, as shown in the following screenshot:

Two speech bubbles.  The first has a Panda next to it.  The text reads, "Hello, how are you doing?"  The second has a zebra and the same text.
Custom speech bubbles pattern.

Within a few minutes, I created this with what is already available in core WordPress, and I actually had several more design choices by doing so. I could see keeping a block pattern on hand for such a layout in the future.

For those who want a quick and easy solution without all the fuss of mixing and matching blocks, LIQUID SPEECH BALLOON would be the better option.

Benefits of the Python Development Language for AI and ML

Artificial intelligence and machine learning have been at their peak in technology and usage for a few years in the IT industry.

While there are still questions about the security of its development, the custom software development company has increased computer intelligence capabilities. In today's world, artificial intelligence is just an idea; it has become the need of every human being. AI is used to handle those jobs that cannot be done manually due to time constraints, increased volume, and intensity. It is why AI is widely used to analyze and process large amounts of data.

An Analysis on Designing Action-Based REST APIs

SOAP is based on operations that are mapped easily to a normal function in code. REST, on the other hand, deals with resources that should be mapped somehow to functions.

HTTP
 
Code| SOAP| REST
getUsers()| getUsers| !
addUser(..)| addUser| !
UpdateUser(..)| updateUser| !
deleteUser(..)| deleteUser| !

REST is not a protocol itself; it depends only on what HTTP provides. Therefore, HTTP should provide us with a solution to do/ask for something.

AWS Cognito Authentication With Serverless and NodeJS

In this post, we are going to see how we can create a REST API application for authentication using AWS Cognito, AWS Serverless, and NodeJS. We are going to use Lambda functions, API Gateway, and Serverless framework to achieve this.

Let’s start by setting up the project.

Will Automated Cloud Optimization Replace Your DevOps Job?

Replacing human folly for algorithmic efficiency means faster and better service and a "perfect cheeseburger" every time. So what can you expect when automated solutions start making decisions about your cloud infrastructure? Well, with the tasks it can do, automation certainly buys you time to do more interesting things than micromanaging your cloud infrastructure.

I wrote a guide to help you understand the impact of automation on your job and whether it will really put your DevOps, cloud engineer, or solutions architect job at risk anytime soon.

Android Native – Query Audio Files from MediaStore

Introduction

In Android development, the MediaStore API is a great API to use if you are building a music player. In this tutorial, we will learn how to query for audio files in the MediaStore database.

Goals

At the end of the tutorial, you would have learned:

  1. How to query for Audio files from the MediaStore.
Tools Required
  1. Android Studio. The version used in this tutorial is Arctic Fox 2020.3.1 Patch 4.
Prerequisite Knowledge
  1. Intermediate Android
  2. Android permissions.
  3. ActivityResult API.
  4. Basic SQL.
Project Setup

To follow along with the tutorial, perform the steps below:

  1. Create a new Android project with the default Empty Activity.

  2. Remove default Hello World! TextView.

  3. Add a new Button under ConstraintLayout.

  4. Constraint the Button to the center of the screen.

  5. Extract the Button android:text value to strings.xml. Set the Resource Name to button_startQuery and Resource Value to Start Query.

  6. Your activity_main.xml content should be similar to the code below.

     <?xml version="1.0" encoding="utf-8"?>
     <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_startQuery"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
     </androidx.constraintlayout.widget.ConstraintLayout>
  7. Download the .mp3 file called Unexpected Gifts of Spring by Alextree from the FreeMusicArchive. This song is licensed under CC BY 4.0.

Project Overview

The frontend of our project is quite simple. It only has a single button. When the project is completed, our App should be able to perform the workflow below:

  1. User taps the Starts Query button.
  2. If the App has not been granted the runtime(dangerous) permission of android.permission.READ_EXTERNAL_STORAGE, the App will request the user to grant this permission.
  3. If the App has received the permission, it will then query the MediaStore database for entries matching the query parameters.
  4. The App will log the query results via the debugging channel.
READ_EXTERNAL_STORAGE

Because our App workflow requires the READ_EXTERNAL_STORAGE permission, so we will take care of that first. Based on the documentation, this permission is a runtime permission, so we must manually request it ourselves (API 23 or higher).

To add the permission request into our workflow, performs the steps below:

  1. In AndroidManifest.xml, add the <uses-permission> element inside of <manifest>, but outside of <application>.

     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  2. Open up the file MainActivity.kt. Inside of onCreate(), add a reference to the Button object.

     val button = findViewById<Button>(R.id.button)
  3. Below the button reference, add the code below to define an ActivityResultLauncher with an empty callback.

     val permissionResultLauncher = registerForActivityResult(RequestPermission()){ isGranted ->
    
     }
  4. Add the code below to bind the Button onClickListener to the permissionResultLauncher#launch() action.

     button.setOnClickListener {
        permissionResultLauncher.launch(READ_EXTERNAL_STORAGE)
     }
  5. You can run the app now if you wish just to see how the permission flow looks like. To clear the granted permission, either reinstall the app or use the adb revoke command below:

     adb shell pm revoke com.example.daniwebandroidqueryaudiomediastore android.permission.READ_EXTERNAL_STORAGE
MediaStore

The Android system has common public locations for Apps to store media files, such as Audio, Video, or Image. For this tutorial, we are only concerned about audio files; Android will automatically scan for audio files in the locations below.

  • Alarms/
  • Audiobooks/
  • Music/
  • Notifications/
  • Podcasts/
  • Ringtones/
  • Recordings/

After scanning, it stores information about these files inside an internal database called MediaStore. To interact with this database, we can use the MediaStore API. When interacting with the MediaStore database, there are a couple of important things to keep in mind:

  1. MediaStore only automatically refreshes its data at certain times, like a cold boot.
  2. Apps can write entries to the MediaStore even if the actual files do not exist. A file can be deleted in a way that does not trigger MediaStore to update itself. Proper checking/error handling is recommended when attempting to play a media file.
MediaStore Query

Even though we are interacting with the MediaStore database via the MediaStore API, just like any SQL query, we will need to create our query. To do this, follow the steps below:

  1. Inside the MainActivity class, create a new queryAudio() function.

     private fun queryAudio(){
     }
  2. To send a SQL query to the MediaStore database, we would use the query() function from the ContentResolver object. We can retrieve the ContentResolver from the App Context. Add the code below into queryAudio().

     applicationContext.contentResolver.query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        selectionArgs,
        sortOrder
     )
  3. The query() function used here takes 5 arguments. Refer to the list below for a simplified explanation for them.
    a. uri: the location to query.
    b. projection: the columns that you want to be included.
    c. selection: this is where you put the SQL WHERE clause.
    d. selectionArgs: if you have any parameter used in the selection query (the previous function argument), you can provide values for them here.
    e. sortOrder: how you would like the result to be sorted.

  4. Now let us define the arguments before the query() call.

     val projection = arrayOf(
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.ALBUM
     )
    
     val selection = null //not filtering out any row.
     val selectionArgs = null //this can be null because selection is also null
     val sortOrder = null //sorting order is not needed
Use the Cursor to navigate

The query() call returns a Cursor object, so we will need to use it to get the data.

  1. Link the result of the query() call to a use clause (similar to Java try-with-resource) using the code below.

     applicationContext.contentResolver.query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        selectionArgs,
        sortOrder
     )?.use { cursor ->
    
        val titleColIndex = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)
        val albumColIndex = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)
    
        Log.d(TAG, "Query found ${cursor.count} rows")
    
        while (cursor.moveToNext()) {
            val title = cursor.getString(titleColIndex)
            val album = cursor.getString(albumColIndex)
    
            Log.d(TAG, "$title - $album")
        }
     }
  2. The code snippet above will log the title and the album values to a logging channel.

  3. Add the top-level TAG in MainActivity.kt.

     private const val TAG = "AUDIO_QUERY"
  4. Call the query() function in your ActivityResultLauncher callback.

     val permissionResultLauncher = registerForActivityResult(RequestPermission()){ isGranted ->
        if (isGranted) queryAudio()
     }
Upload the audio file

Remember the audio file that we had to download earlier? You can find its metadata in the screenshot below. We expect that our App will output the correct value for Title and Album.

1.png

For MediaStore to generate an entry, we will upload the mp3 file directly to the file system and then reboot the device so MediaStore will refresh.

  1. Boot your emulator now.
  2. In Android Studio, open the Device File Explorer from View > Tool Windows > Device File Explorer.
  3. Navigate to /storage/self/primary/Music.
  4. Right-click on Music > Upload > select the mp3 file.

2.png

  1. Cold reboot your emulator.
Run the App

Now run the app while filtering Logcat for AUDIO_QUERY, and you will see that the App correctly logs the output.

2022-01-12 16:58:58.571 8415-8415/com.example.daniwebandroidqueryaudiomediastore D/AUDIO_QUERY: Query found 1 rows
2022-01-12 16:58:58.571 8415-8415/com.example.daniwebandroidqueryaudiomediastore D/AUDIO_QUERY: Unexpected Gifts of Spring - Glint EP

MediaStore_Audio.gif

Solution Code

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.daniwebandroidqueryaudiomediastore">

   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

   <application
       android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:roundIcon="@mipmap/ic_launcher_round"
       android:supportsRtl="true"
       android:theme="@style/Theme.DaniwebAndroidQueryAudioMediaStore">
       <activity
           android:name=".MainActivity"
           android:exported="true">
           <intent-filter>
               <action android:name="android.intent.action.MAIN" />

               <category android:name="android.intent.category.LAUNCHER" />
           </intent-filter>
       </activity>
   </application>

</manifest>

MainActivity.kt

package com.example.daniwebandroidqueryaudiomediastore

import android.Manifest.permission.READ_EXTERNAL_STORAGE
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.widget.Button
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission

private const val TAG = "AUDIO_QUERY"

class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       val button = findViewById<Button>(R.id.button)

       val permissionResultLauncher = registerForActivityResult(RequestPermission()){ isGranted ->
           if (isGranted) queryAudio()
       }

       button.setOnClickListener {
           permissionResultLauncher.launch(READ_EXTERNAL_STORAGE)
       }

   }

   private fun queryAudio(){
       val projection = arrayOf(
           MediaStore.Audio.Media.TITLE,
           MediaStore.Audio.Media.ALBUM
       )

       val selection = null //not filtering out any row.
       val selectionArgs = null //this can be null because selection is also null
       val sortOrder = null //sorting order is not needed

       applicationContext.contentResolver.query(
           MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
           projection,
           selection,
           selectionArgs,
           sortOrder
       )?.use { cursor ->

           val titleColIndex = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE)
           val albumColIndex = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)

           Log.d(TAG, "Query found ${cursor.count} rows")

           while (cursor.moveToNext()) {
               val title = cursor.getString(titleColIndex)
               val album = cursor.getString(albumColIndex)

               Log.d(TAG, "$title - $album")
           }
       }
   }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/button_startQuery"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

strings.xml

<resources>
   <string name="app_name">Daniweb Android Query Audio MediaStore</string>
   <string name="button_startQuery">Start Query</string>
</resources>
Summary

We have learned how to use the MediaStore API to query the MediaStore database. The full project code can be found at https://github.com/dmitrilc/DaniwebAndroidQueryAudioMediaStore

Android Native – How to Add Material 3 Top App Bar

Introduction

The release of Android 12 also came together with Material 3. Whether you love it or hate it, it is likely to be here to stay for a couple of years, therefore, it would be useful to know how to use it. In this tutorial, we will learn how to enable Material 3 themes and how to add the Material 3 Top App Bar into our app.

Goals

At the end of the tutorial, you would have learned:

  1. How to subclass a Material 3 theme.
  2. How to add Material 3 Top App Bar.
Tools Required
  1. Android Studio. The version used in this tutorial is Arctic Fox 2020.3.1 Patch 4.
Prerequisite Knowledge
  1. Basic Android.
Project Setup

To follow along with the tutorial, perform the steps below:

  1. Create a new Android project with the default Empty Activity.
Inherit Material 3 Theme

It is recommended that you apply an app-wide Material 3 theme before using any Material 3 component. Because we wanted to use the Material 3 Top App Bar, we should apply a theme such as Theme.Material3.DayNight.NoActionBar to our App.

  1. In your current project, navigate to res > values > themes.

  2. Open up both themes.xml and themes.xml (night).

  3. Inspect both files. Notice that both of their <style> elements have Theme.MaterialComponents.DayNight.DarkActionBar as the parent. This is only true on my build of Android Studio. If you are using a newer build in the future, you might see a different parent theme. The current theme is a Material 2 theme, so we will need to upgrade it to Material 3 that supports a Top App Bar.

     <style name="Theme.DaniwebAndroidMaterial3TopAppBar" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
  4. Replace the current value of the parent attribute with Theme.Material3.DayNight.NoActionBar for both XML files. This theme does not contain an ActionBar, which allows us to add a Top App Bar that conforms to Material 3 guidelines.

  5. Both of your <style> elements should look similar to this.

     <style name="Theme.DaniwebAndroidMaterial3TopAppBar" parent="Theme.Material3.DayNight.NoActionBar">
  6. But the code will not compile yet because you must add the gradle dependency for Material 3. Open up your gradle module file and replace the current material dependency of implementation 'com.google.android.material:material:1.4.0'to

     implementation' com.google.android.material:material:1.5.0-rc01'
  7. Sync the project.

  8. Run the app now and you can see that the old Action Bar is gone. The background color is also a little bit different, too.

10000201000002F600000326DF919741D4D5F1C0.png

Material 3 Top App Bar

There are many variants of the Top App Bar:

  1. Center aligned.
  2. Small.
  3. Medium.
  4. Large.

1000020100000184000001D9A011BFE668CF7C73.png

For this tutorial, we will add the center-aligned Top App Bar. Follow the steps below to add it to our app:

  1. Open up activity_main.xml in the Design view.

  2. Under the Component Tree, Right-click on ConstraintLayout > Convert view.
    10000201000001870000012397161C328A901CB1.png

  3. Select CoordinatorLayout > Apply.
    10000201000001ED000000C73E800DC420CFA532.png

  4. Switch to Code view.

  5. Add an <AppBarLayout> child to the <CoordinatorLayout>.

     <com.google.android.material.appbar.AppBarLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
    
     </com.google.android.material.appbar.AppBarLayout>
  6. Add a <MaterialToolBar> child to <AppBarLayout>.

     <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/topAppBar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:title="@string/page_title"
        app:titleCentered="true"
        app:menu="@menu/top_app_bar"
        app:navigationIcon="@drawable/ic_baseline_menu_24" />
  7. Add the string resource below to strings.xml.

     <string name="page_title">App Brand</string>
  8. Create a new xml resource for the menu by right-clicking on res > New > Android Resource File. Use the configuration from the screenshot below, select OK.
    100002010000040300000250CD341651C7332B4C.png

  9. Create a new drawable for the navigation icon by right-clicking on drawable > New > Vector Asset. Use the configuration from the screenshot below, and then select Next > Finish.
    1000020100000350000001CB6BC6276F2DE66846.png

  10. Remove the default Hello World! TextView.

Run the App

We are now ready to run the app, so run it now and we can see that we have a centered Top App Bar from the Material 3 library.

10000201000001940000034E7C9F50B56EFC9AD8.png

Solution Code

ic_baseline_menu_24.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
   android:width="24dp"
   android:height="24dp"
   android:viewportWidth="24"
   android:viewportHeight="24"
   android:tint="?attr/colorControlNormal">
 <path
     android:fillColor="@android:color/white"
     android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/>
</vector>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <com.google.android.material.appbar.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">

       <com.google.android.material.appbar.MaterialToolbar
           android:id="@+id/topAppBar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           app:title="@string/page_title"
           app:titleCentered="true"
           app:menu="@menu/top_app_bar"
           app:navigationIcon="@drawable/ic_baseline_menu_24" />

   </com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

top_app_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

</menu>

strings.xml

<resources>
   <string name="app_name">DaniwebAndroid Material 3 Top App Bar</string>
   <string name="page_title">App Brand</string>
</resources>

themes.xml

<resources xmlns:tools="http://schemas.android.com/tools">
   <!-- Base application theme. -->
   <style name="Theme.DaniwebAndroidMaterial3TopAppBar" parent="Theme.Material3.DayNight.NoActionBar">
       <!-- Primary brand color. -->
       <item name="colorPrimary">@color/purple_500</item>
       <item name="colorPrimaryVariant">@color/purple_700</item>
       <item name="colorOnPrimary">@color/white</item>
       <!-- Secondary brand color. -->
       <item name="colorSecondary">@color/teal_200</item>
       <item name="colorSecondaryVariant">@color/teal_700</item>
       <item name="colorOnSecondary">@color/black</item>
       <!-- Status bar color. -->
       <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
       <!-- Customize your theme here. -->
   </style>
</resources>

build.gradle

plugins {
   id 'com.android.application'
   id 'kotlin-android'
}

android {
   compileSdk 31

   defaultConfig {
       applicationId "com.example.daniwebandroidmaterial3topappbar"
       minSdk 21
       targetSdk 31
       versionCode 1
       versionName "1.0"

       testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
   }

   buildTypes {
       release {
           minifyEnabled false
           proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
       }
   }
   compileOptions {
       sourceCompatibility JavaVersion.VERSION_1_8
       targetCompatibility JavaVersion.VERSION_1_8
   }
   kotlinOptions {
       jvmTarget = '1.8'
   }
}

dependencies {

   implementation 'androidx.core:core-ktx:1.7.0'
   implementation 'androidx.appcompat:appcompat:1.4.0'
   implementation 'com.google.android.material:material:1.5.0-rc01'
   implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
   testImplementation 'junit:junit:4.+'
   androidTestImplementation 'androidx.test.ext:junit:1.1.3'
   androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
Summary

We have learned how to add a Material 3 Top App Bar into our App. The full project code can be found at https://github.com/dmitrilc/DaniwebAndroidMaterial3TopAppBar

Digital Lending Is a New Trend in Fintech in Recent Years

Digital lending is currently known to be one of the top new trends in Fintech in recent years. Digital lending is the way of providing loans that are applied for, paid for, and handled via digital channels. Lenders utilize digitized information to make lending choices and generate strategic client loyalty, and this process is becoming more popular. 

The global credit market, including Fintech, is undergoing transformation. Create digital content in seconds, then distribute them online to more connected worldwide consumers by making use of increasingly digitized and available customer data, technological improvements in machine learning and artificial intelligence, and cheap digital platforms. A new trend of Fintech has emerged: the digital lender. 

CDNs and Cloudflare in WordPress – A Definitive Guide

A CDN, or Content Delivery Network, is a system of globally distributed servers that deliver content on behalf of other servers. CDNs cache data from the origin server, allowing users to access the data from a server near them, thus improving performance and reducing latency.

CDNs are an essential part of our modern world. The content that you view on any website or app―whether through a desktop, laptop, tablet, or smartphone―is very likely to have been delivered using a content delivery network.

In this article, we’re going to do a deep dive into content delivery networks, honing in on exactly what it is they do, and how. We’ll also look at a handful of the most used CDNs, and then zoom in on Cloudflare in particular, sharing our thoughts on what sets it apart. Rounding this out will be some tutorials on the different ways you can get Cloudflare up and running. Spoiler: it’s easy peasy.

Continue reading, or jump ahead using these links:

And away we go!

What is a CDN, and Why Do You Need it?

CDNs came into existence in the late 1990s as a means for alleviating the performance bottlenecks of the internet. Since then, they have grown to serve a huge portion of internet content, including web objects (text, graphics, scripts), downloadable objects (media files, software, documents), applications (e-commerce, portals), and media (live streaming, on-demand, & social media).

Without effective CDNs, most of what you view in today’s online world, in particular content that is accessed from a distance or simultaneously with a slew of other users, would take forever to load, have regular delivery interruptions (buffering, glitching, freezing), or completely immobilize websites.

Computer glitching
Without CDN’s delivering data from server to server, the potential for issues is high.

There are many positives to utilizing a CDN. In addition to increased speed, they also amp up site security, lower costs, allow for higher scalability, and deliver a better user experience.

Content origin servers are at a much greater risk of failure without a CDN. Since they must respond to every individual end-user request, large spikes in traffic or persistent loads pose a high likelihood of risk.

By responding to end-user requests with a server that is closer in both physical and network proximity than the origin, a CDN offloads traffic from content servers and improves the web experience, benefitting both the content provider and its end-users.

If your website is hosted in close geographical positioning to a user trying to access your content, they will see your content in fractions of a second. But for those who are further away, that distance creates issues, because the browser has to fetch content from the server in your region, then display it to someone who is thousands of miles away.

Additionally, if users from other countries are requesting the same content simultaneously, the server becomes laden with those requests, increasing the time it takes to load and serve the content. This in turn will impact the speed of content delivery to the user.

A content delivery network offers the solution to this scenario. Since CDNs are broad networks of servers deployed around the world, storing and caching your website’s assets on them provides vastly improved speeds to the end user. Users at a significant distance from you get cached content fetched and delivered to them from a much closer server when using a CDN.

A Sphere of CDNs

Like most tools in the world of WordPress, there are many content delivery networks out there.

Here are a handful of the most well-known CDNs:

  • Amazon CloudFront
  • Microsoft Azure CDN
  • KeyCDN
  • StackPath
  • Akamai
  • Sucuri
  • CacheFly
  • Imperva/Incapsula
  • Cloudflare

Those are just a portion of the companies available. Without going too far in depth, we’ll do a quick roundup of these most popular ones.

Amazon CloudFront is one of the branches under business titan Jeff Bezos. Amazon Web Services (aka AWS, the world’s most comprehensive and broadly adopted cloud platform), is built for high performance, security, and developer convenience. CloudFront securely delivers content with low latency and high transfer speeds, delivering data through 310+ globally dispersed Points of Presence (PoPs) with automated network mapping and intelligent routing.

To use it, you need to create a CloudFront distribution with the AWS for WordPress plugin, or create a secure static website.

Microsoft Azure CDN is an branch of tech magnate Bill Gates’ Windows software company. It provides secure, reliable content delivery, with global coverage and massive scalability. Azure lets you reduce load times, save bandwidth, and speed responsiveness—whether you are developing or managing websites or mobile apps, encoding & distributing streaming media, gaming software, firmware updates, or IoT endpoints.

KeyCDN is a budget-friendly CDN that offers a wide variety of options to improve the performance of websites. Some of the tools include unlimited SSL certificates, low latency, aggressive Gzip compression, rapid HTTP/2 delivery, traffic restriction settings, hotlink protection, and two-factor authentication. Pricing includes unlimited HTTP & HTTPS requests, and a low minimum usage charge (per month), based on the combined total account traffic volume and other services used.

StackPath has comprehensive built-in capabilities, including content protection and asset optimization. Stackpath CDN offers high speed performance (worldwide edge locations, redundant Tier-1 carrier connections, global Anycast, private network backbone between all locations), increased security (delivery control, DDoS attack mitigation, SSL), full visibility (built-in analytics & reporting, RESTful API, customization options), and lower total costs (reduce total bandwidth consumption, reduce downtime, and increase accessibility).

Akamai is one of the oldest content delivery network companies in existence. Purportedly the world’s largest edge platform, Akamai’s tagline is to “keep your digital experiences closer to users, and threats farther away”. They have fast, engaging app & API performance (enhanced by robust data and automation), and consistent delivery of streaming experiences to the largest audiences, on any device. Note: Akamai does not publish specifics on how large their CDN network is or where the POPs are.

Sucuri CDN caches your website on its edges automatically, speeding it up by 70%. Sucuri offers multiple caching options, reliable website uptime, and high availability and redundancy. They also fine-tuned settings to give maximum performance and protection, with custom options available. You can choose what best fits your needs, or get an assist from them. Their Global Anycast Network has 10 SuperPOPs in the USA, Europe, Asia, and 2 CDN POPs in Australia and Brazil.

CacheFly specializes in fast delivery of media files, promising video delivery with less than 1s latency. Aside from ultra-low latency video streaming (delivering video to more than a million uses concurrently), CacheFly also provides lightning-fast gaming (with industry-leading throughput speeds), mobile content optimization (automatic and simple), and multi-CDN (for redundancy and failover). From these specs, you can see CacheFly is particularly suited to streaming and gaming customers (though not exclusive to them).

Imperva (formerly, Incapsula) brings content caching, load balancing, and failover natively built into a comprehensive Web Application and API Protection (WAAP) platform, so your applications are securely delivered across the globe. DDoS protection and Secure CDN are combined to provide complete edge security. Imperva’s website/network defense makes it ideal for corporations that handle confidential information, such as banks and insurance agencies.

Cloudflare is a global CDN designed to make all of your internet connections secure, private, and fast. This flexible and programmable global network was built to serve companies and organizations of all sizes, from individual developers to large corporations, providing services to everyone that were once only available to internet giants. Cloudflare is robust, reliable, and smooth.

CDN and DNS

Some CDNs, such as Amazon CloudFront, require you to perform the initial server load, then use the CDNs URL when referencing the asset. The CDN will then determine which server to use to actually handle the request.

Other CDNs, such as Cloudflare, operate further upstream at the DNS level. Effectively, all of your traffic is routed through Cloudflare (by changing your nameservers to their nameservers). It then analyzes each request, serves those it has an asset for (grabbing them in an initial scan), and passes the others through to your site (mostly your dynamic content, such as posts and pages).

The DNS approach has several distinct advantages:

  • Quick and effortless – it’s just a matter of changing your nameservers
  • Easily reversed – simply change your nameservers back to your hosting provider
  • Improved security – Cloudflare looks at every single request and automatically filters out those that are from known suspicious IP addresses
  • There a no changes to the publishing process

Add to that list the fact that Cloudflare has a free tier in its product list, and using Cloudflare for your WordPress site is pretty compelling. And the reason why it’s our top choice for a CDN.

What is Cloudflare, & What Makes it So Special?

Cloudflare is a powerful CDN, who’s architecture gives you an integrated set of network services, designed to run every service on every server in every data center across their global network, all accessible from a single dashboard.

Cloudflare banner
Cloudflare is an extremely powerful and popular CDN.

It’s secure. Built into every component of the network, Cloudflare’s 100 TBPS network blocks an average of 70 billion threats per day, including some of the largest DDoS attacks ever recorded.

It’s private. Cloudflare complies with local regulations for data locality and storage, and doesn’t generate revenue from advertising (no collection and retention of personal data processed on behalf of the customer).

It’s fast. It has connections to all major cloud providers, and interconnections with nearly every service provider around the world. Plus data centers in over 250 cities that deliver sub-50-millisecond latency to 95% of the internet users in the world.

It’s hassle-free. Cloudflare is designed with maximum ease in mind:

  • setup takes less than 5 minutes
  • anyone with a website and their own domain can use CF (regardless of platform)
  • no additional hardware or software is required
  • no code changes are needed
  • you can keep your current hosting provider (or choose any one you prefer)

Cloudflare also lays claim to an amazing feature that is unique to them—APO, or Automatic Platform Optimization. The effects of using APO are similar to hosting static files on a CDN, but without the need to manage a complicated tech stack.

In addition to caching your static assets (images, JavaScript, CSS), APO caches the actual content on your site (the HTML) using Cloudflare’s massive edge network.

With your entire site being served from cache, your visitors will get near instant load times. Cloudflare reports that its testing shows APO delivers consistent load times of under 400ms for HTML Time to First Byte (TTFB).

Content creators retain the ability to create dynamic websites, without any changes to their workflow for the sake of performance.

If you’re currently using Cloudflare’s free plan, you can get the APO add-on for a low (single-digit) monthly fee. If you’re on their Professional, Business, or Enterprise plans, APO is already included in your subscription.

The plans and prices listed on Cloudflare’s website are under the top menu header Application Services > Overview. The APO feature is under Application Services > Add-ons.

Now that we have a clear picture of what Cloudflare can do, let’s move on to implementing it.

Cloudflare Setup

As mentioned prior, setting up Cloudflare in a simple process. There are multiple options for implementation, and we’ll do a walk-through for each one.

The first step required is…

Creating a Cloudflare Account

Whether you are going to use their free service or purchase a plan, you will need to have a Cloudflare account.

If you already have a Cloudflare account, you must login first to add a site.

If you don’t already have one, you need to create a Cloudflare account:

  1. Go to CloudFlare’s sign up page.
  2. Enter your Email address and Password.
  3. Click Create Account.

That’s all there is to account setup. Next we’ll look into putting Cloudflare in motion using three different methods.

Setting Things Up Through Cloudflare’s Website

Once you have created an account and/or logged in, Cloudflare asks you to add a site. You can also add multiple sites at once with CF’s automation, if you’re so inclined.

Let’s add a single site now.

Adding a Site to Your Cloudflare Account

  1. Once you’re logged in on your account page, click Add a site from the top right of the Home page/dashboard.
  2. Enter your website’s root domain, then click Add Site below. Example: if your website is www.mysite.com, type mysite.com.

    Cloudflare choose a site
    Choose the domain you want to be proxied through Cloudflare.
  3. Select one of the plans, then click Continue at bottom.

    CF choose a plan
    Selecting a plan during Cloudflare account creation. They have a free one!
  4. Cloudflare does a quick scan for existing DNS records, then loads the page Review your DNS records.

    CF DNS records
    A window into your DNS records management on Cloudflare.
  5. Verify that DNS records in the query results are configured correctly. (These records will take effect in Cloudflare after you update your nameservers.)For a free account, your status will be Proxied: Accelerates and protects traffic, which is indicated by the orange cloud icon.
  6. Adjust records as needed, or click Continue.

Click here if you need to manually add missing DNS records.

Click here if you need help regarding which subdomains are compatible with CF’s proxy.

To finish setup and activate your domain on Cloudflare, your nameservers must point to them. Which brings us to the next section.

Changing Your Domain Nameservers to Cloudflare

CF nameservers message
Nameservers have to be revised to work in Cloudflare.

You can point nameservers from any registrar to Cloudflare through your account settings.

Cloudflare does have its own registry service, meaning you can purchase a domain directly from them, if you like. (Cloudflare’s domain registry service currently supports common TLDs (top level domains) only.)

  1. Login & navigate to Cloudflare’s dashboard, then click on your newly added domain.

    CF homepage
    Your websites on Cloudflare’s homepage.
  2. Cloudflare will take you to their Overview > Complete your nameserver setup page. Copy (or memorize) both nameserver 1 & 2 under Replace with Cloudflare’s nameservers.

    CF copy nameservers
    Step right up, and get your nameservers from Cloudflare.
  3. Log into the administrator account for your domain registrar. If you are unsure who your domain registrar is, you can go to ICANN to find out.

    ICANN registry lookup
    ICANN will locate your domain registrar if you don’t know who it is.
  4. Replace the current nameserver records in your registrar account with the information you copied from Cloudflare.

Presto, change-o, you’ve repointed your nameservers.

Here is a handy list of detailed instructions & links for the most common registrars.

  1. Wait for your registrar to update your nameservers; this can take from a few minutes up to 24 hours.
  2. Confirm your site activation by logging into the Cloudflare dashboard.
  • If you no longer see Complete your nameserver setup, you have successfully updated your nameservers and your domain is active at Cloudflare.
  • If Complete your nameserver setup still appears, ensure the nameserver output correctly spells the Cloudflare nameservers, and confirm Cloudflare’s nameservers are the only nameservers listed.
  • If the nameserver output is correct, select Re-check now.

You should now see—or will soon see—the green check mark on this domain in your Cloudflare account. You will also receive a confirmation email from Cloudflare once your nameservers are active on their site.

CF confirmation
Cloudflare confirmation gives you something to shout about.

Click here for additional help changing your domain nameservers to Cloudflare.

For DNS records proxied to Cloudflare, Cloudflare’s IP addresses are returned in DNS queries instead of your original server IP address. This allows Cloudflare to optimize, cache, and protect all requests for your website.

Verifying Your Traffic is Routed Through Cloudflare

Though not required, you can check that your domain nameservers are now pointing to Cloudflare through other means. There are a couple of different methods for doing this.

Note that most DNS tools online use cached query results, therefore it may take longer for them to show the updated nameservers.

Method 1: Use the following text in the operating system command line/prompt.

On Linux/Unix:
dig domain_name +trace @1.1.1.1
dig domain_name +trace @8.8.8.8

On Windows:
nslookup domain_name 1.1.1.1
nslookup domain_name 8.8.8.8

Be sure to replace the generic “domain_name” with your actual domain name.)

Wondows C prompt check
What my Windows command prompt nameserver check revealed.

FYI, 8.8.8.8 is a Google DNS server, while 1.1.1.1 is a DNS resolver operated by Cloudflare.

Method 2: Use an online tool, such as this DNS Propagation Checker.

If the nameservers returned here are not the ones provided and expected by Cloudflare, you’ll need to check with your Registrar.

If you run into issues, here are some things you can do:

  • Check that no DS records are present; if any are, remove them at your Registrar.
  • Check that only the Cloudflare nameservers are present; if there are others, remove them in Registrar configuration.
  • Check that the Cloudflare nameservers are spelled correctly in your Registrar configuration.

Click here for additional Cloudflare DNS FAQs.

Confirm Traffic is Proxied to Cloudflare

Some online tools such as GTmetrix don’t recognize Cloudflare as a Content Delivery Network, due to the fact that Cloudflare doesn’t operate like a traditional CDN.

To confirm your domain traffic actively proxies through Cloudflare:

  1. Copy this URL >> https://www.mysite.com/cdn-cgi/trace, then replace the “www.mysite.com” portion with the domain proxied to Cloudflare.
  2. Paste the edited code into your browser, and enter to load the page.

If proxied to Cloudflare, output similar to the image below will appear in your browser:

Proxy checker example
Example text to confirm domain traffic is proxied through Cloudflare using cdn-cgi trace.
Proxy checker, my result
My result, confirming traffic is proxied through Cloudflare using cdn-cgi trace.

If you don’t observe similar output:

  • Confirm your DNS record has the orange cloud icon in its row.
  • Enter your domain at ICANN to confirm the nameservers only list Cloudflare nameservers for your domain.

For any unresolved issues or questions, check out Cloudflare’s full troubleshooting guide.

Now we’ll look at our second scenario, which is…

Setting Up Cloudflare via cPanel

In this section, we’re going to look at how to activate Cloudflare through the cPanel customer interface.

Many hosting providers have support for Cloudflare built into cPanel, so installing Cloudflare is as simple as filling in a short form. Depending on how your hosting provider handles cPanel, this may look slightly different, but should follow the same basic steps.

  1. After the Cloudflare plugin is installed, you should see a Cloudflare icon in cPanel. Double-click to open the application.

    CF in cPanel
    Locating Cloudflare in the software section of cPanel.
  2. Login to your Cloudflare account through the login screen. (If you skipped over the account creation part of this article and don’t yet have an account, click on Sign up.)
  3. Your Cloudflare account will likely be configured for you, again dependent upon your hosting provider. However, you should be able to select which sites you want to use Cloudflare with.

Now on to our final method…

Using the Cloudflare WordPress Plugin

Cloudflare has their own plugin on the WordPress repository.

CF plugin in WP
The Cloudflare plugin for WordPress, ready for installation.

Use of the plugin is not necessary by any means, whether or not you have already set up Cloudflare. It simply serves as another point of access to some of Cloudflare settings, allowing you to view or adjust them from within WordPress. Not all options are accessible under the free plan, rather require a Pro/paid plan.

Let’s do a quick walkthrough of how the plugin installs and works.

  1. Go to the WordPress repository, and search for Cloudflare (or, do it directly from within the WordPress dashboard, via Plugins > Add new).
  2. Install and activate the plugin, then click Create Your Free Account, or Sign in here.

    CF plugin splashscreen
    Logging in through the WordPress Cloudflare plugin.
  3. Enter your Cloudflare account email address and API key; click on Save API Credentials.

    CF plugin enter credentials
    Cloudflare’s API credentials entry field in the WordPress plugin.

After sign-in, you’ll be taken to the Cloudflare plugin’s Home page. There are two other pages you can access here, which you’ll see identified by blue icons at the top—Setting, & Analytics.

Home and Settings will keep you in the plugin, while Analytics connects you to the Cloudflare.com website.

CF plugin homepage in WP
The landing page of the Cloudflare WordPress plugin.

Here’s a short video of what the plugin options offer on each page, once you are signed in.

Options available through the Cloudflare plugin for free and paid plans.

Options available through the Cloudflare plugin for free and paid plans.

Now that we’ve looked into setting up Cloudflare in a variety of ways, I’d like to show you how to boost it even further by…

Optimizing Cloudflare in Hummingbird

Hummingbird, if you’re unfamiliar, is our WordPress speed optimization plugin—and it’s completely free.

If you use WPMU DEV’s hosting, or have one of our memberships, Hummingbird Pro is automatically included in the package of services & products we provide (along with our other premium plugins).

Hbird plugin banner
The Hummingbird plugin banner on WordPress.org.

Hummingbird is a full performance suite, with world-class caching, one-click minification, and a slew of other premium optimization tools.

Hummingbird also has an integration for Cloudflare’s APO, built right in!

Hbird & CF Integration
Hummingbird and Cloudflare work in tandem to give you an incredible amount of speed and protection.

Cloudflare’s APO for WordPress is a paid feature. (See prior section, “What Makes Cloudflare So Special”, for more information on features, plans, and pricing.)

However, you can still integrate Cloudflare in Hummingbird on their free plan, with no paid add-ons. The benefit you would gain is the ability to clear Cloudflare’s browser cache from within Hummingbird.

In the end, it’s a personal choice whether or not to get APO, but it is a robust feature, well worth investing in for the small fee it requires.

Let’s look at how to set up Cloudflare integration in Hummingbird.

  1. Navigate to Cloudflare.com, and make sure you’re logged in.
  2. From your main account page, choose the domain you are using for this, then click on it. On the resultant page load, scroll to the bottom, and click on Get your API token.
    Though you can use your Global API Key or API Token from Cloudflare for the Hummingbird integration, the API token is recommended, because it’s isolated per zone. The Global API key gives admin access to your account, which isn’t really required.

    CF get API token
    Getting an API token from Cloudflare’s website.
  3. From the API Tokens section, click on Create Token.

    CF API create token
    API token creation in Cloudflare.
  4. Scroll down to WordPress in the list of API token templates, then click on Use template.

    CF token WP template
    WordPress is one in a list of many pre-configured permission templates.
  5. Now we have to create a zone for this token. Scroll down to Zone Resources, then click the dropdown menu under All Zones, and select Specific zone.
    A new selection menu will pop up on the right. We need to pick the specific zone from this dropdown, which will be the domain we’re going to connect through WordPress and Hummingbird. Click Continue to summary.

    CF API zone resources
    In Zone Resources, select the type of zone, then the specific zone.
  6. Cloudflare will display a summary displayed in tiered format. Click on Create Token below it.

    CF API token creation
    Cloudflare’s WordPress API token creation summary.
  7. The API Token Key has been created. Click on the Copy button to copy to clipboard.
    CF API token ready to copy
    Copy the API token Cloudflare creates for you.

    You can view the tokens associated with your domains on Cloudflare any time. The list under each domain will show you what tokens are active.
    Just click on the ellipses “” to see the options for View summary, Edit, Roll, and Delete. This makes it quick and easy to revoke a token if you ever desire to do so.

    CF API manage tokens
    Cloudflare’s API token management page.

    The Roll option is what you’d choose if your API token (Cloudflare calls this “the secret”) is lost or believed to be compromised. Rolling your secret key into a new one will invalidate the previous one, but the access and permissions will be the same as the previous key.

    Now that we’ve got our token, we can head back over to the Hummingbird plugin in our WordPress website.

  8. From the dashboard, navigate to Hummingbird > Caching.

    CF in Hbird integrations page
    Hummingbird Integrations are available from the Caching page.
  9. From Integrations, click the blue plus + button on the right of the Cloudflare row, and the Hummingbird popup wizard appears.
    Make sure the email associated with your Cloudflare account is in the email field, then click API Token. Paste the key you copied into the Cloudflare API token field, then click Connect.

    CF Hbird credentials entry
    Entering the credentials required in Hummingbird’s popup integration wizard.

    Hummingbird presents a message, indicating you need to activate a zone.

  10. From the dropdown menu for Select zone, choose the domain we just got the API token for on Cloudflare, then click Enable Cloudflare.

    Hbird CF add zone
    After inputting credentials, you need to tell Hummingbird which zone (domain) you’re connecting.

Tada! You’ve now successfully integrated Cloudflare with Hummingbird.

Hbird CF confirmation of connection
The green indicators under Status let you know your Cloudflare account is connected in Hummingbird.

One last bit of housekeeping to take care of—if you subscribe to Cloudflare’s APO feature.

Scroll down to the bottom of the page and toggle the button for Enable APO. And there you go!

Hbird CF enable APO
Hummingbird’s Cloudflare integration allows enabling APO.

If you don’t pay for Cloudflare’s APO service, this toggle button will be grayed out, but a link is provided to purchase it from Cloudflare’s site for your convenience (if you’re interested).

Hbird & CF cache by device
Hummingbird integration settings for Cloudflare allow you to Cache by device type.

Once enabled, you can also select an additional option inside to cache content according to the device types used by your site visitors. Cache by device type ensures that only needed assets are cached and delivered to the user’s browser depending on the device type used: mobile, tablet or desktop.

Hummingbird and Cloudflare will now work in tandem to give you an incredible amount of speed and protection.

On Cloud(flare) 9

In today’s world, almost all websites and applications rely on a CDN to help serve content to their users. Which makes sense, given that CDNs have proven their many benefits, including these top four: better performance, increased reliability, cost savings, and resilience against cyber attacks.

There are many options for choosing a CDN, so if you don’t like one you tried previously, don’t give up! Cloudflare in particular is such a good choice, especially due to their amazing and proprietary APO feature.

As you’ve seen in this article, setting up Cloudflare in WordPress can be done in a number of different ways (none of which are difficult), and afterward you will continue to reap its rewards.

Considering the power and prevention that CDN and Cloudflare bring, there seems little reason not to give them the old college try.

8 Helpful Accessibility Links for January 2022

Every now and then, I find that I’ve accumulated a bunch of links about various things I find interesting. Accessibility is one of those things! Here’s a list of related links to other articles that I’ve been saving up and think are worth sharing.

Screenshot of the Accessibility Maze homepage.

8 Helpful Accessibility Links for January 2022 originally published on CSS-Tricks. You should get the newsletter and become a supporter.

JDBC Tutorial Part 3: Using Database Connection Pools

In part 3 of this tutorial series, you’ll learn what a database connection pool is and how to use it. Connection pools are a must in web applications that require handling simultaneous requests that consume a database.

Note: We’ll continue where the previous step of the tutorial left off. Refer to part 1 and part 2 of this tutorial for more details. The source code is available on GitHub.

Who Can Get The Welcome Bonus at Bingo Billy Casino?

  Contents List of the most popular online slots Bingo Billy Casino Bonus Money Registration and Login to Bingo Billy Casino You can play for free at Bingo Billy online gaming casino Bingo Billy Casino Newcomers at the beginning of his career in the casino can count on only some bonuses in online casinos, one […]

Anypoint Platform Connected Apps

What Is a Connected App?

The connected App feature provides you the option to integrate an external application with the Anypoint platform without sharing your user credentials with the help of OAuth 2.0 or OpenID Connect.

Authentication Protocol Supported by Connected Apps 

1. OAuth 2.0: OAuth (Open Authorization) is an open protocol that enables secure API authorization from applications in a standardized way. It can authorize resource access without revealing user credentials to apps.