If you are trying to add / edit the "Pages" widget on your Blogger blog's layout you may have noticed that it isn't working lately.
Show random product suggestions on Checkout page in Shopify
An "Add more to cart" module on the Checkout is a great way to increase the amount of products your customers buy, Checkout page can be a great place for showing a few more products that your customers may want to add to their carts.
Editing the Checkout.liquid file is only possible for Shopify Plus users, so this tutorial is targetted only for Shopify sites which have the ability to edit the checkout's liquid file, if you don't you may not be able to do this.
What are we building?
This. If you are here you know why you may need it so I won't go into the details about the marketing needs for having an up-sell module on your checkout page.
Show me how to do this
Even after you get the ability to edit Checkout.liquid file you still don't get a whole bunch of goodies that you can simply drag and drop on your Checkout pages. We will use JS DOM Manipulation to insert the required HTML.
Next is getting a list of random products, now no AJAX API in Shopify provides a direct API to get you a list of random products, so we built a nice enough system to get us that, using Product Recommendations API
Let's get started
<script type="text/javascript">If you are having trouble viewing the code then check this Gist on Github with the full code where you can copy and paste easily.
var addProuct = function( variant_id, qty, btn ) {
if ( !qty ) { qty = 1; }
var data = {
"id": variant_id,
"quantity": qty
};
window.Checkout.jQuery.ajax({
type: 'POST',
url: '/cart/add.js',
data: data,
dataType: 'json',
success: function() {
// As soon as the success response is received we reload the page,
// so the user can see the updated cart items on checkout page itself.
$( btn ).removeClass('btn--loading');
window.location.reload();
}
});
};
// Function that makes a call to the Product Recommendations API, we pass a random product id and get a list of products, then we choose a random product from that list of products.
function _getARandomProduct( productid ) {
Checkout.$.getJSON("/recommendations/products.json?product_id="+ productid +"&limit=5", function( res ) {
if ( res.products != null ) {
var selectARandom = res.products[ _getRandomInt( 0, ( res.products.length - 1 ) ) ];
// We don't get the different sizes of images in the response, so we do a simple string replace to add _small to load a small image and not a full sized one.
var smallImage = selectARandom.featured_image.replace('.jpg', '_small.jpg');
// This is one individual product card,
var productHtml = `
<div class='random-product-item'>
<div class='thumb-product-img'>
<img src='${ smallImage }'>
</div>
<div class='product-detail-col'>
<h4 class='prod-title'><a href='${ selectARandom.url }' target='_blank'>${selectARandom.title}</a></h4>
<div class='prod-price'>Rs.${ (selectARandom.price / 100) }</div>
</div>
<div class='product-add-wrapper'>
<a href='#' class="extra-productadd-btn" data-variant='${selectARandom.variants[0].id}'>
<span class='btn-text'>Add</span>
<svg class="icon-svg icon-svg--size-18 btn__spinner icon-svg--spinner-button" aria-hidden="true" focusable="false"> <use xlink:href="#spinner-button"></use></svg>
</a>
</div>
</div>
`;
// We keep appending each product to the HTML
Checkout.$('.checkout-add-products-list').append( productHtml );
}
});
}
function _getRandomInt(min, max) {
return min + Math.floor(Math.random() * (max - min + 1));
}
// This is the entire function that will execute on page load, here we will reference to the functions that we created above.
(function(){
$ = Checkout.jQuery;
$( document ).on('page:load page:change', function(){
/*
* Add more products to cart.
*/
// Here we add this container HTML after the #order-summary div that's there on the page
$('#order-summary').after( `
<div class="checkout-add-cart-module">
<h4>Add more products to cart</h4>
<div class='checkout-add-products-list'></div>
</div>`
);
// IMPORTANT:
// These are product ids, it should be different for your site. These product ids are what we use to find random related products, so fill these with the products from collections from where you want to show random products.
// To get the product ids go to a product edit page, on the browser address bar you will find the id in the url at the end.
var productIds = [
'5514666082459', '5448173977755', '5448178270363', '5448176894107',
];
// We assume there's a div .cart-random-products
//
var randomProductsToShow = [];
for ( var i = 0; i < 6; i++ ) {
var randomProductId = productIds[ _getRandomInt( 0, ( productIds.length - 1 ) ) ];
_getARandomProduct( randomProductId );
}
$('body').on( 'click', '.extra-productadd-btn', function( e ){
// Get the variant id of the product
var variant = $( this ).data('variant');
// Add a nice loading effect to button while the AJAX call runs
$( this ).addClass( 'btn--loading' );
// Call the function to add the product using ajax and reload the page on success.
addFreeGift( variant, 1, $(this) );
// So the button link doesn't do anything strange.
e.preventDefault();
});
});
}());
</script>
HTML is done, let's do some styling
/*This is it. I have made it mobile responsive too and gave it a slider kind of look so that it doesn't take a lot of vertical space on mobile screens.
* Add to Cart module for Checkout
*/
.checkout-add-cart-module {
padding: 0px;
background-color: transparent;
margin-top: 30px;
}
.checkout-add-cart-module > h4 {
font-size: 20px;
font-weight: 600;
margin-bottom: 15px;
}
.checkout-add-cart-module .checkout-add-products-list {
margin: 15px 0;
}
.checkout-add-cart-module .random-product-item {
padding: 5px 0px;
display: flex;
align-items: stretch;
}
.random-product-item .product-detail-col {
width: 50%;
padding: 5px 10px;
}
.random-product-item .product-detail-col .prod-title {
font-weight: 600;
color: #333;
font-size: 15px;
margin-bottom: 5px;
line-height: 1.4;
}
.random-product-item .product-detail-col .prod-price {
font-size: 13px;
font-weight: 600;
color: #333;
}
.checkout-add-cart-module .random-product-item .thumb-product-img {
width: 65px;
height: 65px;
border-radius: 5px;
position: relative;
overflow: hidden;
background-color: #fff;
border: 1px solid #eee;
}
.checkout-add-cart-module .random-product-item .thumb-product-img img {
width: 100%;
height: 100%;
object-fit: contain;
object-position: center;
}
.product-add-wrapper {
width: 25%;
display: flex;
align-items: center;
justify-content: flex-end;
height: 100%;
align-self: center;
position: relative;
}
.product-add-wrapper a.extra-productadd-btn {
color: #fff;
display: inline-block;
padding: 5px 20px;
background-color: #197bbd;
border-radius: 4px;
font-size: 12px;
font-weight: 600;
position: relative;
}
.product-add-wrapper a.extra-productadd-btn:hover {
background-color: #1c6495;
}
.product-add-wrapper a.extra-productadd-btn.btn--loading .btn-text {
opacity: 0;
}
@media ( max-width: 640px ) {
.checkout-add-products-list {
display: flex;
overflow-y: auto;
align-items: flex-start;
}
.checkout-add-cart-module .random-product-item {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
min-width: 175px;
}
.random-product-item .product-detail-col {
width: 100%;
text-align: center;
}
.product-add-wrapper {
width: 100%;
justify-content: center;
}
.checkout-add-cart-module .random-product-item .thumb-product-img {
margin: 0 auto;
}
.product-add-wrapper {
align-self: flex-start;
height: auto;
}
}
Where do I find help on this?
Fixing WordPress Website Infected by .ico Malware
More cases of WordPress websites being infected by .ico Malware are showing up and it is a difficult job to get rid of it completely and make sure site safe again, but it's not impossible.
I wrote an article on fixing this virus problem before and it is recommended you check it first, it explains how to get rid of the virus by manual process simply by finding the strange looking PHP files and the .ico files which are spread across different folders, it makes it very hard to find if you are not someone who deals with these sort of things on a regular basis.
Just recently multiple websites were again infected by this malware, which in all instances caused the website's to go down and returned error messages like "There has been critical error on your website."
What does the malware do?
What to do now?
Getting Rid of WordPress Malware (.ico Backdoor Malware)
In this post we talk about a malware that affects the site by injected malicious .ico files at random locations, as well as index.php files and code snippets in core WordPress files.
One of the sites that I manage was affected by this malware, first course of action was to look for the problem being faced by other people, this article came up which was one of the very few links online that discussed the issue we face:
https://www.getastra.com/e/malware/infections/favicon-ico-malware-backdoor-in-wordpress-drupal
As discussed this hack injects files with .ico extensions in different folders. These ico files contain malicious PHP code which does all of the malicious tasks it is supposed to do, one is to spread the malware and infect further files. Primary function of this malware is to redirect incoming traffic to some shady websites.
Steps that were taken
But did not work.I tried finding the root cause, where it came from, which plugin caused but it was not very clear. However, I decided to take some steps to clean it which was to look for .ico files on the server, because some core files like wp-config.php, index.ph, wp-settings.php had the code these @include.. PHP which referenced to the actual files I was able to search for its location by decoding the Unicode text.

Using FTP I found the files which were in a deep folder:

After removing it we believed the problem was solved, but 2 days later the same problem was back, this time the .ico file was added to a different random location and the code injected into different core files.
What Worked
- Make sure you have FTP access to your site, also take backup of your files (any customized theme, plugins etc.)
- Delete these folders completely:
wp-adminwp-includes - When you delete the folders, also remove core files in the root folder where files like wp-config.php, index.php etc. reside. Make sure to copy contents of wp-config.php file as it contains details of your server / database.
- Download WordPress files from here: https://wordpress.org/download/ - unzip it and place it somewhere on your system.
- Now one by one first upload the files using FTP that you deleted from the root folder, make sure to replace important content in wp-config.php file.
- Now, it is time for uploading the entire
wp-adminandwp-includesfolder back. Use your FTP software to upload all the files.
At this point all we can do is wait and see if the malware returns. In our case this method fixed the problem which makes it apparent that somewhere inside the core WordPress files the malware was injected and went unnoticed by security plugins like Sucuri and WordFence.
If you still face the issue even after trying this let us know in the comments.
Show A COVID-19 / Corona Virus Update Message on your Blogger Blog
In this quick tutorial I will quickly show a simple and efficient way to display a message on your blog / website hosted with Blogger. You do not need any coding experience, just basic knowledge of copy-pasting work.
<script type='text/javascript'>
var covid19msg = (function(){
/* Edit values here */
var covid19msg = {
'message': 'Hello readers, due to the COVID-19 outbreak you may see some delays in our regular updates. Kindly bear with us for the time-being.',
'background-color': '#333',
'text-color': '#fff',
'position': '' // set to 'fixed' if you want the msg to be displayed always
};
/* Don't edit anything below this */
var newElm = document.createElement('div');
var theMsg = covid19msg.message;
var fixedClass = '';
if ( covid19msg.position == 'fixed' ) {
fixedClass = 'msg-fixed';
}
var covid19html = '<div class="covid19-message '+ fixedClass +'"><div class="inner">'+ theMsg +'</div></div><style>.covid19-message { position: relative; padding: 20px; text-align: center; background: #333; color: #fff; } .covid19-message.msg-fixed { position: fixed; top: 0; left: 0; right: 0; z-index: 99; } .covid19-message { background-color: '+ covid19msg['background-color'] +';color: '+ covid19msg['text-color'] + '; }</style>';
newElm.innerHTML = covid19html;
var theBody = document.getElementsByTagName('body')[0];
theBody.insertBefore(newElm, theBody.firstChild);
});
covid19msg();
</script>
Copy this code and then go to your Blogger Dashboard -> Layout -> Add A Gadget on any area on the layout

Click on the plus sign next to the "HTML/JavaScript" widget

Now paste the code from above in the content area, and make sure the option on the top right shows "Rich Text", this means that we are currently in HTML mode.

We do not need to enter any title for the widget. Save it.
If you know a bit of JS coding you may be able to edit the configuration of the message by altering some variables in the code. In any case you will still want to edit the message that it shows, so before you save the code you can edit the message part in the code.
Solving "Preload key requests" point on PageSpeed for WordPress sites
Update 3rd Jan 2020 : Modified the code to support extra attributes like crossorin and type that is required for some other types of content such as Fonts file.
This tutorial is focused towards WordPress sites but the technique is same for any site, it's just a few lines of HTML that goes on top of the <head> of your website.
I won't discuss what's preloading a request is in detail but if you would like to know more check this out: https://web.dev/uses-rel-preload/
Note: There is another point that sounds very similar, it is "preconnect", it is for pre-fetching DNS that we know will be required. There will be another similar tutorial for that, so stay tuned.
It looks something like this in the PageSpeed report:

/*
* Preload the s**t out of Google
*/
function stramaxon_preload_requests_html() {
$preloadRequests = array(
array(
'as' => 'style',
'href' => '/wp-content/themes/example/style.css',
'type' => 'text/css'
),
array(
'as' => 'script',
'href' => '/wp-content/themes/example/main.js',
'type' => 'text/javascript'
),
array(
'as' => 'font',
'href' => '/wp-content/themes/example/font.woff2',
'type' => 'font/woff2',
'crossorigin' => 'crossorigin'
),
$linksHtml = '';
foreach ($preloadRequests as $val) {
$attrs = '';
foreach ($val as $key => $att ) {
$attrs .= $key . '="' . $att . '" ';
}
$linksHtml .= '<link '. $attrs .' rel="preload">';
}
echo $linksHtml;
}
add_action('wp_head', 'stramaxon_preload_requests_html', -100);
The above code will go into your theme's functions.php file. All you have to do here it add elements to the array
$preloadRequests and define the href and as value as required.Are you looking to solve another Google PageSpeed x WordPress problem? Let us know in the comments, we will be happy to write a blog post for that as well.
A Review of the Blogger App for Android
I have been away from Blogger and blogging for quite a while now, but just recently heard about the official Blogger app for Android, well, there was one some few years back but it was a nightmare from what I remember.
The new app looks sleek, the design blends with the roundish material design of the latest Android UIs, and overall looks very, dull. Yes, while other Google apps, like Gmail, Messages etc. are pretty useful in the kind of design and layout they possess Blogger doesn't.
For a Blogging app the design is bland, features that should be there on a blogging app are missing. It looks more like a note keeping app. Of-course you get a mobile optimized writing experience but you can do pretty much the same thing by visiting Blogger.com on your mobile browser.
While I think the app is a good step for people who are more comfortable with using apps for most of their work, it still isn't enough to urge a person from not using the desktop version of the platform on their mobile browser - after-all you trade scale of the site for a lot of features you need on a blogging app.
Google needs to do a lot more work on the app to make it look, feel and work like a real Blogger app and less like a note keeping app.
Multiple Descriptions Tab for Shopify Product Pages without any Apps
This is not very easily achievable in Shopify, unless you are ready to spend a lot of money on trying apps, and even then it doesn't always bring results and customization option you may have needed, other option left is to learn coding, but even if you are already a coder, it is not something you will do in a snap of a finger, you will need good planning of how things are going to work and then code it. Quite a tedious job.
Good news is that I have already done that, I did it for a Shopify site specifically but later found that with a few changes in my code I can make it available for everyone to use in their own.
A note to remember: While I have made this tutorial simple to understand for even non-coders to try it is still recommended not to proceed without at least taking up your theme's backup. Just in case.
Things you will need
- A theme that has jQuery added to it. Our custom code requires JavaScript cod that uses jQuery functions, so it is important we have it.
- Preferably a nice code editor, such as Sublime Text, it will make handling snippets of code easier.
Find the JS file
- Go to your Shopify admin panel
- Click on "Online Store" on the left pane
- Then on "Themes" under it
- Now on the theme preview section you will see a drop down button called "Action", click on it and choose "Edit Code"

vendor.js or script.js and maybe even main.jsFor me it was vendor.js, you will find those files below "Assets" section on the theme code editor

Open the files with .js extensions and look for mention of "jQuery" in the files, if you find it, it means you can append the custom code I am about to give you right into this file and it will work,.
The JS Snippet
/*
* product tab js
* @author: Deepak Kamat (https://stramaxon.com)
*/
$( document ).ready(function(){
var productDescriptionHTML = $(".product-single__description").html();
var toPutContentIn = "";
var productTabCount = 0;
$(".product-single__description > *").each(function(){
// Check if this is a tab
if ( $(this)[0].tagName == "P" && (/^--[a-zA-Z]+--$/.test( $(this).text() )) ) {
var tabname = removeHyphens($(this).text());
// Insert Product tab link
var dataTarget = "product-tab-" + myslugify( tabname.trim() );
var newLink = "<a href='#' data-target='"+ dataTarget +"'>" + tabname + "</a>";
$(".product-description-tabs .tabs-link-btns").append( newLink );
var newTabContent = "<div class='product-tab-content' id='"+ dataTarget +"'></div>";
$(".product-description-tabs .description-tabs-content").append( newTabContent );
toPutContentIn = dataTarget;
productTabCount++;
} else {
if ( toPutContentIn.length ) {
$("#" + toPutContentIn).append( $(this) );
}
}
});
if ( productTabCount ) {
$(".template-product .content-block").hide();
$(".product-description-tabs").show();
changeProductTabFocus( $(".product-description-tabs .tabs-link-btns > a").data("target") );
}
$("body").on("click", ".product-description-tabs .tabs-link-btns > a", function(e){
$(this).parent().find("a").removeClass("active");
$(this).addClass("active");
var thisTarget = $(this).data("target");
$(".product-description-tabs .description-tabs-content .product-tab-content").removeClass("active");
$("#" + thisTarget).addClass("active");
e.preventDefault();
});
});
function myslugify(text) {
return text.toString().toLowerCase()
.replace(/\s+/g, '-') // Replace spaces with -
.replace(/[^\w\-]+/g, '') // Remove all non-word chars
.replace(/\-\-+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, ''); // Trim - from end of text
}
function removeHyphens(str){
return str.replace("--", "").replace("--", "");
}
function changeProductTabFocus( target ) {
$("a[data-target='"+ target +"']").parent().find("a").removeClass("active");
$("a[data-target='"+ target +"']").addClass("active");
$(".product-description-tabs .description-tabs-content .product-tab-content").removeClass("active");
$("#" + target).addClass("active");
}
Copy the entire code and place it inside of a code editor or text editor program of your choice.
On line number 8 you will see this code statement:
var productDescriptionHTML = $(".product-single__description").html();The
.product-single__description is the class name selector for out existing product description container, it is important that we have it correct since this is where our code will fetch the original description text. Now in most themes .product-single__description is standard for the container of product description, but in case it is something different on your theme you may have to replace it with the class name of according to your theme.A bit of HTML now
<div class="product-description-tabs" style="display: none;">
<div class="tabs-link-btns">
</div>
<div class="description-tabs-content rte">
</div>
</div>
This is a barebone markup, no content, nothing, because the JS code we earlier installed will run on page load and fill it with the content.
Where to put it? You have to check the code in product-template.liquid / product.liquid and see where your description code is, under there you can place the above code and save it. I know the explanation is a little vague, but all themes may different in file names and it is not possible for me to have one common instruction for everyone, so you have to figure out, either with the help of an expert or yourself (contact me on depy45631@gmail.com if you want professional help at low costs.)
Styling of the tabs
.product-description-tabs {
padding: 20px;
margin: 20px auto;
}
.product-description-tabs .tabs-link-btns {
margin-bottom: 00px;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap;
border-bottom: 1px solid #eee;
}
.product-description-tabs .tabs-link-btns a {
position: relative;
display: block;
font-weight: 600;
padding: 10px 20px;
background-color: #fff;
color: #252f56;
border-radius: 5px 5px 0 0;
color: #333;
text-decoration: none;
margin-right: 10px;
}
.product-description-tabs .tabs-link-btns a:hover,
.product-description-tabs .tabs-link-btns a.active {
background-color: #eee;
}
.product-description-tabs .description-tabs-content {
background: transparent;
}
.product-description-tabs .description-tabs-content .product-tab-content {
padding: 20px;
border: 1px solid #eee;
display: none;
}
.product-description-tabs .description-tabs-content .product-tab-content.active {
display: block;
}
/* Theme 2 */
.theme-2.product-description-tabs .tabs-link-btns a {
background-color: transparent;
font-weight: 400;
margin: 0;
}
.theme-2.product-description-tabs .tabs-link-btns a:hover,
.theme-2.product-description-tabs .tabs-link-btns a.active {
font-weight: 700;
}
/* Theme 3 */
.theme-3.product-description-tabs .tabs-link-btns a {
background-color: transparent;
font-weight: 400;
margin: 0;
border-radius: 0;
margin-bottom: 10px;
background-color: #03a9f4;
color: #fff;
margin-right: 15px;
line-height: 1;
}
.theme-3.product-description-tabs .tabs-link-btns a span {
position: relative;
z-index: 1;
}
.theme-3.product-description-tabs .tabs-link-btns a:after {
content: "";
position: absolute;
left: 50%;
bottom: -5px;
width: 15px;
height: 15px;
background-color:#03a9f4;
transform: translateX(-50%) rotate(45deg) translateY(-5px);
opacity: 0;
transition: 0.1s all ease-in-out;
}
.theme-3.product-description-tabs .tabs-link-btns a.active::after,
.theme-3.product-description-tabs .tabs-link-btns a:hover::after{
opacity: 1;
transform: translateX(-50%) rotate(45deg) translateY(0px);
}
.theme-3.product-description-tabs .tabs-link-btns a.active {
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}
.theme-3.product-description-tabs .description-tabs-content .product-tab-content {
background-color: #fff;
border: 0 solid;
box-shadow: 0 12px 20px rgba(0,0,0,0.15);
padding: 20px 30px;
}
The CSS code can be added in any CSS file from the assets files in your theme code. Find a .css file, you will have to make sure that CSS file is the main CSS file for the theme or a CSS that is used in the theme, so that the CSS code does apply on the live site.
At the end of the found CSS file, paste the above code and save it.
Now in the CSS code I have given three themes that you can use, one is default, other two are theme-2 and theme-3, to change the look you will have to add a class name to the barebone HTML we added in the last step.
Theme 1 (Default):
<div class="product-description-tabs" style="display: none;">

Theme 2
<div class="product-description-tabs theme-2" style="display: none;">

Theme 3
<div class="product-description-tabs theme-3" style="display: none;">

Final step, formatting your description
The final step is to format your description text for your products so that the JS code can parse it and convert it into a tabbed element. And for that you do not have to do any coding there, all you have to do is write the description in a certain way, like this.--Details--Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent lacinia arcu lectus, vel varius eros porta in. Fusce in tortor tincidunt, interdum mauris ut, fermentum nunc.
--Additional Info--Curabitur nec lacinia odio, ut interdum risus. Quisque consectetur luctus diam et consectetur. Proin at nulla ligula. Quisque et urna leo. Donec eget turpis et diam sollicitudin iaculis. Phasellus sollicitudin ullamcorper sodales. Morbi laoreet ante at sapien pharetra, eu eleifend justo semper. Morbi nibh nibh, auctor et gravida eget, ornare eget nisi. Phasellus dictum volutpat pellentesque. Proin vitae tellus nec velit feugiat tincidunt eu sed dui. Vestibulum feugiat eros et porttitor dictum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Duis semper, leo sed maximus mattis, massa erat fringilla dui, in bibendum ante tellus id tellus.
--Another Tab--
Etiam vitae pharetra turpis, sed condimentum sem. Pellentesque gravida augue id justo ornare cursus. Donec vitae porta leo. Nam nec orci eu est fermentum consequat. Vestibulum mollis nisl et magna elementum, non semper turpis feugiat.
The text in the description editor will look like this. The tab title will be any text between -- -- for example --Details--
Anything below that and before the next line of text that matches the same pattern will become that tab's content.
Want help with setup? Let's talk!
Setting up InspectorControl with Color Selection in Gutenberg | Gutenberg Series
This tutorial however is not about creating blocks, I assume you have already created a block and now are looking to add option for the user to control color of something in your block, for e.g the background or text color.
I will write an article on creating an editable Gutenberg block from scratch using the best practices.
I started off with a very simple block, it has a block of text, just that, I also added predefined styles using the `styles` option, but I wanted the user to have extra control on how the block should look and so I wanted to add color selection option and reflect what they chose on the block, both on the editor and the front-end. Due to lack of documentation and guides on Gutenberg it took me a while to figure out how to do it correctly, but here we are. So let's start.
A few things to note:
- I am using ESNext, it's just easier to write JSX in it, however if you know JS well you might already know how to convert an ESNext code to good 'ol JavaScript.
- Also, this site uses some ancient syntax highlighter so bear with me until I get a new one.
Get the dependencies first
const {
InspectorControls,
PanelColorSettings,
ColorPalette,
} = wp.editor;
Then from wp.components get these:
const {
PanelBody,
PanelRow,
} = wp.components;
It's not very crucial for the whole color setting thing but still a good practice to get these components in order to make the inspector control look cleaner.
InspectorControl can be anywhere
Since it is something that appears in the sidebar and not as part of the content of block it doesn't matter where we place it in the code, it can be anywhere inside of the main wrapper of the block. Do note it goes inside of `edit` function of your block though.I personally prefer assigning the JSX to a constant / variable and then use it conveniently in the `edit` function. So here's the code for outputting a simple color selection in the Inspector Controls.
const myInspectorControls = (
<InspectorControls>
<PanelBody>
<PanelColorSettings
title={ __( 'Block Background Color' ) }
colorValue={ blockBackgroundColor }
initialOpen={ false }
colorSettings={ [ {
value: blockBackgroundColor,
onChange: onChangeBackgroundColor,
colors: backgroundColors,
label: __( 'Choose a background color' ),
} ] }
>
</PanelColorSettings>
</PanelBody>
</InspectorControls>
);
That's it. You are done. Have a good one!
No, I am not leaving you in the middle, if you want help with understanding the code and also seeing an example `save` and `edit` function then read on.
What's going on? The tag <InspectorControl> defines the, of course, inspector controls, <PanelBody> is just a container component to contain our various settings.
<PanelColorSettings> is the real deal. It's the editor component that is responsible for bringing up the color selector and as you can see it contains quite a lot attributes, so let's go through it as well.
- title: The title is what shows up as the control's title.
- colorValue: This is important one, you assign to it the value, i.e the color it will have. `{ blockBackgroundColor }` is the attribute that's been set-up when registering the block (we will come back to it later, if you do not understand how it will work then keep on reading.)
- initialOpen: boolean, whether the panel should be open by default.
- colorSetting: it is an array of objects with four keys namely value, onChange, colors, and label
value: The same color value blockBackgroundColor
onChange: callback when the color is changed
colors: This takes an object of color names and hex values and shows it on the color settings before the color picker. So you can show a few preset of colors if you want.
Now there can be multiple colorSettings in the array.
Let's see how we can make use of the new Inspector control we just added. First step is to declare an attribute for the block that will hold the value of the selected color as a string, we will name it blockBackgroundColor
attributes: {
blockBackgroundColor: {
type: string,
default: '#000' // is optional
}
}
And then bring that in your edit function
edit ( props ) {
const { attributes: { blockBackgroundColor }, setAttributes } = props;
// other code..
Remember we set onChangeBackgroundColor to the onChange event? So let's create that as well.
function onChangeBackgroundColor( newBackground ) {
setAttributes( { blockBackgroundColor: newBackground } );
}
Cool. Now we have a working inspector control that you can use to choose a color. However, it's of no use if you are not applying the selected color somewhere. Let's take a look at a simple example on using the selected color in both the edit and save function.
edit( props ) {
// all the other codes...
const myInspectorControls = ( <InspectorControls>...</InspectorControls> );
return(
<div
className="my-simple-block"
style={
{
backgroundColor: blockBackgroundColor
}
}>
{ myInspectorControls }
<RichText/>
</div>
);
}
save( props ) {
return(
<div className="my-simple-block"
style={
{
backgroundColor: props.attributes.blockBackgroundColor
}
}>
// something
</div>
);
}

I have just uploaded a very simple Gutenberg block's plugin code that registers a block with color settings, you can find it here StramaXon Gutenberg Blocks
Stay tuned for more Gutenberg blocks tutorial, also let me know tutorial around which aspect of Gutenberg Blocks you want to see next, on my to-do list I have Alignment toolbar setting so do subscribe to get notified when it comes out.
Redirecting HTTP to HTTPS in Magento 2 for Bitnami AWS Stack
This guide is for advanced users who are comfortable working with core configuration files and knows how to access, edit and save these files. If you are a general user and looking to achieve the results then I would recommend you to hire a professional who can help you do it.
Coming back to the problem, so the site was accessible from both the insecure (http://) and secure (https://) protocol independently, however we intended the behavior to be such that going to the insecure URL should redirect to the secure one - unfortunately for some reasons Magento 2 doesn't provide that option in the Admin's settings.
I had to dig very deeper and had to try with multiple .conf files to finally find the one that actually work, but before that's let get an overview of the situation.
Bitnami's Official Documentation Didn't Help
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]
And then restarted Apache server using:
sudo /opt/bitnami/ctlscript.sh restart apacheHowever, that didn't resolve the issue. One thing was obvious that it has to be one of the .conf or .htaccess files where I needed to add this. The next section will describe how.
The .conf file that worked
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]
</IfModule>
And save. Now use the command to restart the Apache server, now to test the site, do that in an Incognito window so you are not confused by cached pages.
This worked for me, and I hope it does for you as well, if you are facing an issue please do let me know in the comments.
Add Happy New Year Message to your Blog 2018
Let's put a smile on everyone's faces who visits your blog by wishing them a happy new year when they open your website up for the first time.
We've created a small set of photos that you can add to your Blogger blog using a few lines of HTML, CSS and JavaScript code, no coding knowledge required, you have have to know the basics of editing HTML templates. All you are going to do is basic copying-pasting.
The new year is just hours away so without wasting much time let's get on with the tutorial.
Before we begin, here's a quick demo of what you will be adding: Demo Hosted on JSBin
The code that you need
The new message is basically an image that is shown interactively using JavaScript and the way it is displayed using CSS as well. The entire code here is a mixture of HTML, CSS and JavaScript code.Copy the code:
<div class="new-year-message" id="stramaxon_new_year_message"></div>
<style>
.new-year-message {
display: none;
opacity: 0;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .5s all ease-in-out;
z-index: 99999;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-attachment: fixed;
background-image: url("https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizdj3FJait56mKMFM_iTeNZYt4jfI4Cqyx9ZG4TtdS16zwaYVyJ96MoIeuuH9Mr5a-DCkabCQUPJPveTIjqfZ6qVrx7E0DMS1kgj0Vwn6lVHZB4ih_REe-icnX6lCPJj-PCTFPy91DjKeA/s1600/happy-new-year-3-t.jpg");
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function(){
var seconds = 5; // Number of seconds you want the message to be visible
var show = true;
var message = document.getElementById("stramaxon_new_year_message");
// Check if the message has been shown before
if ( window.localStorage ) {
if ( !localStorage.getItem("stramaxonNewYearMessage") ) {
show = true;
}
else {
show = false;
}
}
// Show and click to close
if ( show ) {
_fadeIn( message );
setTimeout(function(){
_fadeOut( message );
}, seconds * 1000 );
if ( window.localStorage ) {
localStorage.setItem("stramaxonNewYearMessage", "shown")
}
}
else {
// don't show
}
message.addEventListener("click", function(){
_fadeOut(this);
});
});
function _fadeOut(el){
el.style.opacity = 1;
(function fade() {
if ((el.style.opacity -= .1) < 0) {
el.style.display = "none";
} else {
requestAnimationFrame(fade);
}
})();
};
function _fadeIn(el, display){
el.style.opacity = 0;
el.style.display = display || "block";
(function fade() {
var val = parseFloat(el.style.opacity);
if (!((val += .1) > 1)) {
el.style.opacity = val;
requestAnimationFrame(fade);
}
})();
};
</script>
Add it to your blog
- Log-into your Blogger dashboard
- On your blog's dashboard, go to the Layout section
- In the sidebar or a footer section, you may see "Add a Gadget" link, click open it
- In the list of gadgets you will find "HTML/JavaScript" to add it click on the plus icon next to it.
- You will now see a text-box under "Content", this is where you have to paste the copied code. Leave the "Title" field empty since we do not want the widget box to be apparently visible on the blog.

- Hit "Save" and that's it.
I want a different image
- In the code that you pasted in the HTML/JavaScript gadget, find the following line
background-image: url("https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizdj3FJait56mKMFM_iTeNZYt4jfI4Cqyx9ZG4TtdS16zwaYVyJ96MoIeuuH9Mr5a-DCkabCQUPJPveTIjqfZ6qVrx7E0DMS1kgj0Vwn6lVHZB4ih_REe-icnX6lCPJj-PCTFPy91DjKeA/s1600/happy-new-year-3-t.jpg"); - As the name suggests it tells the browser which image to load. The URL inside url() is the link to the image we are using. All you have to do is replace it with the URL of the image you would like to use.
- Copy full-size image address (default)
- Copy full-size image address
- Copy full-size image address
- Copy full-size image address
Why I don't see it?
- Either JavaScript is disabled in your browser. To fix it please look for ways to enable JavaScript in the browser you are using.
- In case you only were able to see it for the first time you loaded your blog and it doesn't show up after that, then it is not a problem, as the message is set to display only once for a person. You do not want to obstruct a reader's experience every time they visit a different page on your blog with the same message banner. If you just want to check how it looks then fire up a Incognito or Private browsing mode in your browser and load the blog.
New Year, A New Beginning for StramaXon and Me
Over these years many things changed, the blog itself went through a lot of make-overs. The content however remained pretty much same in nature - to share the knowledge I have with you all.
Starting with Blogger, I stepped into even broader topics, like web design itself though I always wanted this blog to be only about one topic but I soon found out it was neither wise nor good for the blog itself.
Many tutorials were posted on this blog, everything about Blogger. In the past couple of years, I however failed to write much, a lot of things kept me occupied, academic and work related as well as personal reasons.
I was unable to do for most of the part during the last couple of years and that was to write blog posts here. Somewhere during that time I wanted to start writing blogs again but I was too busy on web development / designing work I had forgot what Blogger was (not in its literal sense!), to be able to write about something you had to be consistent in using that, finding out what needed to covered, but I was unable to do so and that resulted in many many months of no blog posts.
Though, that's the story of past, a new year is awaits. We all know new year's resolutions don't turn out to be great as always, though in this case my new resolution is about something that I love - to write blogs and help people, and this is what I am going to do in 2018 and so on.
Most of the subscribers and readers of the blogs came here for Blogger related topics, and I am going to continue with Blogger and I am sure you will also love the content on topics ranging from Blogger to App Development. If you are a reader of this blog you may know that my blog posts even related to coding are very simplified and aimed at non-coders and that's what it is going to be with the new categories on the blog.
I hope you find my blog useful and find something new to learn. A lot of new content is coming and with it a new look for StramaXon!
Wish you all a very happy new year in advance.
Deepak Kamat
Trouble Adding AdSense Code for Page-Level Ads? Learn how to fix it.
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"/>Unfortunately if you have tried placing the code in your theme you may have run into this error that states:
Error parsing XML, line n, column n: Attribute name "async" associated with an element type "script" must be followed by the ' = ' character.
That's a bit annoying - What could be going wrong with the code that AdSense (a Google product) has provided is causing error on Blogger (another Google product).
The problem is highlighted in the error message itself "Attribute name "async" associated with an element type "script" must be followed by the ' = ' character."
Attribute name "async" in the code we got must be followed by a '=' character. But the code we got simply has
<script async ... />So what can be done? Modify the code to be parsed by Blogger's theme parser correctly. Here's the code with a little change, we replaced async with async="async" to make the code a valid XHTML markup.
<script async="async" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
Place this code in your Blogger theme code and save. It should work properly now.
Why do we have to use this "hack"?
Will it have any impact on the way this code is supposed to work?
Inviting All Friends to Facebook Page at Once JavaScript Snippet
It can be a hefty job clicking on thousands of "Invite" buttons one after one since Facebook doesn't give you an "Invite all" button. Same used to be true for Group requests but fortunately it now does, but as for Facebook page invites you still have to do the manual way.
In this tutorial we will be learning how to invite all friends to page on Facebook automatically. In the past on our blog we posted some similar codes for Facebook but as you know Facebook changes it design and structure so not all the old codes may still work.
This one is latest and is working (created in June 2017).
We will keep this short, there's only two step mainly, copy the code and paste it, but to perform it successfully we have to do more than just that.
Copy the JavaScript Code
var btns = document.querySelectorAll("button");
var i = 0;
setInterval(function(){
if ( btns[i].textContent == "Invite" ) {
btns[i].click();
console.log( i + " buttons clicked." );
}
i++;
}, 200);
Open Facebook on Desktop in Chrome / Mozilla Firefox or Safari
In the browser open JavaScript Console and Paste the Code
- Google Chrome: CTRL+Shift+J (CMD for Mac) OR Right click on page > Inspect > Console tab
- Safari: Safari > Preferences, click Advanced, then select “Show Develop menu in menu bar.”. Now in the Safari Develop menu select "Show JavaScript Console"
- Firefox: CTRL+Shift+J (or CMD+Shift+J on a Mac) ORselect "Browser Console" from the Web Developer submenu in the Firefox Menu (or Tools menu if you display the menu bar or are on OS X)
Does it have a limit?
Why shouldn't I use an extension?
- You never know what the extension might be running in the background
- Such extensions are known to go rogue and show pop-up ads in the future
- Do you really need to install a forever running extension for a small task ?
I see an error
Full Sized Background Image on Blogger with Blur Effect
Looking to add a nice effect to your blog by using beautiful pictures as background images? It is a great way to personalize a blog, depending on the color scheme of your blog and the feel that you want the blog to have can all be improved by using an image as the full background.

This tutorial will be guiding you through the process of setting a custom full size image on your Blogger blog with a few lines of CSS as well as showing a way to give it a blurred glass effect.
Here's a quick demo of what you are going to have on your blog by following the steps to add the CSS to your blog: Full Page Background Image Blurred Effect using CSS
Uploading the image
- Open a draft post in your Blogger dashboard
- Upload the image
- When the image appears in the post area, right click on it and "Copy image address" or "Copy link address", the option might be different on different browsers.
- Paste the copied URL that is the image's address in a Notepad / Textedit app. We may get something like this
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyrajfadQBUo8BooKtb2RHwsSG3DsiDCrVtBHEkAVqP6zcdTmtcmXJ3XQiBo1B0WO6AaeyLOljOpRaaaabRAbD4Y0jnfBmq6pY9TZrb9z0v7pIaWucvuvajBbg2KiWedjLR5pDoqAC9xy2/s1600/photo-1434394673726-e8232a5903b4.jpg - Keep it with yourself, we will need this in the next step.
The CSS Snippet
html, body {
background: url('IMAGE-URL-HERE') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
Copy the CSS code and paste it in another Notepad / Textedit window.
In this code, replace IMAGE-URL-HERE with the image URL we got in the last step.
html, body {
background: url('https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyrajfadQBUo8BooKtb2RHwsSG3DsiDCrVtBHEkAVqP6zcdTmtcmXJ3XQiBo1B0WO6AaeyLOljOpRaaaabRAbD4Y0jnfBmq6pY9TZrb9z0v7pIaWucvuvajBbg2KiWedjLR5pDoqAC9xy2/s1600/photo-1434394673726-e8232a5903b4.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
I've done it, what now? Now that you have placed your image's URL in the code we are ready to make it appear on the blog. but before that please do take a backup of your existing blog theme.
- Log-into your Blogger Dashboard
- Go to the Theme
section - Click on "Customize"
- In the Theme Designer go to Advanced > Add CSS
- Paste the CSS snippet into the text area on the theme designer page and click on Apply to Blog on the top right
Let's give it a blurred effect
We assume you are still in the Advanced > Add CSS page in the Theme designer from the last step. A small change in the URL of the image is required to get the blurred effect - that is to reduce the size of the image. Yes, the smaller the image the more blurry it will be. So that's our general idea, instead of using a photo editor app to make the original image blurry we use a small version of the original image.
Let's suppose your code is this, the URL of your image is of course different than the one in the following one.
html, body {
background: url('https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyrajfadQBUo8BooKtb2RHwsSG3DsiDCrVtBHEkAVqP6zcdTmtcmXJ3XQiBo1B0WO6AaeyLOljOpRaaaabRAbD4Y0jnfBmq6pY9TZrb9z0v7pIaWucvuvajBbg2KiWedjLR5pDoqAC9xy2/s1600/photo-1434394673726-e8232a5903b4.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
In the URL of your image, which may look something similar to this:
https://3.bp.blogspot.com/..............ynOTNfQCKgB/s1600/photo-1434394673726-e8232a5903b4.jpgChange the number with the s prefixed to it to something smaller.
https://3.bp.blogspot.com/..............ynOTNfQCKgB/s32/photo-1434394673726-e8232a5903b4.jpgs32 means the CSS code will load a version of the image that is only 32 pixels wide, so when a small image stretches from edge to edge on a screen it becomes blurry and gives the perfect effect we want.
You can change the value to whatever you like to adjust the level of blurriness of your background image. Change that small part in the code and again click on Apply to Blog to update the CSS code and make it go live on your blog.
Help Needed?
On some third-party themes and even the original themes provided by Blogger the code may not work properly due to some other CSS setting that may be overriding it. If you are unable to get it working then please share your blog URL in the comments down below along with the code that you are using as it is. We would be glad to jump in to help.Full Blog Posts on Notable Theme's Homepage in Blogger Blogs
There is no setting to make the theme show full posts on the home, index and archive pages and that is why we feel the need of writing this tutorial.
Previously on StramaXon we published a tutorial to show how it was done on Contempo theme, this tutorial will guide you through the steps to achieve the same with Notable theme, so if you are a Notable Theme user in Blogger then follow the steps given below to get your blog posts to show up as full.
Important: As with all of our tutorials where we are supposed to touch the theme code it is highly recommended that you take a backup of your current Blogger theme.
Video walk-through.
Link to the video tutorial.
Editing the XML / HTML Code in Theme
- Open a new tab in the browser and Log-into your Blogger Dashboard
- Go to the Theme
section - Click on "Edit HTML"
- When the Theme code editor opens, focus into the code editor and hit CTRL + F / CMD + F to open the in-page search
- Look for the following line of code|
<b:include cond='data:this.postDisplay.showSnippet ?: true' data='post' name='postBodySnippet'/>
- Upon searching you will get the result like this,

- Copy the following HTML / XML markup
<b:if cond='data:widget.type != "PopularPosts"'>
<div class='post-body-container'>
<b:include data='post' name='postBody'/>
<div class='post-sidebar invisible'>
<b:with value='data:widget.instanceId + "-normalpostsidebar-" + data:post.id' var='sharingId'>
<b:include cond='data:post.shareUrl' data='{ shareButtonClass: "post-share-buttons-top", overridden: true }' name='maybeAddShareButtons'/>
</b:with>
<b:if cond='data:post.labels and !data:post.labels.empty and data:this.allBylineItems.labels'>
<div class='post-labels-sidebar'>
<h3><data:messages.labels/></h3>
<b:include data='post' name='postLabels'/>
</div>
</b:if>
</div>
</div>
<b:else/>
<b:include cond='data:this.postDisplay.showSnippet ?: true' data='post' name='postBodySnippet'/>
</b:if> - Go back to the theme editor where we previously found the line of code from step 5. Replace that line of code with the code you just copied. This is what it the XML code should look like when you have replaced it.

- Now click on "Save theme" to save the changes and go to your blog to see the change. The posts should now appear full on all the pages.
You may have noticed that the "Read More" button is still there even though the post shows up full, it's because the Jump link is added by another code that we didn't touch yet and it isn't even necessary, we will be using CSS to simply hide the links.
CSS to hide the Jump Link
.widget.Blog .jump-link {
display: none;
}Here's a complete guide with screenshots on adding CSS in Blogger blogs
- Log-into your Blogger Dashboard
- Go to the Theme
section - Click on "Customize"
- In the Theme Designer go to Advanced > Add CSS
- Paste the CSS snippet into the text area on the theme designer page and click on "Apply to Blog" on the top right











