Aleksandar Krstic

Personal Blog

How to create subdomain on NGINX server

In order to create subdomain with NGINX server please follow these steps:

* – used in this article need to be replaced with your domain
** – used in this article need to be replaced with your desired sub-domain

1. Add subdomain in domain configuration provided by your domain provider

Only thing you need is IP address of your hosting which you get by running the following command:


In response you will see IP address (for purpose of this article we will consider it as, which you need to add in DNS manager for your domain as “A” record, and that should look similar to this (godaddy example)

Per example that we use in this article name should be “subdomain”, and Value should be “”

2. Create folder under you main www folder called per your wanted subdomain


3. Create config file with the following command

nano /etc/nginx/sites-available/

Enter the following lines

server {
listen 80;
root /var/www/;
index index.html index.htm index.nginx-debian.html;
location / {
try_files $uri $uri/ =404;

*this is very basic configuration for http. There are a lot of options dependably on what your needs are (https, certificates, ….).

4. Enable configuration by linking it to sites-enabled folder

ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

5. Nginx reload

service nginx reload

*Reload is enough for changes to apply (without downtime), no need for restart.

Laravel 5 – Display nested relations in View without Eloquent

In case that you need to display nested relations in a View, Laravel offers Eloquent.

This approach is well known and well documented in official Laravel Documentation.

So, we will play with different approach here.

First of all, what are nested relations?

We can use example with projects and tasks where you want to display all projects with their tasks.

Something like:

Project 1
Task 1
Task 2

Project 2
Task 3
Task 4

How to achieve this?

Step 1. Create function which will retrieve data from DB in your Controller
It’s usually something like app/Http/Controllers/YourController.php

    public function getProjects(){
        $data['data'] = DB::table('projects')
                        ->join('tasks', '', '=', 'tasks.project_id')
                        ->select(' as pname', ' as pid', DB::raw('group_concat( SEPARATOR "<br>") as tid'), DB::raw('group_concat( SEPARATOR "<br>") as tname'))
        return view('project-list', $data); //view where we will use this data

First two lines of query are pretty much strait forward – it’s a simple join of two tables (projects and tasks).

In line with select part you can notice the following:

DB::raw('group_concat( SEPARATOR "<br>")

This is standard Laravel way to achieve MySQL GROUP_CONCAT.

Why we need this? We need it in order to group tasks by Project. Otherwise, we will get something like:
Task 1
Task 2
Task 3
Task 4



we will replace standard “,” separator with “new line” tag, just to look nicer.

Of course, we also need groupBy, and as I mentioned, we want to group it by Project (or better to say by Project’s ID).

Step 2. Routing
It’s usually in routes/web.php

Route::get('/project-list', 'YourController@getProjects');

Here we basically connect function with our View called “project-list”.

Step 3. Create View and display data
Views are usually under resources/views, and in that folder we will create project-list.blade.php in order to display data with standard foreach loop.

foreach ($data as $value) {
	echo "<div class='project-list-out'>";
	echo "<table class='project-list'>";
	echo "<tr>";
	echo "<td>" . $value->pname . "</td>";
	echo "</tr>";
	echo "</table>";

	echo "<table class='task-list'>";
	echo "<tr>";
	echo "<th>ID</th><th>Task Title</th>";
	echo "</tr>";
	echo "<tr>";
	echo "<td>" . $value->tid . "</td><td>" . $value->tname . "</td><td>";
	echo "</tr>";
	echo "</table>";
	echo "</div>";

As a conclusion, I would suggest usage of Eloquent as you primary option, but in case that for some reason, that is not an option for you, this approach can do the trick.

PHP console log – The easiest way

PHP console log – The easiest way is to use JavaScript inside PHP, and that can be done with the simple trick.

$str = "Cars";
$arr = array("Volvo", "BMW", "Saab");

echo("<script>console.log('Log: ".$str."');</script>");
echo "<br>";
echo("<script>console.log('Log: ".json_encode($arr)."');</script>");

You will probably notice the difference between 2 logs. One have json_encode, another doesn’t. There is no need to use it when we want to log a string, but when we want to log an array, we need it, because otherwise it will just log information that you dealing with array(s), without values.

Example with json_encode.

PHP console log

Without json_encode.

PHP console log

MySQL Union with Order By

When you execute commands that contains UNION and ORDER BY in MySQL like this one:

(SELECT col1 FROM tab1 WHERE ... ORDER BY col1 ASC) 
(SELECT col1 FROM tab2 WHERE ... ORDER BY col1 ASC);

you expect to get col1 from tab1 (ordered ascending by col1) “joined” with col1 from tab2 (ordered ascending by col1).

And in some cases you will get the desired rusult, but in some situations query execution will ignore ORDER BY in both SELECT statements.

I think that depends on version of mysql server, which is used. In my case it doesn’t work on Linux Server – MariaDB 10.0.25, but it works on MAMP’s MySQL – 5.6.35.

Anyway, the only way to make sure that ORDER BY will work for all SELECT’s in UNION, is simply to add LIMIT.

So, the example from above should look like this:

(SELECT col1 FROM tab1 WHERE ... ORDER BY col1 ASC LIMIT 10) 
(SELECT col1 FROM tab2 WHERE ... ORDER BY col1 ASC LIMIT 10);

This is the official explanation from

“Use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows. Therefore, the use of ORDER BY in this context is typically in conjunction with LIMIT, so that it is used to determine the subset of the selected rows to retrieve for the SELECT, even though it does not necessarily affect the order of those rows in the final UNION result. If ORDER BY appears without LIMIT in a SELECT, it is optimized away because it will have no effect anyway.”

Hope that this article helped with this, at least for me, unusual problem.

Magento 2 – Cookies with JavaScript

This article is basically follow up on previous one.

There I talked about popup/sliding panel handling, but if you want to improve that with cookies usage (for example, to auto-load popup just once per session or similar …) here you can find some useful tips.

In Magento 2 you can achieve that with PHP or JavaScript (jQuery, mage/cookies, js-cookie, …)

From what I have experienced, the best way is with the js-cookie plugin (inheritor of jQuery Cookies which is “retired” from 2015).

Why not PHP?
PHP approach cannot be implemented in custom block from Magento backend, and JavaScript can through require.js.

Why not jQuery Cookies plugin?
As I mentioned, it’s retired from 2015, and people who worked on it continued the job on js-cookie plugin. Beside that, cookie retrieving not working anymore (at least for me).

So which one?
That plugin can be found here –

Only file that you need is –

So, steps for the implementation are:

1. Place js.cookie.js in \lib\web
2. Run Static Content Deploy command – php bin/magento setup:static-content:deploy
3. Go to place where you want to use js-cookie and call it.

        function($, Cookies) { …. }

Set cookie – Cookies.set(‘name’, ‘value’, { expires: 30 }); // expires in 30 days
Get cookie – Cookies.get(‘name’); //returns value
Remove cookie – Cookies.remove(‘name’);

Complete documentation can be found here

Updated code from the previous article now looks:

<script type="text/javascript">
        function($, modal, Cookie){
            var options = {
                type: 'popup', // there is also a slide type. By default sliding from the right.
                responsive: true,
                innerScroll: true,
                buttons: [{
                    text: $.mage.__('Close'),
                    class: '',
                    click: function () {
            var popup = modal(options, $('#popup-modal'));
            //Popup appears on winodow load only once in session
            $( document ).ready(function() {
                    var cookieGet = Cookies.getJSON('amishown');
                    if (cookieGet === null || cookieGet === undefined){
	            var cookieSet = Cookies.set('amishown', 'shown');