<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Perl / Mojolicious Archives | The Curious Technoid</title>
	<atom:link href="https://thecurioustechnoid.com/category/perl/feed/" rel="self" type="application/rss+xml" />
	<link>https://thecurioustechnoid.com/category/perl/</link>
	<description>technology made simple</description>
	<lastBuildDate>Fri, 16 Sep 2022 04:29:49 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.5</generator>

<image>
	<url>https://thecurioustechnoid.com/wp-content/uploads/2020/06/cropped-fav-1-32x32.png</url>
	<title>Perl / Mojolicious Archives | The Curious Technoid</title>
	<link>https://thecurioustechnoid.com/category/perl/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>WebSockets using Mojolicious</title>
		<link>https://thecurioustechnoid.com/websockets-using-mojolicious/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=websockets-using-mojolicious</link>
					<comments>https://thecurioustechnoid.com/websockets-using-mojolicious/#respond</comments>
		
		<dc:creator><![CDATA[Rakshith Chengappa Mullengada]]></dc:creator>
		<pubDate>Sun, 09 May 2021 06:59:33 +0000</pubDate>
				<category><![CDATA[Perl / Mojolicious]]></category>
		<category><![CDATA[mojolicious]]></category>
		<category><![CDATA[mojolicious web sockets]]></category>
		<category><![CDATA[websockets]]></category>
		<guid isPermaLink="false">https://thecurioustechnoid.com/?p=583</guid>

					<description><![CDATA[<p>Most of the websites you find on the web today are mostly built on the concept of request-response. User clicks a link / button on the webpage, browser sends a request to the server, server sends back the relevant content. This works just fine for most of the websites out there. But imagine a scenario&#8230;</p>
<p>The post <a href="https://thecurioustechnoid.com/websockets-using-mojolicious/">WebSockets using Mojolicious</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></description>
										<content:encoded><![CDATA[


<p class="has-drop-cap">Most of the websites you find on the web today are mostly built on the concept of request-response. User clicks a link / button on the webpage, browser sends a request to the server, server sends back the relevant content. This works just fine for most of the websites out there. But imagine a scenario where you are constantly showing stock prices in your website. User(Client) will not request(click on) anything however, the server should keep sending the latest stock prices. To achieve this, traditionally websites relied on techniques like HTTP long polling where in the server holds any request until new content is available and once available, it sends it to the client, client then immediately sends another request which is held by the server until new content is available, this is repeated practically forever or until the session ends. This, as you can see adds severe burden on the server.</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://youtu.be/8Dt5bH4mZ0Q"><img decoding="async" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/WatchOnYoutubeImage.png" alt="" class="wp-image-78" width="217" height="87"/></a></figure></div>



<p>WebSockets overcomes the above problem by providing full-duplex bidirectional connection between client and server which enables servers to send data to client without the need for client to request for it. Few examples where WebSockets are useful are chat, website displaying stock market prices, website showing game scores etc.</p>



<p>In this article, let us try to implement a simple group chat application to demonstrate WebSockets. We will be using Mojolicious Web Framework here. Mojolicious has WebSockets support by default which makes it quite easy to implement this.</p>



<p>We will keep our chat application simple with the below features:</p>



<ul class="wp-block-list"><li>Users should be able provide their name and connect to the chat application</li><li>Messages sent by any user should be available to everyone connected to the chat application</li><li>Users inactive for 5 mins should be automatically disconnected from the chat application</li></ul>



<h2 class="wp-block-heading">Server-Side Logic</h2>



<p>For the purpose of this demonstration, I will use <em><a href="https://thecurioustechnoid.com/mojolicious-intro-hello-world/" target="_blank" rel="noreferrer noopener">Mojolicious lite app</a></em>. Let us go ahead and create our application using the below command:</p>



<pre class="wp-block-code"><code>mojo generate lite_app simpleChatApp</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="638" height="203" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.23.34.png" alt="" class="wp-image-586"/></figure></div>



<p>Let us now write a route to handle any websocket requests. In Mojolicious you use the <em><strong>websocket</strong></em> request to do that. We will also set a timeout of 5mins so that any user not active for more than 5mins gets automatically disconnected. We will store all the connected user information in a hash(%users) so that we can broadcast any new message to everyone.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img decoding="async" width="706" height="217" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.24.42.png" alt="" class="wp-image-591"/><figcaption>Check out the complete source code <a href="https://github.com/curioustechnoid/MojoWebsockets/blob/main/simpleChatApp" target="_blank" rel="noreferrer noopener">here</a></figcaption></figure></div>



<p>Once the user is connected, any new message sent by any user needs to be broadcasted to all the users that are there in the %users hash. We will parse the pipe delimited message received from the user which will have the name and the message(we will add this logic in the HTML template in the next section). We will append the current time and send all the information in JSON format to all the connected users (%users).</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="782" height="467" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-11.00.44.png" alt="" class="wp-image-593" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-11.00.44.png 782w, https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-11.00.44-768x459.png 768w" sizes="auto, (max-width: 782px) 100vw, 782px" /><figcaption>Check out the complete source code <a href="https://github.com/curioustechnoid/MojoWebsockets/blob/main/simpleChatApp" target="_blank" rel="noreferrer noopener">here</a></figcaption></figure></div>



<p>If the users disconnects or time-out occurs, we will remove the user from our hash so that new messages are not sent to them.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="717" height="167" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.25.16.png" alt="" class="wp-image-594"/><figcaption>Check out the complete source code <a href="https://github.com/curioustechnoid/MojoWebsockets/blob/main/simpleChatApp" target="_blank" rel="noreferrer noopener">here</a></figcaption></figure></div>



<h2 class="wp-block-heading">Client-Side Logic</h2>



<p>Now that we have our server side logic in place, time to write client side logic. Javascript has APIs which can be used to connect to server via websockets. We will be using that here.</p>



<p>First, we will have to connect to server via websocket either when the page loads or on some user action. In our case, we will give a button to the user to connect to the server by providing his name; when that button is clicked, we call the below code to connect to the webserver and display a message saying <em>Client Connected</em>. We have HTML elements to display the messages and capture the user inputs. You can check the complete source code <a href="https://github.com/curioustechnoid/MojoWebsockets" target="_blank" rel="noreferrer noopener">here</a>.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="705" height="171" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.26.31.png" alt="" class="wp-image-595"/><figcaption>Check out the complete source code <a href="https://github.com/curioustechnoid/MojoWebsockets/blob/main/simpleChatApp" target="_blank" rel="noreferrer noopener">here</a></figcaption></figure></div>



<p>Once the connection is established, whenever the user sends a new message, we append his name with the message he has typed and send it to the server delimited by pipe(you should ideally be using JSON or something!).</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="883" height="62" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.27.15.png" alt="" class="wp-image-597" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.27.15.png 883w, https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.27.15-768x54.png 768w" sizes="auto, (max-width: 883px) 100vw, 883px" /><figcaption>Check out the complete source code <a href="https://github.com/curioustechnoid/MojoWebsockets/blob/main/simpleChatApp" target="_blank" rel="noreferrer noopener">here</a></figcaption></figure></div>



<p>When anyone sends a message (including the user himself), the message which is broadcasted by the server will be captured, parsed and displayed on the chat window. Chat window is a HTML text area, you can check the source code <a href="https://github.com/curioustechnoid/MojoWebsockets/blob/main/simpleChatApp" target="_blank" rel="noreferrer noopener">here</a>.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1021" height="189" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.26.50.png" alt="" class="wp-image-598" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.26.50.png 1021w, https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.26.50-768x142.png 768w" sizes="auto, (max-width: 1021px) 100vw, 1021px" /><figcaption>Check out the complete source code <a href="https://github.com/curioustechnoid/MojoWebsockets/blob/main/simpleChatApp" target="_blank" rel="noreferrer noopener">here</a></figcaption></figure></div>



<p>In case the user is inactive for 5mins or the server closes the connection, we pop-up a message to the user saying connection is closed:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="883" height="133" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.26.39.png" alt="" class="wp-image-599" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.26.39.png 883w, https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-07.26.39-768x116.png 768w" sizes="auto, (max-width: 883px) 100vw, 883px" /><figcaption>Check out the complete source code <a href="https://github.com/curioustechnoid/MojoWebsockets/blob/main/simpleChatApp" target="_blank" rel="noreferrer noopener">here</a></figcaption></figure></div>



<h2 class="wp-block-heading">Testing</h2>



<p>Would you believe if I told you, this is all you need to build a simple chat program? Well, that&#8217;s Mojolicious for you. Let us fire up the morbo server and check out our chat application.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="534" height="130" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.09.13.png" alt="" class="wp-image-600"/></figure></div>



<p>Let us try accessing our chat program using the url: <code>http://127.0.0.1:3000</code></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="775" height="379" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.13.27.png" alt="" class="wp-image-601" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.13.27.png 775w, https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.13.27-768x376.png 768w" sizes="auto, (max-width: 775px) 100vw, 775px" /></figure></div>



<p>Give your name and click <em>Connect</em> button to connect to the chat session.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="794" height="405" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.13.49.png" alt="" class="wp-image-603" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.13.49.png 794w, https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.13.49-768x392.png 768w" sizes="auto, (max-width: 794px) 100vw, 794px" /></figure></div>



<p>A welcome message is displayed and it also shows that the user is connected to the server. Now go ahead, enter a message and hit send.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="756" height="389" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.14.17.png" alt="" class="wp-image-604"/></figure></div>



<p>You can see your message in the text area with a time stamp. The message is actually broadcasted by the server to all the connected users. Now let us access this chat program from our phone and send a message.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="769" height="394" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.15.19.png" alt="" class="wp-image-605"/></figure></div>



<p>You can see the messages sent by any user getting broadcasted to all the active users. If a time out occurs or if the server disconnects the connection, all the users will get a pop-up message like this:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="953" height="523" src="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.15.45.png" alt="" class="wp-image-606" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.15.45.png 953w, https://thecurioustechnoid.com/wp-content/uploads/2021/05/Screen-Shot-2021-05-05-at-08.15.45-768x421.png 768w" sizes="auto, (max-width: 953px) 100vw, 953px" /></figure></div>



<p>That&#8217;s about it, we have successfully implemented a simple chat program in Mojolicious using websockets. You can find the complete <a href="https://github.com/curioustechnoid/MojoWebsockets" target="_blank" rel="noreferrer noopener">source code</a> of this program <a href="https://github.com/curioustechnoid/MojoWebsockets" target="_blank" rel="noreferrer noopener">here</a>. Below is the video demonstration of what we discussed in this article, if it interests you. Thank you for reading.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Websockets using Mojolicious" width="640" height="360" src="https://www.youtube.com/embed/8Dt5bH4mZ0Q?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
<p>The post <a href="https://thecurioustechnoid.com/websockets-using-mojolicious/">WebSockets using Mojolicious</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://thecurioustechnoid.com/websockets-using-mojolicious/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mojolicious Minion &#8211; A High Performance Job Queue</title>
		<link>https://thecurioustechnoid.com/mojolicious-minion-a-high-performance-job-queue/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mojolicious-minion-a-high-performance-job-queue</link>
					<comments>https://thecurioustechnoid.com/mojolicious-minion-a-high-performance-job-queue/#respond</comments>
		
		<dc:creator><![CDATA[Rakshith Chengappa Mullengada]]></dc:creator>
		<pubDate>Mon, 26 Apr 2021 14:55:28 +0000</pubDate>
				<category><![CDATA[Perl / Mojolicious]]></category>
		<category><![CDATA[minion]]></category>
		<category><![CDATA[minions]]></category>
		<category><![CDATA[mojolicious]]></category>
		<category><![CDATA[mojolicious minion]]></category>
		<guid isPermaLink="false">https://thecurioustechnoid.com/?p=514</guid>

					<description><![CDATA[<p>Minion is a third party plugin for Mojolicious Web Framework which allows you to process time consuming tasks in the background. They are high performance job queue for Perl programming language and is not limited to just Mojolicious web framework. Minion is a high performance job queue for the Perl programming language, with support for&#8230;</p>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-minion-a-high-performance-job-queue/">Mojolicious Minion &#8211; A High Performance Job Queue</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="has-drop-cap">Minion is a third party plugin for Mojolicious Web Framework which allows you to process time consuming tasks in the background. They are high performance job queue for Perl programming language and is not limited to just Mojolicious web framework.</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://youtu.be/Icc9YOOF414" target="_blank" rel="noopener"><img loading="lazy" decoding="async" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/WatchOnYoutubeImage.png" alt="" class="wp-image-78" width="217" height="87"/></a></figure></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Minion is a high performance job queue for the Perl programming language, with support for multiple named queues, priorities, high priority fast lane, delayed jobs, job dependencies, job progress, job results, retries with backoff, rate limiting, unique jobs, expiring jobs, statistics, distributed workers, parallel processing, autoscaling, remote control, Mojolicious admin ui, resource leak protection and multiple backends (such as PostgreSQL).</p><cite>mojolicious.org</cite></blockquote>



<p>Minions doesn&#8217;t come pre-installed with Mojolicious installation so it needs to be installed separately.</p>



<pre class="wp-block-code"><code>cpanm Minion</code></pre>



<p>If you use docker, I have built an image which has Mojolicious and Minion together. You can get it here:</p>



<pre class="wp-block-code"><code>docker pull curioustechnoid/mojolicious</code></pre>



<p>Minion uses database backend to store and process the jobs. Most of the popular databases(like SQLite, PostgreSQL) are supported. Jobs can be added to the queue from different programs like Mojolicious, Perl Program, Command Line etc. The Minion worker will be monitoring your backend database and processes the jobs based on priority and availability.</p>



<p>There are 2 important components to Minions:</p>



<ul class="wp-block-list"><li>Minion Worker</li><li>Job Queues</li></ul>



<p>Let us see how we can configure and deploy Minion.</p>



<h2 class="wp-block-heading">Minion Worker</h2>



<p>Minion workers are the silent warriors that keeps monitoring the backend database and processes the jobs that gets added to the queue.</p>



<p>Let us go ahead and create a script to start the Minion worker. I am using Mojolicious lite app to create a worker. You can very well create a worker without using Mojolicious, read more about it <a href="https://docs.mojolicious.org/Minion/Guide#Custom-workers" target="_blank" rel="noreferrer noopener">here</a>. We will also add definition of our jobs inside this script. We will be adding a &#8216;<em>slow-running</em>&#8216; task and a &#8216;<em>high priority&#8217;</em> task to the script as an example. For the purpose of this demo, I am using SQLite as the backend.</p>



<pre class="wp-block-code"><code>#!/usr/bin/env perl
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# minion-worker.pl
#
# AUTHOR:  Curious Technoid
# DATE:  20-Apr-2021
# VERSION:  1.0
# PURPOSE:
#           This mojo app is to initiate the minion worker
#           which will process the jobs in the queue.
#
# USAGE: 
#       ./minion-worker.pl minion worker -m production
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# 
use Mojolicious::Lite -signatures;


# Using sqlite for the queue
plugin Minion =&gt; { SQLite =&gt; 'minionjobqueue.db', };



#
# Dummy Slow Running Task
#
app-&gt;minion-&gt;add_task(slow_task =&gt; sub ($job) {

        my $id = $job-&gt;id;
        $job-&gt;app-&gt;log-&gt;info("Slow Running Task Initiated -&gt; ".$id);
        sleep 20;
        $job-&gt;app-&gt;log-&gt;info("Slow Running Task Completed -&gt; ".$id);
        $job-&gt;finish({message =&gt; "Slow Running Task Completed -&gt; ".$id});
});

#
# Dummy High Priority Task
#
app-&gt;minion-&gt;add_task(high_priority =&gt; sub ($job) {

        my $id = $job-&gt;id;
        $job-&gt;app-&gt;log-&gt;info("High Priority Task Initiated -&gt; ".$id);
        sleep 3;
        $job-&gt;app-&gt;log-&gt;info("High Priority Task Completed -&gt; ".$id);
        $job-&gt;finish({message =&gt; "High Priority Task Completed -&gt; ".$id});
});



app-&gt;start;</code></pre>



<h4 class="wp-block-heading">Start the worker</h4>



<p>Now that our Worker script is ready time to start it. You can manually start the worker by running the one of the below commands in terminal:</p>



<pre class="wp-block-code"><code>./minion-worker.pl minion worker

./minion-worker.pl minion worker -m production

nohup ./minion-worker.pl minion worker -m production &amp;</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="794" height="208" src="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minion-1.png" alt="" class="wp-image-537" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minion-1.png 794w, https://thecurioustechnoid.com/wp-content/uploads/2021/04/minion-1-768x201.png 768w" sizes="auto, (max-width: 794px) 100vw, 794px" /></figure>



<p>In a production environment, I prefer creating it as a systemd service and run it in the background.</p>



<pre class="wp-block-code"><code>&#91;Unit]
Description=Minion Workers for Mojolicious
After=mariadb.service

&#91;Service]
Type=simple
ExecStart=/path/to/your/worker/minion-worker.pl minion worker -m production
ExecReload=/path/to/your/worker/minion-worker.pl minion worker -m production
KillMode=process

&#91;Install]
WantedBy=multi-user.target</code></pre>



<p>Now we have the worker running, ready to process any jobs added to the queue. You can check the status of the jobs in the queue using the command:</p>



<pre class="wp-block-code"><code>./minion-worker.pl minion job</code></pre>



<p>Minion comes with a pre-built Admin console to monitor the jobs that are enqueued and processed. It can be enabled using the plugin:</p>



<pre class="wp-block-code"><code>plugin 'Minion::Admin';</code></pre>



<p>We will see it&#8217;s usage when we build our Mojolicious app for adding jobs to the queue.</p>



<p>Next task would be create means to enqueue the job queue.</p>



<h2 class="wp-block-heading">Job Queue</h2>



<p>There are many ways to add jobs to the job queue, we will look at the below 3 ways:</p>



<ul class="wp-block-list"><li>Mojolicious App</li><li>Perl Script</li><li>Command Line</li></ul>



<h4 class="wp-block-heading">Mojolicious App</h4>



<p>One of the best use cases of using Minions is to call it from Mojolicious Web App to do time consuming or CPU intensive task in the background. We will create a Mojolicious App which will do the below things:</p>



<ol class="wp-block-list"><li>Add new jobs to the Queue</li><li>Enable Minion Admin Console to monitor the job queue</li></ol>



<p>Without further adieu let us quickly create a new Mojolicious app to begin with:</p>



<pre class="wp-block-code"><code>mojo generate app mojominion</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="794" height="658" src="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionmojoGenerate-1.png" alt="" class="wp-image-549" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionmojoGenerate-1.png 794w, https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionmojoGenerate-1-768x636.png 768w" sizes="auto, (max-width: 794px) 100vw, 794px" /></figure></div>



<p>In our main library created by the <em>mojo</em> command, we will first add the logic to call the Minion plugin.</p>



<p><code>File: mojominion/lib/mojominion.pm</code></p>



<pre class="wp-block-code"><code>$self-&gt;plugin(Minion =&gt; { SQLite =&gt; 'minionjobqueue.db'});</code></pre>



<p>We will keep it simple and only add routes to:</p>



<ol class="wp-block-list"><li>Add new jobs to the queue</li><li>Navigate to Minion Admin Console</li></ol>



<p>We will not think much about security as of this moment. This is just to show you how to add jobs to the queue, so right now anybody can add jobs to the queue.</p>



<pre class="wp-block-code"><code>  $r-&gt;get('/addjob/slow')-&gt;to(controller =&gt; 'Example', action =&gt; 'addSlowJob');  # Route to add slow job
  $r-&gt;get('/addjob/high')-&gt;to(controller =&gt; 'Example', action =&gt; 'addHighJob');  # Route to add high priority job
  $self-&gt;plugin('Minion::Admin' =&gt; {route =&gt; $r-&gt;any('/admin')});  # Route to navigate to Minion Admin Console</code></pre>



<p>You can find the complete source code <a href="https://github.com/curioustechnoid/Minion" target="_blank" rel="noreferrer noopener">here</a>.</p>



<p>Let us now add the logic in our default controller to push the job to the queue.</p>



<p><code>File: mojominion/lib/mojominion/Controller/Example.pm</code></p>



<p>Add the below 2 procedures in the controller:</p>



<pre class="wp-block-code"><code># Subroutine to add slow jobs
sub addSlowJob ($self) {

   my $jobid = $self-&gt;minion-&gt;enqueue(slow_task =&gt; &#91;]);

  $self-&gt;render(text =&gt; 'Your Slow Task is Added to the queue, Job ID: '.$jobid.'. &lt;a href="/admin"&gt;Click here&lt;/a&gt; to view the status.');
}



# Subroutine to add high priority jobs
sub addHighJob ($self) {

   # 
   # By default priority is set to 0, anything more than that gets priority.
   # You can have values between -100 to 100
   #
   my $jobid = $self-&gt;minion-&gt;enqueue(high_priority =&gt; &#91;] =&gt; {priority =&gt; 10});
   # my $jobid = $self-&gt;minion-&gt;enqueue(slow_task =&gt; &#91;]); #Another way of adding the task to the job queue

   $self-&gt;render(text =&gt; 'Your Task is Added to the high priority lane, Job ID: '.$jobid.'. &lt;a href="/admin"&gt;Click here&lt;/a&gt; to view the status.');

}</code></pre>



<p>Task given high priority will get picked up first once the worker becomes free. You can see this first hand in a video demo that I created in <a href="https://www.youtube.com/watch?v=Icc9YOOF414" target="_blank" rel="noreferrer noopener">youtube</a>.</p>



<p>You can find the complete source code of the above codes <a href="https://github.com/curioustechnoid/Minion" target="_blank" rel="noreferrer noopener">here</a>.</p>



<h5 class="wp-block-heading">Time to Test</h5>



<p>We created the worker, started it and then created a Mojolicious App that can handle job requests. Let us fire it up and see if it works.</p>



<pre class="wp-block-code"><code>morbo mojominion/script/mojominion</code></pre>



<p>Let us first access the admin console to see if that is accessible:</p>



<p><code>http://127.0.0.1:3000/admin</code></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1400" height="958" src="https://thecurioustechnoid.com/wp-content/uploads/2021/04/miniondashboard1.png" alt="" class="wp-image-539" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/04/miniondashboard1.png 1400w, https://thecurioustechnoid.com/wp-content/uploads/2021/04/miniondashboard1-768x526.png 768w" sizes="auto, (max-width: 1400px) 100vw, 1400px" /></figure>



<p>Admin console is working fine and we can see that we have 1 worker running. Time for us add some jobs by using the below URLs (keep the admin console open):</p>



<p><code>http://127.0.0.1:3000/addjob/slow</code><br><code>http://127.0.0.1:3000/addjob/high</code></p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="569" height="217" src="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionslowtask-1.png" alt="" class="wp-image-546"/></figure></div>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="574" height="212" src="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionhightask.png" alt="" class="wp-image-541"/></figure></div>



<p>Open the URL multiple times to add more jobs. If we head back to our admin console we can see our job getting executed.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1402" height="955" src="https://thecurioustechnoid.com/wp-content/uploads/2021/04/miniondashboard2.png" alt="" class="wp-image-542" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/04/miniondashboard2.png 1402w, https://thecurioustechnoid.com/wp-content/uploads/2021/04/miniondashboard2-768x523.png 768w" sizes="auto, (max-width: 1402px) 100vw, 1402px" /></figure>



<p>Just like that we have successfully implemented Minions using Mojolicious.</p>



<h4 class="wp-block-heading">Perl Script</h4>



<p>Can we use Minions without Mojolicious ? Most definitely. We will keep the above Mojolicious app running to access the admin console and then try to add a job using the below plain Perl script:</p>



<pre class="wp-block-code"><code>#!/usr/bin/env perl
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# add-minion-job.pl
#
# AUTHOR:  Curious Technoid
# DATE:  20-Apr-2021
# VERSION:  1.0
# PURPOSE:
#           This perl script is used to add a new job to
#           minion queue.
#
# USAGE: 
#       ./add-minion-job.pl slow
#       ./add-minion-job.pl fast
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# 
use Minion;


# Do you notice we are using the same database
my $minion = Minion-&gt;new( SQLite =&gt; 'minionjobqueue.db');


# Getting the parameter
my $param = shift;


if(lc $param eq 'slow'){

    # Add slow task to the queue
    my $jobid = $minion-&gt;enqueue(slow_task =&gt; &#91;]);

    print("Your Slow Task is Added to the queue from perl, Job ID: $jobid\n\n");

}elsif(lc $param eq 'fast'){

    # Add high priority task to the queue
    my $jobid = $minion-&gt;enqueue(high_priority =&gt; &#91;] =&gt; {priority =&gt; 10});

    print("Your High Priority Task is Added to the queue from perl, Job ID: $jobid\n\n");
");

}else{

    die("Incorrect parameter\n");
}</code></pre>



<p>Once the script is ready, run it using the below command to add jobs:</p>



<pre class="wp-block-code"><code>./add-minion-job.pl slow
./add-minion-job.pl fast</code></pre>



<p>Now if you head back to the Admin console that is running from our previous example, you can notice that the new jobs added by the Perl script is queued and executed. If you don&#8217;t want to use the Mojolicious Admin console at all, you can always use the command line to check the jobs:</p>



<pre class="wp-block-code"><code>./minion-worker.pl minion job</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="799" height="309" src="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionjob.png" alt="" class="wp-image-543" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionjob.png 799w, https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionjob-768x297.png 768w" sizes="auto, (max-width: 799px) 100vw, 799px" /></figure>



<h4 class="wp-block-heading">Command Line</h4>



<p>We can even add jobs to the queue from command line directly. One way is ofcourse to use the pure Perl script above and use that to add jobs from command line. Not only that, you can also add jobs using the worker script(minion-worker.pl) we wrote in the beginning. Below command adds jobs to the queue directly from command line:</p>



<pre class="wp-block-code"><code>./minion-worker.pl minion job -e slow_task</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="795" height="266" src="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionCLI.png" alt="" class="wp-image-545" srcset="https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionCLI.png 795w, https://thecurioustechnoid.com/wp-content/uploads/2021/04/minionCLI-768x257.png 768w" sizes="auto, (max-width: 795px) 100vw, 795px" /></figure>



<p>You can pass arguments like this:</p>



<pre class="wp-block-code"><code>./minion-worker.pl minion job -e slow_task -a '&#91;"param1","param2"]'</code></pre>



<p>This is very useful if you want to schedule jobs using cron.</p>



<div style="height:32px" aria-hidden="true" class="wp-block-spacer"></div>



<p>That&#8217;s about it. We have configured, deployed and tested Mojolicious Minions in this article. If you wish to check out the hands on demonstration about the things we discussed in this blog, check out my video in youtube below.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Mojolicious Minion - High Performance Job Queue" width="640" height="360" src="https://www.youtube.com/embed/Icc9YOOF414?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>You can read more about Minion documentation in the <a href="https://docs.mojolicious.org/Minion" target="_blank" rel="noreferrer noopener">official page here</a>. </p>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-minion-a-high-performance-job-queue/">Mojolicious Minion &#8211; A High Performance Job Queue</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://thecurioustechnoid.com/mojolicious-minion-a-high-performance-job-queue/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mojolicious (Part 4): Database Management</title>
		<link>https://thecurioustechnoid.com/mojolicious-part-4-database-management/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mojolicious-part-4-database-management</link>
					<comments>https://thecurioustechnoid.com/mojolicious-part-4-database-management/#comments</comments>
		
		<dc:creator><![CDATA[Rakshith Chengappa Mullengada]]></dc:creator>
		<pubDate>Wed, 15 Jul 2020 02:00:00 +0000</pubDate>
				<category><![CDATA[Perl / Mojolicious]]></category>
		<category><![CDATA[mojolicious]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[web framework]]></category>
		<guid isPermaLink="false">https://thecurioustechnoid.com/?p=459</guid>

					<description><![CDATA[<p>We have reached the last part of Mojolicious series. We have so far built a new project with Mojolicious full_app, created a home page for our website, then we looked at layouts &#38; templates, and finally ended our last article with session management. In this session we will cover database management, which is one of&#8230;</p>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-part-4-database-management/">Mojolicious (Part 4): Database Management</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="has-drop-cap">We have reached the last part of Mojolicious series. We have so far built a new project with Mojolicious <em>full_app</em>, created a <a aria-label="undefined (opens in a new tab)" href="/mojolicious-part1-homepage/" target="_blank" rel="noreferrer noopener">home page</a> for our website, then we looked at <a aria-label="undefined (opens in a new tab)" href="/mojolicious-part2-layouts-templates/" target="_blank" rel="noreferrer noopener">layouts &amp; templates</a>, and finally ended our last article with <a aria-label="undefined (opens in a new tab)" href="/mojolicious-part-3-session-management/" target="_blank" rel="noreferrer noopener">session management</a>. In this session we will cover database management, which is one of the important functionalities when building a website.</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://youtu.be/Y_vg0hdS3YM" target="_blank" rel="noopener noreferrer"><img loading="lazy" decoding="async" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/WatchOnYoutubeImage.png" alt="" class="wp-image-78" width="217" height="87"/></a></figure></div>



<p>The main functionality of our test case website that we are working on from <a href="/mojolicious-part1-homepage/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">part 1</a> of Mojolicious series is for registered users to be able to publish their testimonials in the website. To achieve that, we need to follow the below steps:</p>



<ul class="wp-block-list"><li>Create Database Components</li><li>Create Testimonials Page Template</li><li>Database Connectivity Logic</li><li>Verification</li><li>Deploy to Production</li></ul>



<h2 class="wp-block-heading">Create Database Components</h2>



<p>The testimonials entered by the users needs to be stored in the database so that all the testimonials entered by all the users is visible to everyone. We will use <em>MariaDB</em> database to store our testimonial table. First, we will create a <em>MariaDB</em> database called <code>tct_mojo_db</code> by logging in as root user:</p>



<pre class="wp-block-code"><code>mysql -u root -p</code></pre>



<pre class="wp-block-code"><code>CREATE database tct_mojo_db;</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="883" height="517" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-db.jpg" alt="" class="wp-image-464" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-db.jpg 883w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-db-768x450.jpg 768w" sizes="auto, (max-width: 883px) 100vw, 883px" /></figure></div>



<p>Then we will create a database user called <strong>demo</strong> and give it all the privileges to the database <code>tct_mojo_db</code></p>



<pre class="wp-block-code"><code>CREATE USER 'demo'@'localhost' IDENTIFIED BY 'welcome123';

GRANT ALL PRIVILEGES ON tct_mojo_db.* TO 'demo'@'localhost';</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="882" height="248" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-user.png" alt="" class="wp-image-466" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-user.png 882w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-user-768x216.png 768w" sizes="auto, (max-width: 882px) 100vw, 882px" /></figure></div>



<p>Finally we login as the new user(<strong>demo</strong>) and create the table <code>tct_mojo_testimonials</code> in our new database <code>tct_mojo_db</code></p>



<pre class="wp-block-code"><code>mysql -u demo -p</code></pre>



<pre class="wp-block-code"><code>use tct_mojo_db;

CREATE TABLE IF NOT EXISTS tct_mojo_testimonials (
id             INT(20)         NOT NULL AUTO_INCREMENT,
published_by   VARCHAR(560)    NOT NULL,
published_on   TIMESTAMP       NOT NULL DEFAULT CURRENT_TIMESTAMP,
testimonial    VARCHAR(32000)  NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB;</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="927" height="414" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-table.jpg" alt="" class="wp-image-467" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-table.jpg 927w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-create-table-768x343.jpg 768w" sizes="auto, (max-width: 927px) 100vw, 927px" /></figure></div>



<p>We will store the testimonials published by the users in the above database table. We have all the database related components in place for your project.</p>



<h2 class="wp-block-heading">Create Testimonials Page Template</h2>



<p>We need a new page template where users can publish their testimonials and view the testimonials of others. We will have a single page which does both. The first section of the page will be a html form which registered users can use to provide their testimonials and we will have a section below which will have all the testimonials given by everyone.</p>



<p>Let us go ahead and create a new template called: <code>managetestimonials.html.ep</code> in our templates folder: <code>myWebSite/templates/myTemplates/</code> with the below content:</p>



<pre class="wp-block-code"><code>% layout 'master';
% title 'View Testimonials';
&lt;a href="/"&gt;Home&lt;/a&gt;&amp;nbsp;&amp;nbsp;
&lt;a href="/logout"&gt;Log Out&lt;/a&gt;

&lt;h1&gt;&lt;%= $msg %&gt;&lt;/h1&gt;

&lt;center&gt;
&lt;form action="/testimonials" method="post"&gt;

    &lt;textarea id="userReview" name="userReview" rows="8" cols="50"&gt;Please enter your testimonial here&lt;/textarea&gt;&lt;/br&gt;
    &lt;input type="reset" value="Clear" /&gt;
    &lt;input type="submit" value="Publish"&gt;

&lt;/form&gt;
&lt;/center&gt;

&lt;table width=100% align=center border=1 cellspacing=0 cellpadding=0&gt;
  &lt;tr&gt;
    &lt;th&gt;Testimonials&lt;/th&gt;
  &lt;/tr&gt;

  &lt;%== $alltestimonials %&gt;

&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>



<p>We are referring to a perl variable <code>$alltestimonials</code> in the template code, this will have the existing testimonials from database in HTML format. We will set this value in our controller after getting them from database.</p>



<h2 class="wp-block-heading">Database Connectivity Logic</h2>



<p>Now that we have the new page template ready, time for us to add the logic to handle database operations. In order to achieve that we need to make the following changes to our project:</p>



<ul class="wp-block-list"><li>Update DB credentials in myWebSite.conf file</li><li>Add DB handler and logic to handle new route</li><li>Create DB Modeller for database operations</li><li>Change Controller logic to handle DB operations</li></ul>



<h5 class="wp-block-heading">myWebSite.conf</h5>



<p>We need to update our conf file to include database credentials. We will add the database connectivity in the below format:</p>



<pre class="wp-block-code"><code>mysql =&gt; 'mysql://dbusername:dbpassword@localhost/databasename'</code></pre>



<p>So our updated <code>myWebSite.conf</code> file will look like this:</p>



<pre class="wp-block-code"><code>{
  secrets =&gt; &#91;'8c285c2b2f9ce11c46ee322d52179ac32be6d42a'],
  mysql =&gt; 'mysql://demo:welcome123@localhost/tct_mojo_db'
}</code></pre>



<h5 class="wp-block-heading">DB Handler</h5>



<p>We have DB connections in place. Now let us create a helper in our main library(<em>myWebSite.pm</em>) which will be used as a handle to our database. This can be used my our modeller and controller to access the database.</p>



<p>Database helpers can be created using the below statement:</p>



<pre class="wp-block-code"><code># Invoking Database handle 
$self-&gt;helper(mysql =&gt; 
sub { state $mysql = Mojo::mysql-&gt;new(shift-&gt;config('mysql')) });

$self-&gt;helper(dbhandle =&gt; 
sub { state $vikidb = myWebSite::Model::Database-&gt;new(mysql =&gt; shift-&gt;mysql) });</code></pre>



<p>We will also add the below routes to handle the new testimonial page action using :</p>



<pre class="wp-block-code"><code>$authorized-&gt;get('/testimonials')-&gt;to('CustomController#loadTestimonials');
$authorized-&gt;post('/testimonials')-&gt;to('CustomController#saveTestimonial');</code></pre>



<p>If you remember from our previous session, the <code>$authorized</code> handle helps us in making sure that only logged in users can access the above calls since these statements are called after the <em><strong>under</strong></em> statement.</p>



<p>Do not forget to import the module <code>use Mojo::mysql;</code> in your main library. If <code>Mojo::mysql</code> is not installed, go ahead and install the perl module.</p>



<p>We will also import our database modeller in our main library: <code>use myWebSite::Model::Database;</code>. This does not exist yet, we will be creating this modeller in the next section.</p>



<p>Once all the change are done, your main library file <code>myWebSite.pm</code> should look something like <a href="/wp-content/uploads/misc/myWebSite_part4.txt" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">this</a>.</p>



<h5 class="wp-block-heading">DB Modeller</h5>



<p>Next we will be creating a database modeller which will have the logic to query the testimonial data and insert any newly published testimonial. We will create the modeller inside our <code>lib</code> directory using the command:</p>



<pre class="wp-block-code"><code>mkdir lib/myWebSite/Model

touch lib/myWebSite/Model/Database.pm</code></pre>



<p>Let us now open the database modeller file and add the below content:</p>



<pre class="wp-block-code"><code>package myWebSite::Model::Database;
use Mojo::Base -base;

has 'mysql';

# Subroutine to get all the testimonials
sub fetch_all_testimonials{ shift-&gt;mysql-&gt;db-&gt;query('select * from tct_mojo_testimonials order by published_on desc')-&gt;hashes-&gt;to_array }

# Subroutine to insert the new testimonial to database
sub publish_testimonial{


   my ($self, $new_testimonial, $username) = @_;
   my $sql = 'insert into tct_mojo_testimonials(published_by,testimonial) values (?,?)';


   $self-&gt;mysql-&gt;db-&gt;query($sql, $username, $new_testimonial);

}


1;</code></pre>



<p>We have 2 subroutine in our modeller, <code>fetch_all_testimonials</code> will fetch all the testimonials into an array of hashes and the second subroutine <code>publish_testimonial</code> inserts the newly published testimonials to the database. These are the only 2 database operation we require for your website.</p>



<h5 class="wp-block-heading">Controller CustomController.pm Changes</h5>



<p>We have our modeller in place that handles the DB operations, let us go ahead and add subroutines in our controller which calls these.</p>



<p>In the above section, we had added 2 new subroutine calls to our controller in the main library file: <code>myWebSite.pm</code>. Let us add the logic to those 2 subroutines in our existing controller: <code>lib/myWebSite/Controller/CustomController.pm</code></p>



<p><em><strong>loadTestimonials</strong></em> basically generates a HTML data of all the testimonials that are there in the database. The generated HTML data is passed as parameter to the template where it is rendered. It uses the <code>fetch_all_testimonials</code> subroutine from the DB modeller that we created above. In the section <em>Create Testimonials Page Template</em> above we had used the variable <code>$alltestimonials</code> to display the data, the value for it is being set in the below subroutine.</p>



<pre class="wp-block-code"><code>sub loadTestimonials{

    my $self = shift;
    my $all_testimonials_html;

    foreach my $all_testimonials (@{$self-&gt;dbhandle-&gt;fetch_all_testimonials})
    {
        $all_testimonials_html .= "
  &lt;tr&gt;
      &lt;td&gt;
          ".$all_testimonials-&gt;{testimonial}."&lt;/br&gt;&lt;/br&gt;
          &lt;div style='text-align: right;'&gt;&lt;i&gt;".$all_testimonials-&gt;{published_by}."&lt;/br&gt;".$all_testimonials-&gt;{published_on}."&lt;/i&gt;&lt;/div&gt;
     &lt;/td&gt;
  &lt;/tr&gt;";
    }
    $self-&gt;render(template =&gt; 'myTemplates/managetestimonials',msg =&gt; 'View Testimonials',alltestimonials =&gt; $all_testimonials_html);


}</code></pre>



<p><em><strong>saveTestimonial</strong></em> basically saves the newly created testimonial added by the registered users. It uses the <code>publish_testimonial</code> subroutine from the DB modeller that we created above.</p>



<pre class="wp-block-code"><code>sub saveTestimonial{

    my $self = shift;
    my $new_testimonial = $self-&gt;param('userReview');
    my $user = $self-&gt;session('username');

    $self-&gt;dbhandle-&gt;publish_testimonial($new_testimonial,$user);
    &amp;loadTestimonials($self);
}</code></pre>



<p>Once all the above changes are done, our CustomController.pm controller will look like <a href="/wp-content/uploads/misc/CustomController_part4.txt" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">this</a>.</p>



<h2 class="wp-block-heading">Verification</h2>



<p>That&#8217;s about it, we have everything we need to start our web application. Let us start our web application using <code>morbo</code> webserver:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="772" height="321" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1.jpg" alt="" class="wp-image-362" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1.jpg 772w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1-768x319.jpg 768w" sizes="auto, (max-width: 772px) 100vw, 772px" /></figure></div>



<p>I have <a href="/ssh-tunneling/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">SSH Tunnel</a> enabled, so let me access our website using localhost IP and port 3000.</p>



<p>Once we login and navigate to Testimonials page, it should look like this:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1044" height="539" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-testimonial-page.png" alt="" class="wp-image-469" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-testimonial-page.png 1044w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-testimonial-page-768x397.png 768w" sizes="auto, (max-width: 1044px) 100vw, 1044px" /></figure></div>



<p>If we add any new testimonial, we can see it getting added in the table below:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1060" height="513" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-testimonial-page-add-1.png" alt="" class="wp-image-471" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-testimonial-page-add-1.png 1060w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-testimonial-page-add-1-768x372.png 768w" sizes="auto, (max-width: 1060px) 100vw, 1060px" /></figure></div>



<p>We have successfully handled database connection in our website.</p>



<h2 class="wp-block-heading">Deploy to Production</h2>



<p>Now that we have a fully operational website with all the requirements met and tested, we can deploy our changes in production and start it to be available for everyone. To do that, as explained in the <a aria-label="undefined (opens in a new tab)" href="/mojolicious-intro-hello-world/" target="_blank" rel="noreferrer noopener">Mojolicious Introduction</a> article, we will use the production webserver <code>hypnotoad</code>.</p>



<ol class="wp-block-list"><li>Let&#8217;s tell <code>hypnotoad</code> to run on port 80. To do that, we will update the <code>myWebSite/myWebSite.conf</code> file to look like this: </li></ol>



<pre class="wp-block-code"><code>{
     secrets =&gt; &#91;'8c285c2b2f9ce11c46ee322d52179ac32be6d42a'],
     mysql =&gt; 'mysql://demo:welcome123@localhost/tct_mojo_db',
     hypnotoad =&gt; {
          listen =&gt; &#91;'http://*:80'],
          workers =&gt; 10
     }
}</code></pre>



<p>We have also told <code>hypnotoad</code> to run 10 workers.</p>



<ol class="wp-block-list" start="2"><li>Next we will open firewall ports 80 so that the website is accessible to everyone. I run Mojolicious on Fedora and use <strong><em>firewalld</em></strong>, I will run the below command to open the ports: </li></ol>



<pre class="wp-block-code"><code>firewall-cmd --zone=public --permanent --add-port 80/tcp
firewall-cmd --reload</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1029" height="285" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-firewall.png" alt="" class="wp-image-472" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-firewall.png 1029w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-firewall-768x213.png 768w" sizes="auto, (max-width: 1029px) 100vw, 1029px" /></figure></div>



<ol start="3"><li>Start the web application using <code>hypnotoad</code> by using the command: </li></ol>



<pre class="wp-block-code"><code>hypnotoad myWebSite/script/myWebSite</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="858" height="183" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-final-hypno-start.png" alt="" class="wp-image-476" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-final-hypno-start.png 858w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-final-hypno-start-768x164.png 768w" sizes="auto, (max-width: 858px) 100vw, 858px" /></figure></div>



<ol start="4"><li>Finally verify by accessing the website using your server IP (or domain name if you have one mapped):</li></ol>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1207" height="891" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-final-hypno-1.png" alt="" class="wp-image-474" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-final-hypno-1.png 1207w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo4-final-hypno-1-768x567.png 768w" sizes="auto, (max-width: 1207px) 100vw, 1207px" /></figure></div>



<p class="has-small-font-size"><em><span style="color:#313131" class="tadv-color">Note: I recommend to use Apache Reverse Proxy along with hypnotoad for production deployments.</span></em></p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p>With that the Mojolicious tutorial comes to an end. We have successfully created a fully operational website covering major features of any website and made it available to general public. Hope the Mojolicious <a aria-label="undefined (opens in a new tab)" href="https://thecurioustechnoid.com/tag/mojolicious/" target="_blank" rel="noreferrer noopener">tutorial series</a> were informative and helpful. Do let me know your thoughts and comments in the comment section below. You can find the entire <a href="https://github.com/curioustechnoid/IntroductionToMojolicious" target="_blank" rel="noreferrer noopener">source code</a> of the testimonials project <a href="https://github.com/curioustechnoid/IntroductionToMojolicious" target="_blank" rel="noreferrer noopener">here</a>. You can watch the entire Mojolicious series that we discussed in this blog series in my <a aria-label="undefined (opens in a new tab)" href="https://www.youtube.com/playlist?list=PLf0DTZRjrjle9aL1LMsUtMr_ExVLeGJAH" target="_blank" rel="noreferrer noopener">youtube channel</a>. Keep visiting this blog for more technical tutorials.</p>



<figure class="wp-block-embed aligncenter is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Mojolicious (Part 4): Database Management" width="640" height="360" src="https://www.youtube.com/embed/Y_vg0hdS3YM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">Edits:</h4>



<p><strong>[13-May-2021] </strong>It so happened that I missed to mention about changing the <code>homepage.html.ep</code> file to point to the new testimonial route(/testimonials) that we created in the main library(<em>myWebSite.pm</em>). You just need to change the <em>href</em> tag in the homepage template to point to the new route and you should be good to go.</p>



<pre class="wp-block-code"><code>% layout 'master';
% title 'Home Page';
    &lt;a href="/logout">Log Out&lt;/a>
      &lt;h1>&lt;%= $msg %>&lt;/h1>
      &lt;h5 class="w3-padding-32">This is my personal site built with Mojolicious. You can provide testimonials using the link &lt;a href="<span style="font-size: inherit; background-color: inherit;"><mark>/testimonials</mark></span>">here&lt;/a>. 
&lt;/h5></code></pre>



<p>Thanks to Jim for pointing this out.</p>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-part-4-database-management/">Mojolicious (Part 4): Database Management</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://thecurioustechnoid.com/mojolicious-part-4-database-management/feed/</wfw:commentRss>
			<slash:comments>23</slash:comments>
		
		
			</item>
		<item>
		<title>Mojolicious (Part 3): Session Management</title>
		<link>https://thecurioustechnoid.com/mojolicious-part-3-session-management/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mojolicious-part-3-session-management</link>
					<comments>https://thecurioustechnoid.com/mojolicious-part-3-session-management/#comments</comments>
		
		<dc:creator><![CDATA[Rakshith Chengappa Mullengada]]></dc:creator>
		<pubDate>Sun, 05 Jul 2020 13:04:46 +0000</pubDate>
				<category><![CDATA[Perl / Mojolicious]]></category>
		<category><![CDATA[mojolicious]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[web framework]]></category>
		<guid isPermaLink="false">https://thecurioustechnoid.com/?p=431</guid>

					<description><![CDATA[<p>In the previous article we made our home page beautiful by adding a HTML template using the concept of Templates and Layouts. Let us now see how we can restrict access to our website to only registered users. We will achieve this by authenticating known users and using session cookies after successful login. We will&#8230;</p>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-part-3-session-management/">Mojolicious (Part 3): Session Management</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In the <a aria-label="undefined (opens in a new tab)" href="/mojolicious-part2-layouts-templates/" target="_blank" rel="noreferrer noopener">previous article</a> we made our home page beautiful by adding a HTML template using the concept of <em><strong>Templates and Layouts</strong></em>. Let us now see how we can restrict access to our website to only registered users. We will achieve this by authenticating known users and using session cookies after successful login. We will break this task into the below steps and conquer it one by one:</p>



<ul class="wp-block-list"><li>Create Login and Logout Pages</li><li>Authentication and Session Management Logic</li><li>Verification</li></ul>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://youtu.be/SnGxyxe41fc" target="_blank" rel="noopener noreferrer"><img loading="lazy" decoding="async" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/WatchOnYoutubeImage.png" alt="" class="wp-image-78" width="217" height="87"/></a></figure></div>



<p>Before we proceed further, let us all remind ourselves how our Mojolicious website looks as of now:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1546" height="894" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-homepage-new-template.png" alt="" class="wp-image-379" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-homepage-new-template.png 1546w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-homepage-new-template-768x444.png 768w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-homepage-new-template-1536x888.png 1536w" sizes="auto, (max-width: 1546px) 100vw, 1546px" /></figure></div>



<p>and this is our project file structure:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="676" height="817" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo3-tree.jpg" alt="" class="wp-image-432"/></figure>



<h2 class="wp-block-heading">Create Login and Logout Pages</h2>



<p>Instead of the home page, we will redirect the users to the login page whenever they access our website. If they provide the correct username / password, we will create session cookies and re-direct them to the home page. Once they are done browsing our website, they can click the <em>Logout</em> link (which we will add to our homepage). This will remove the session cookies and safely logout.</p>



<p>We have already created a <em>master</em> <em><strong>layout</strong></em> in our <a href="/mojolicious-part2-layouts-templates/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">previous session</a> which is the skeleton of our website. This makes us not worry about the look and feel of the website as it is already taken care of. We just need to create template files for login and logout pages which will call our already created <em>master</em> <strong><em>layout</em></strong>.</p>



<h4 class="wp-block-heading">Login Page</h4>



<p>Let us create a new template called<em> login.html.ep</em> inside the template folder of our project: <em>myWebSite/templates/myTemplates</em>. We will add the below code to it:</p>



<pre class="wp-block-code"><code>% layout 'master';
% title 'Login Page';

&lt;center&gt;
&lt;h1&gt;Please Login to Access the Website&lt;/h1&gt;

&lt;h6&gt;
&lt;!-- Logic to display errors if any --&gt;
&lt;font color=red&gt;
&lt;% if($error_message){ %&gt;
&lt;%= $error_message %&gt;
&lt;% } %&gt;
&lt;/font&gt;
&lt;/h6&gt;

&lt;form action="/login" method="post"&gt;

    &lt;b&gt;UserName&lt;/b&gt; &lt;input type="text" name="username" required&gt;&lt;/br&gt;
    &lt;b&gt;Password&lt;/b&gt; &lt;input type="password" name="pass" required&gt;&lt;/br&gt;

    &lt;input type="submit" value="Submit"&gt;
    &lt;input type="reset" value="Reset" /&gt;

&lt;/form&gt;
&lt;/center&gt;</code></pre>



<p>The variable <code>$error_message</code> is used to display any error encountered while validating the user credentials.</p>



<p>We are using the <em>master</em> <em><strong>layout</strong></em> that we created in the <a href="/mojolicious-part2-layouts-templates/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">previous session</a>. We changed the <em>title</em> helper to say it&#8217;s a <em>Login Page</em>. Then we created a very simple login form which on submit is routed to <code>/login</code> action.</p>



<h4 class="wp-block-heading">Logout Page</h4>



<p>We will now create a logout page template with the name <em>logout.html.ep</em> in our template folder: <em>myWebSite/templates/myTemplates</em> with the below content:</p>



<pre class="wp-block-code"><code>% layout 'master';
% title 'Logout Page';

&lt;center&gt;
&lt;h6&gt;You have successfully logged out of the website. Thank you for visiting. If you want to login again, please &lt;a href="/"&gt;click here&lt;/a&gt;&lt;/h6&gt;
&lt;/center&gt;</code></pre>



<h4 class="wp-block-heading">Modify Home Page</h4>



<p>Let&#8217;s also add a logout link to our <em>homepage</em> template that we created in the previous article.</p>



<pre class="wp-block-code"><code>% layout 'master';
% title 'Home Page';
      &lt;a href="/logout"&gt;Log Out&lt;/a&gt;
      &lt;h1&gt;&lt;%= $msg %&gt;&lt;/h1&gt;
      &lt;h5 class="w3-padding-32"&gt;This is my personal site built with Mojolicious. You can provide testimonials using the link &lt;a href="#"&gt;here&lt;/a&gt;. 
&lt;/h5&gt;</code></pre>



<h2 class="wp-block-heading">Authentication and Session Management</h2>



<p>Our login and logout pages are ready, now time to add logic to authenticate the registered users using session cookies. We will create the below 3 subroutines in our controller (<em>CustomController.pm</em>*):</p>



<ul class="wp-block-list"><li>displayLogin</li><li>validUserCheck</li><li>alreadyLoggedIn</li><li>logout</li></ul>



<p>*<em>myWebSite/lib/myWebSite/Controller/CustomController.pm</em></p>



<h4 class="wp-block-heading">displayLogin</h4>



<p>This subroutine will display the <em>login page</em> template that we created in the previous section of this article. In case the user is already logged in, they will be redirected to the home page.</p>



<pre class="wp-block-code"><code>sub displayLogin {

    my $self = shift;

    # If already logged in then direct to home page, if not display login page
    if(&amp;alreadyLoggedIn($self)){
    # If you are using Mojolicious v9.25 and above use this if statement as re-rendering is forbidden
    # Thank you @Paul and @Peter for pointing this out.
    # if($self->session('is_auth')){

            &amp;welcome($self);

    }else{

       $self->render(template => "myTemplates/login", error_message =>  "");

    }

}</code></pre>



<h4 class="wp-block-heading">validUserCheck</h4>



<p>This subroutine will check the details entered by the user in the login page and authenticates the user to access the website. This also creates session cookies to keep the user&#8217;s session active. The users are prompted with proper error messages when incorrect credentials are passed. We set the variable <code>error_message</code> here which gets displayed in our <em>login.html.ep</em> template.</p>



<pre class="wp-block-code"><code>sub validUserCheck {

    my $self = shift;

    # List of registered users
    my %validUsers = ( "JANE" =&gt; "welcome123"
                      ,"JILL" =&gt; "welcome234"
                      ,"TOM"  =&gt; "welcome345"
                      ,"RAJ"  =&gt; "test123"
                      ,"RAM"  =&gt; "digitalocean123"
                     );

    # Get the user name and password from the page
    my $user = uc $self-&gt;param('username');
    my $password = $self-&gt;param('pass');

    # First check if the user exists
    if($validUsers{$user}){

        # Validating the password of the registered user
        if($validUsers{$user} eq $password){

            # Creating session cookies
            $self-&gt;session(is_auth =&gt; 1);             # set the logged_in flag
            $self-&gt;session(username =&gt; $user);        # keep a copy of the username
            $self-&gt;session(expiration =&gt; 600);        # expire this session in 10 minutes if no activity


            # Re-direct to home page
            &amp;welcome($self);

        }else{

            # If password is incorrect, re-direct to login page and then display appropriate message
            $self-&gt;render(template =&gt; "myTemplates/login", error_message =&gt;  "Invalid password, please try again");
        }

    }else{

        # If user does not exist, re-direct to login page and then display appropriate message
        $self-&gt;render(template =&gt; "myTemplates/login", error_message =&gt;  "You are not a registered user, please get the hell out of here!");

    }

}</code></pre>



<h4 class="wp-block-heading">alreadyLoggedIn</h4>



<p>This subroutine checks session cookies to see if the user has already logged in, if yes then the user will be automatically allowed to access the pages in the website</p>



<pre class="wp-block-code"><code>sub alreadyLoggedIn {

      my $self = shift;

      # checks if session flag (is_auth) is already set
      return 1 if $self-&gt;session('is_auth');


      # If session flag not set re-direct to login page again.
      $self-&gt;render(template =&gt; "myTemplates/login", error_message =&gt;  "You are not logged in, please login to access this website");

      return;

}</code></pre>



<h4 class="wp-block-heading">logout</h4>



<p>We need to destroy all the session cookies that were created when the user logged in, forcing any visitor to the website to enter the credentials again. <code>logout</code> subroutine does that.</p>



<pre class="wp-block-code"><code>sub logout {

    my $self = shift;

    # Remove session and direct to logout page
    $self-&gt;session(expires =&gt; 1);  #Kill the Session
    $self-&gt;render(template =&gt; "myTemplates/logout");

}</code></pre>



<p>After all these changes your controller should look like <a href="/wp-content/uploads/misc/CustomController.txt" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">this</a>.</p>



<p>Now we need to tell Mojolicious to call these subroutine whenever there is any action on the page. What handles the action on the page? If you have gone through the <a aria-label="undefined (opens in a new tab)" href="/mojolicious-part2-layouts-templates/" target="_blank" rel="noreferrer noopener">previous articles</a>, you know it&#8217;s the main library file: <em>myWebSite/lib/myWebSite.pm</em>. Right now we only have 1 routes in our main library file which looks like this:</p>



<pre class="wp-block-code"><code># Normal route to controller
$r-&gt;get('/')-&gt;to('CustomController#welcome');</code></pre>



<p>Lets add the routes to send requests to all the subroutines we created in the previous section</p>



<pre class="wp-block-code"><code># Normal route to controller
$r-&gt;get('/')-&gt;to('CustomController#displayLogin');
$r-&gt;post('/login')-&gt;to('CustomController#validUserCheck');
$r-&gt;any('/logout')-&gt;to('CustomController#logout');

my $authorized = $r-&gt;under('/')-&gt;to('CustomController#alreadyLoggedIn');</code></pre>



<p>Our main library file should finally look like <a aria-label="undefined (opens in a new tab)" href="/wp-content/uploads/misc/myWebSite.txt" target="_blank" rel="noreferrer noopener">this</a>.</p>



<p>Let us just try to understand quickly what all we are trying to do:</p>



<p><code>$r-&gt;get('/')-&gt;to('CustomController#login');</code> Whenever anyone accesses our root path of the website redirect them to <code>login</code> subroutine(which renders login page), instead of the home page which was the case before.</p>



<p><code>$r-&gt;post('/login')-&gt;to('CustomController#validUserCheck');</code> When the credentials are entered and submitted in the login page we will route the request to <code>validUserCheck</code> subroutine which basically validates the user, creates session cookies and redirects the user to website home page.</p>



<p><code>$r-&gt;any('/logout')-&gt;to('CustomController#logout');</code> Whenever <em>Log Out</em> link is clicked, it directs the request to <code>logout</code> subroutine which destroys the session cookies.</p>



<p><code>my $authorized = $r-&gt;under('/')-&gt;to('CustomController#alreadyLoggedIn');</code> This is a special condition. The &#8220;<strong>under</strong>&#8221; call ensures nothing after this statement gets executed, if the subroutine in &#8220;under&#8221; call fails(in our case the subroutine is <code>alreadyLoggedIn</code>). This is especially useful when we have multiple webpages and you want only authorized users has access to it. We will see this is our next session when we build our testimonials page.</p>



<h2 class="wp-block-heading">Verification</h2>



<p>I guess we have done everything that is required to enable authentication to our website. Let us not waste any more time and start our web application with morbo:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="772" height="321" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1.jpg" alt="" class="wp-image-362" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1.jpg 772w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1-768x319.jpg 768w" sizes="auto, (max-width: 772px) 100vw, 772px" /></figure></div>



<p>When we access our website now, we are greeted with the login page instead of the home page:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1185" height="815" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-page2.png" alt="" class="wp-image-442" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-page2.png 1185w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-page2-768x528.png 768w" sizes="auto, (max-width: 1185px) 100vw, 1185px" /></figure></div>



<p>If you give incorrect credentials, you will get not be allowed to login and will get the below messages:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1198" height="822" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-wrong-user.png" alt="" class="wp-image-443" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-wrong-user.png 1198w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-wrong-user-768x527.png 768w" sizes="auto, (max-width: 1198px) 100vw, 1198px" /><figcaption>incorrect username</figcaption></figure></div>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1040" height="740" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-wrong-password.png" alt="" class="wp-image-444" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-wrong-password.png 1040w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-login-wrong-password-768x546.png 768w" sizes="auto, (max-width: 1040px) 100vw, 1040px" /><figcaption>incorrect password</figcaption></figure></div>



<p>Valid users will be logged into the website and they can access the home page. They will also see a logout link in their home page.</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1279" height="868" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-homepage.png" alt="" class="wp-image-445" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-homepage.png 1279w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-new-homepage-768x521.png 768w" sizes="auto, (max-width: 1279px) 100vw, 1279px" /><figcaption>New homepage with logout</figcaption></figure></div>



<div class="wp-block-image is-style-default"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1257" height="840" src="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-logout-page.png" alt="" class="wp-image-446" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-logout-page.png 1257w, https://thecurioustechnoid.com/wp-content/uploads/2020/07/mojo-logout-page-768x513.png 768w" sizes="auto, (max-width: 1257px) 100vw, 1257px" /><figcaption>Logout Page</figcaption></figure></div>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p>With that we have secured our website. This completes the session management and user authentication part of Mojolicious tutorial. Ofcourse in the real world, you would validate the user credentials from your database with encrypted passwords. For the purpose of this demo, I have kept it simple. In the <a href="/mojolicious-part-4-database-management/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">next session</a>, we will cover <a href="/mojolicious-part-4-database-management/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">database management</a> in Mojolicious. You can watch the demo of this article in my youtube channel below.</p>



<figure class="wp-block-embed aligncenter is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Mojolicious (Part 3): Session Management" width="640" height="360" src="https://www.youtube.com/embed/SnGxyxe41fc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-part-3-session-management/">Mojolicious (Part 3): Session Management</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://thecurioustechnoid.com/mojolicious-part-3-session-management/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
		<item>
		<title>Mojolicious (Part 2): Layouts and Templates</title>
		<link>https://thecurioustechnoid.com/mojolicious-part2-layouts-templates/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mojolicious-part2-layouts-templates</link>
					<comments>https://thecurioustechnoid.com/mojolicious-part2-layouts-templates/#respond</comments>
		
		<dc:creator><![CDATA[Rakshith Chengappa Mullengada]]></dc:creator>
		<pubDate>Thu, 02 Jul 2020 05:00:38 +0000</pubDate>
				<category><![CDATA[Perl / Mojolicious]]></category>
		<category><![CDATA[mojolicious]]></category>
		<category><![CDATA[perl web framework]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[web framework]]></category>
		<guid isPermaLink="false">https://thecurioustechnoid.com/?p=376</guid>

					<description><![CDATA[<p>Now that we have our Home Page built in the previous article, let&#8217;s extend our project from it. Our home page looks quite dull and boring, so let&#8217;s add some color to it. This can be achieved by Layouts and Templates in Mojolicious. To start with, what we need is a nice looking HTML template.&#8230;</p>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-part2-layouts-templates/">Mojolicious (Part 2): Layouts and Templates</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Now that we have our Home Page built in the <a href="/mojolicious-part1-homepage/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">previous article</a>, let&#8217;s extend our project from it. Our home page looks quite dull and boring, so let&#8217;s add some color to it. This can be achieved by Layouts and Templates in Mojolicious. To start with, what we need is a nice looking HTML template. Then we embed that template so that Mojolicious starts considering it to render our pages. Let us take it step by step. Firstly, how different are Templates and Layouts ?</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://youtu.be/o1NCMK7Yaqo" target="_blank" rel="noopener noreferrer"><img loading="lazy" decoding="async" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/WatchOnYoutubeImage.png" alt="" class="wp-image-78" width="217" height="87"/></a></figure></div>



<p><em><strong>Layouts</strong></em> are reusable skeleton of your website. This generally would have your header, logo, footer, menus, side bar etc<br><em><strong>Templates</strong></em> are the dynamic content that you want to display based on different actions on the web portal. This is generally the content that needs to be inside the layout.</p>



<h3 class="wp-block-heading">Download Template</h3>



<p>To put it into action, let&#8217;s download a free HTML template from the internet. I downloaded one from <a href="https://www.w3schools.com/w3css/tryw3css_templates_start_page.htm" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">w3 schools</a>. </p>



<p>It looks like this:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1541" height="895" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-original-template-1.jpg" alt="" class="wp-image-378" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-original-template-1.jpg 1541w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-original-template-1-768x446.jpg 768w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-original-template-1-1536x892.jpg 1536w" sizes="auto, (max-width: 1541px) 100vw, 1541px" /></figure></div>



<p>You can get the <a aria-label="undefined (opens in a new tab)" href="/wp-content/uploads/misc/w3school-html-template.txt" target="_blank" rel="noreferrer noopener">source code here</a>.</p>



<h3 class="wp-block-heading">Create a Layout</h3>



<p>Let us make this HTML template as a <strong>layout</strong> in Mojolicious, so that we can use it across our pages. To do so, lets follow the below steps:</p>



<table style="width: 100%;" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr style="vertical-align: top;">
<td style="width: 9.827586206896552%;">              </td>
<td style="width: 3.9655172413793105%;">1.</td>
<td style="width: 85.86206896551725%;">Create a file called: <em>myWebSite/templates/layouts/master.html.ep</em> with the source code of the HTML we downloaded in the previous section. This will be our <em><strong>layout</strong></em> with name: <em>master</em></td>
</tr>
<tr style="vertical-align: top;">
<td style="width: 9.827586206896552%;">              </td>
<td style="width: 3.9655172413793105%;">2.  </td>
<td style="width: 85.86206896551725%;">Remove the section which you think will not be static across the pages. I will comment the &#8220;Second Grid&#8221; section. I don&#8217;t mind all my website pages having the rest of the content from the downloaded HTML template.</td>
</tr>
<tr style="vertical-align: top;">
<td style="width: 9.827586206896552%;">              </td>
<td style="width: 3.9655172413793105%;">3.</td>
<td style="width: 85.86206896551725%;">I will also change parts of &#8220;First Grid&#8221; section and add the line: <code>&lt;%= content %&gt;</code>. <em><strong>content</strong></em> is a Mojolicious helper which will have static or dynamic data mentioned in the Mojolicious <em><strong>template</strong></em> (which we will see in the next section).</td>
</tr>
<tr style="vertical-align: top;">
<td style="width: 9.827586206896552%;">              </td>
<td style="width: 3.9655172413793105%;">4.  </td>
<td style="width: 85.86206896551725%;">Also instead of static title, replace the title with <code>&lt;%= title %&gt;</code>. You can dynamically change the title value from the Mojolicious <em><strong>template</strong></em>.</td>
</tr>
<tr style="vertical-align: top;">
<td style="width: 9.827586206896552%;">              </td>
<td style="width: 3.9655172413793105%;">5.</td>
<td style="width: 85.86206896551725%;">Also, I replaced the text &#8220;START PAGE&#8221; with title helper: <code>&lt;%= title %&gt;</code></td>
</tr>
<tr style="vertical-align: top;">
<td style="width: 9.827586206896552%;">              </td>
<td style="width: 3.9655172413793105%;">6.</td>
<td style="width: 85.86206896551725%;">Since we only have home page now, I will also comment all the other menu links: <em>Link 1</em>, <em>Link 2</em> etc.</td>
</tr>
</tbody>
</table>



<p>We will finally have the <strong>layout</strong> file, <a aria-label="undefined (opens in a new tab)" href="/wp-content/uploads/misc/master.html.ep.txt" target="_blank" rel="noreferrer noopener">master.html.ep</a> which looks <a aria-label="undefined (opens in a new tab)" href="/wp-content/uploads/misc/master.html.ep.txt" target="_blank" rel="noreferrer noopener">like this</a>. You can check comments by <strong>The Curious Technoid</strong> to know the changes I did to the original file.</p>



<p>This will be our <em><strong>layout</strong></em> which is our website skeleton and will be used across our website. We will only change the <em><strong>content</strong></em> and <em><strong>title</strong></em> dynamically using Mojolicious <strong><em>templates</em></strong>.</p>



<h3 class="wp-block-heading">Create Templates</h3>



<p>Now that we have our website <em><strong>layout</strong></em> in place, we will create <strong><em>templates</em></strong> from where these <strong><em>layouts</em></strong> gets called from. If you have gone through the <a aria-label="undefined (opens in a new tab)" href="/mojolicious-part1-homepage/" target="_blank" rel="noreferrer noopener">previous article</a>, you have already created a new <strong><em>template</em></strong> called: <em>myWebSite/templates/myTemplates/homepage.html.ep</em> which looks like this:</p>



<pre class="wp-block-code"><code>% layout 'default';
% title 'Home Page';
&lt;h2>&lt;%= $msg %>&lt;/h2>
&lt;p> This is my personal site built with Mojolicious. You can provide testimonials using the link &lt;a href="#">here&lt;/a>. 
&lt;/p></code></pre>



<p>Lets change it to call our newly created <strong><em>layout</em></strong> <em>master.html.ep</em>. We also add our &#8220;content&#8221; using the same <em>HTML tag</em> and <em>CSS Class</em> which was their in the original HTML source:</p>



<pre class="wp-block-code"><code>% layout 'master';
% title 'Home Page';
&lt;h1>&lt;%= $msg %>&lt;/h1>
&lt;h5 class="w3-padding-32"> This is my personal site built with Mojolicious. You can provide testimonials using the link &lt;a href="#">here&lt;/a>. 
&lt;/h5></code></pre>



<p><code>% layout 'master';</code> tells Mojolicious which <strong><em>layout</em></strong> to use<br><code>% title 'Home Page';</code> &#8211; the title helper which gets replaced in <strong><em>layout</em></strong><br>Any <strong>HTML data</strong> you enter in the <strong><em>template</em></strong> will be displayed in the <code>&lt;%= content %&gt;</code> section of the <strong><em>layout</em></strong>.</p>



<h3 class="wp-block-heading">Verify Changes</h3>



<p>Now that we have our <strong><em>templates</em></strong> and <strong><em>layouts</em></strong> in place. Lets start our web application using <em>morbo</em>:</p>



<pre class="wp-block-code"><code>morbo myWebSite/script/myWebSite</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="772" height="321" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1.jpg" alt="" class="wp-image-362" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1.jpg 772w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1-768x319.jpg 768w" sizes="auto, (max-width: 772px) 100vw, 772px" /></figure></div>



<p>Since we have <a href="/ssh-tunneling/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">SSH Tunnel</a> enabled as usual, we will check our website using local host and port 3000:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1546" height="894" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-homepage-new-template-1.png" alt="" class="wp-image-380" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-homepage-new-template-1.png 1546w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-homepage-new-template-1-768x444.png 768w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-html-homepage-new-template-1-1536x888.png 1536w" sizes="auto, (max-width: 1546px) 100vw, 1546px" /></figure></div>



<p>Our website doesn&#8217;t look that bad now, does it.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p>In the <a href="/mojolicious-part-3-session-management/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">next article</a>, we will make our website accessible by only registered users using sessions and cookies.</p>



<figure class="wp-block-embed-youtube aligncenter wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Mojolicious (Part 2): Templates and Layouts" width="640" height="360" src="https://www.youtube.com/embed/o1NCMK7Yaqo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-part2-layouts-templates/">Mojolicious (Part 2): Layouts and Templates</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://thecurioustechnoid.com/mojolicious-part2-layouts-templates/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mojolicious (Part 1): Build Full App</title>
		<link>https://thecurioustechnoid.com/mojolicious-part1-homepage/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mojolicious-part1-homepage</link>
					<comments>https://thecurioustechnoid.com/mojolicious-part1-homepage/#respond</comments>
		
		<dc:creator><![CDATA[Rakshith Chengappa Mullengada]]></dc:creator>
		<pubDate>Sat, 27 Jun 2020 11:51:40 +0000</pubDate>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[Perl / Mojolicious]]></category>
		<category><![CDATA[mojolicious]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[web framework]]></category>
		<guid isPermaLink="false">https://thecurioustechnoid.com/?p=349</guid>

					<description><![CDATA[<p>In the previous article we looked at how to install Mojolicious, build a hello world web app, test it and deploy the same in the instance. In the course of next few articles, we will look at building a mini project which covers session management, database connections, templates and layouts. Test Case Synopsis The test&#8230;</p>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-part1-homepage/">Mojolicious (Part 1): Build Full App</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In the <a aria-label="undefined (opens in a new tab)" href="/mojolicious-intro-hello-world/" target="_blank" rel="noreferrer noopener">previous article</a> we looked at how to install Mojolicious, build a hello world web app, test it and deploy the same in the instance. In the course of next few articles, we will look at building a mini project which covers <a href="/mojolicious-part-3-session-management/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">session management</a>, <a href="/mojolicious-part-4-database-management/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">database connections</a>, <a href="/mojolicious-part2-layouts-templates/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">templates and layouts</a>.</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://youtu.be/EdZNpI_t3Fw" target="_blank" rel="noopener noreferrer"><img loading="lazy" decoding="async" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/WatchOnYoutubeImage.png" alt="" class="wp-image-78" width="217" height="87"/></a></figure></div>



<h2 class="wp-block-heading">Test Case Synopsis</h2>



<p>The test case that we have is to build a web application for testimonials. That&#8217;s the easiest one that I could think of to cover the topics I want to discuss. The web application will have the following features:</p>



<ul class="wp-block-list"><li><strong>Login Page:</strong> Which restricts website access to registered users</li><li><strong>Home Page: </strong>Main page for the registered users with a welcome message and website instructions</li><li><strong>Testimonial Page: </strong>Testimonial Page which displays all the testimonials from database entered by the users and option to save new testimonials in the database</li><li><strong>Log Out: </strong>To gracefully logout of the website</li></ul>



<p>We will also add a simple HTML template to the website which would cover the templates and layouts concept in Mojolicious.</p>



<p>Without further adieu, let&#8217;s begin building this project.</p>



<h2 class="wp-block-heading">Create full_app project</h2>



<p>In our previous tutorial on Mojolicious, we created &#8220;Hello World&#8221; web app with <em>lite_app</em>. This time we will build this project with <em>full_app</em>. To create a <em>full_app</em>, open the terminal and enter the below command:</p>



<pre class="wp-block-code"><code>mojo generate app myWebSite</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="758" height="857" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo_generate_full-1.jpg" alt="" class="wp-image-359"/></figure></div>



<p>This will create a directory called <strong>myWebSite</strong> with the below folder structure:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="612" height="817" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo_full_tree.jpg" alt="" class="wp-image-360"/></figure></div>



<p>Lets understand the below components from the above screenshot</p>



<ul class="wp-block-list"><li>lib</li><li>myWebSite.conf</li><li>public</li><li>script</li><li>t</li><li>templates</li></ul>



<h4 class="wp-block-heading">lib</h4>



<p>The library directory is probably the most crucial directory which holds all your programming code. Your Controller and Model logic goes here. The logic to handle any action on your webpage will be somewhere in this directory.</p>



<p>Your routes and page-actions are sent to the file <code>myWebSite/lib/myWebSite.pm</code> which then invokes the relevant Controller and Model to handle your requests.</p>



<h4 class="wp-block-heading">myWebSite.conf</h4>



<p>This is the master configuration file for your web app. You can add secret phrases for signed cookies, mention the number of workers that you want webservers to run, the port that your application should run on, database connection details, so on and so forth.</p>



<h4 class="wp-block-heading">public</h4>



<p>You can find all your static pages here. Along with the static pages, all publicly available components like your css, images or any other media goes into this directory.</p>



<h4 class="wp-block-heading">script</h4>



<p>Script to start your web site is present in this directory. You run you web app using the <code>script/myWebSite</code> file present in this directory.</p>



<h4 class="wp-block-heading">t</h4>



<p>Folder dedicated for your test scripts.</p>



<h4 class="wp-block-heading">templates</h4>



<p>Directory which holds the templates and layouts used by your web app.</p>



<p>I will not go in detail about the theory as you can always read more about it in the <a href="http://mojolicious.org/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">official website</a> of Mojolicious. Let us proceed with our project.</p>



<p>Let&#8217;s go ahead and run this sample web app as it is, using the development web server morbo:</p>



<pre class="wp-block-code"><code>morbo myWebSite/script/myWebSite</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="772" height="321" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1.jpg" alt="" class="wp-image-362" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1.jpg 772w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo_full_1-768x319.jpg 768w" sizes="auto, (max-width: 772px) 100vw, 772px" /></figure></div>



<p>Since we don&#8217;t see any errors, let&#8217;s fire up the browser and check our page (I have <a href="/ssh-tunneling/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">SSH Tunnel</a> enabled, so I can access the webpage with localhost IP and default port(3000):</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="724" height="242" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo_full_samplepage.png" alt="" class="wp-image-363"/></figure>



<p>Our Website is running fine.</p>



<p>How did our website&#8217;s content get rendered ? Let us understand the flow of events. First, let me just remind you how the structure of your web application looks like:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="612" height="817" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo_full_tree.jpg" alt="" class="wp-image-360"/></figure>



<p>Below diagram shows the flow of events from different files when you access your web page:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1543" height="903" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/MojoControlFlow-1.jpg" alt="" class="wp-image-354" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/MojoControlFlow-1.jpg 1543w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/MojoControlFlow-1-768x449.jpg 768w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/MojoControlFlow-1-1536x899.jpg 1536w" sizes="auto, (max-width: 1543px) 100vw, 1543px" /></figure></div>



<p>Whenever you access any web page built in mojolicious, the first file that gets called is the library file: <em>lib/myWebSite.pm</em>. The line <code>$r-&gt;get('/')-&gt;to('example#welcome');</code> in the file basically tells to go to the controller <em>Example.pm</em> and execute the <em>welcome</em> sub-routine. Controllers, as you can see in the above screenshot are stored in <em>lib/myWebSite/Controller</em>.</p>



<p>In the controller we see the below lines:</p>



<pre class="wp-block-code"><code># Render template "example/welcome.html.ep" with message
$self->render(msg => 'Welcome to the Mojolicious real-time web framework!');</code></pre>



<p>This basically tells Mojolicious to set a value to the variable <code>$msg</code> and render the template. But which template ? We don&#8217;t see any template name mentioned in the controller, then which page is getting rendered?? Well, since no template is explicitly called Mojolicious will look for the template is the path similar to the controller path: <em>example/welcome</em>. In the above directory structure, we can see a template: <em>template/example/welcome.html.ep</em>, that&#8217;s what is getting rendered in the home page now. Ofcourse, you can explicitly mention the template name in the controller and it will exactly behave the same way. Just pass the template name like this:</p>



<pre class="wp-block-code"><code>  $self->render(msg => 'Welcome to the Mojolicious real-time web framework!',template => "example/welcome");</code></pre>



<p>I prefer explicitly mentioning the template names in my controller, to avoid any confusion.</p>



<p>Now that we know that our main page&#8217;s content is being displayed by <em>myWebSite/templates/example/welcome.html.ep</em> and the contents looks like this:</p>



<pre class="wp-block-code"><code>% layout 'default';
% title 'Welcome';
&lt;h2>&lt;%= $msg %>&lt;/h2>
&lt;p>
  This page was generated from the template "templates/example/welcome.html.ep"
  and the layout "templates/layouts/default.html.ep",
  &lt;%= link_to 'click here' => url_for %> to reload the page or
  &lt;%= link_to 'here' => '/index.html' %> to move forward to a static page.
&lt;/p></code></pre>



<p>We will change it to add our content:</p>



<pre class="wp-block-code"><code>% layout 'default';
% title 'Home Page';
&lt;h2>&lt;%= $msg %>&lt;/h2>
&lt;p> This is my personal site built with Mojolicious. You can provide testimonials using the link &lt;a href="#">here&lt;/a>. 
&lt;/p></code></pre>



<p>If you notice that the heading in the above html content is displayed by the variable <code>$msg</code>. This was set by our controller: <em>myWebSite/lib/myWebSite/Controller/Example.pm</em>. Let us open the controller file and change the below line:</p>



<pre class="wp-block-code"><code># Render template "example/welcome.html.ep" with message
$self->render(msg => 'Welcome to the Mojolicious real-time web framework!');</code></pre>



<p>to</p>



<pre class="wp-block-code"><code># Render template "example/welcome.html.ep" with message
$self->render(msg => 'Welcome to My Personal Website!',template => "example/welcome");</code></pre>



<p>Not only did I change the heading, I also explicitly mentioned which template to render.</p>



<p>Lets run our web app with morbo:</p>



<pre class="wp-block-code"><code>morbo myWebSite/script/myWebSite</code></pre>



<p>Refresh our web browser:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="724" height="256" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo_morbo_2.png" alt="" class="wp-image-364"/></figure>



<p>Working as expected. Before we wind up, lets just change the default controller and template files to our customized file names:</p>



<pre class="wp-block-code"><code>cp myWebSite/lib/myWebSite/Controller/Example.pm myWebSite/lib/myWebSite/Controller/CustomController.pm</code></pre>



<pre class="wp-block-code"><code>mkdir myWebSite/templates/myTemplates</code></pre>



<pre class="wp-block-code"><code>cp myWebSite/templates/example/welcome.html.ep myWebSite/templates/myTemplates/homepage.html.ep</code></pre>



<p><strong>New Controller Name : </strong><em>myWebSite/lib/myWebSite/Controller/CustomController.pm</em><br><strong>New Template Name : </strong><em>myWebSite/templates/myTemplates/homepage.html.ep</em></p>



<p>Open the new controller(CustomController.pm) and change the first line to reflect the new controller name, from:</p>



<pre class="wp-block-code"><code>package myWebSite::Controller::Example;</code></pre>



<p>to</p>



<pre class="wp-block-code"><code>package myWebSite::Controller::CustomController;</code></pre>



<p>Now change the below line in the same file to point to our newly created template: <em>myTemplates/homepage</em></p>



<pre class="wp-block-code"><code># Render template "example/welcome.html.ep" with message
$self->render(msg => 'Welcome to My Personal Website!',template => "example/welcome");</code></pre>



<p>to</p>



<pre class="wp-block-code"><code># Render template "myTemplates/homepage.html.ep" with message
$self->render(msg => 'Welcome to My Personal Website!',template => "myTemplates/homepage");</code></pre>



<p>Finally, open the main library file: <em>myWebSite/lib/myWebSite.pm</em> and change the below line to call our now custom controller rather than the default:</p>



<pre class="wp-block-code"><code>$r->get('/')->to('example#welcome');</code></pre>



<p>to</p>



<pre class="wp-block-code"><code>$r->get('/')->to('CustomController#welcome');</code></pre>



<p>Lets start our web app and refresh the browser:</p>



<pre class="wp-block-code"><code>morbo myWebSite/script/myWebSite</code></pre>



<div class="wp-block-image"><figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="686" height="265" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo_full_page_final.jpg" alt="" class="wp-image-366"/></figure></div>



<p>You will not see any changes since we didn&#8217;t change the content. But we also didn&#8217;t see any errors that means we have achieved what we want.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p>We successfully created the home page of your website. In the <a href="/mojolicious-part2-layouts-templates/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">next session</a>, we will learn about templates and layouts. We will try to add some color to our dull home page that we created in this article.</p>



<figure class="wp-block-embed-youtube aligncenter wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Mojolicious (Part 1): Build Full App (Home page)" width="640" height="360" src="https://www.youtube.com/embed/EdZNpI_t3Fw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-part1-homepage/">Mojolicious (Part 1): Build Full App</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://thecurioustechnoid.com/mojolicious-part1-homepage/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Mojolicious: &#8220;Hello World&#8221; with Mojolicious::Lite</title>
		<link>https://thecurioustechnoid.com/mojolicious-intro-hello-world/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mojolicious-intro-hello-world</link>
					<comments>https://thecurioustechnoid.com/mojolicious-intro-hello-world/#respond</comments>
		
		<dc:creator><![CDATA[Rakshith Chengappa Mullengada]]></dc:creator>
		<pubDate>Sun, 21 Jun 2020 12:13:02 +0000</pubDate>
				<category><![CDATA[Perl / Mojolicious]]></category>
		<category><![CDATA[mojolicious]]></category>
		<category><![CDATA[perl web framework]]></category>
		<guid isPermaLink="false">https://thecurioustechnoid.com/?p=291</guid>

					<description><![CDATA[<p>Mojolicious is a full fledged Perl web development framework developed by the original author of Catalyst framework. You can start building websites with it very quickly and easily. It&#8217;s a very powerful web development tool with tons of features which will enable you to build any web application. Recently, I started experimenting on it and&#8230;</p>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-intro-hello-world/">Mojolicious: &#8220;Hello World&#8221; with Mojolicious::Lite</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Mojolicious is a full fledged Perl web development framework developed by the original author of Catalyst framework. You can start building websites with it very quickly and easily. It&#8217;s a very powerful web development tool with tons of features which will enable you to build any web application. Recently, I started experimenting on it and thought would share what I have learnt so far. I will only cover the basics of Mojolicious, which should help you in getting started with this web framework.</p>



<div class="wp-block-image"><figure class="aligncenter size-large is-resized"><a href="https://youtu.be/LC9UFVbBp2I" target="_blank" rel="noopener noreferrer"><img loading="lazy" decoding="async" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/WatchOnYoutubeImage.png" alt="" class="wp-image-78" width="217" height="87"/></a></figure></div>



<p>I strongly suggest you visit the <a rel="noreferrer noopener" href="https://mojolicious.org" target="_blank">official website</a> for in depth documentation:<br><center><a href="https://mojolicious.org" target="_blank" rel="noopener noreferrer"><img loading="lazy" decoding="async" width="161" height="38" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojolicious-logo1.png" alt="" class="wp-image-294"></a></center></p><br>



<p>Articles on Mojolicious are published with an assumption that you have basic knowledge on Perl and fundamental idea on how web pages work.</p>



<p>In this article, we will look at Mojolicious::Lite, a Micro real-time web framework(as it&#8217;s author puts it). It&#8217;s a light weight domain specific language built around Mojolicious. This can be used for your tiny one page projects. We will cover the following topics in this blog:</p>



<ol class="wp-block-list"><li>Installation of Mojolicious</li><li>Building a simple &#8220;Hello World&#8221; app with Mojolicious::Lite</li><li>Testing</li><li>Deployment</li></ol>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Installation</h2>



<p>There are 2 different methods to install Mojolicious. You can chose whichever method you find convenient:</p>



<h4 class="wp-block-heading">Method 1</h4>



<p>Installation of the powerful Mojolicious framework can be achieved using only a single-line command. Open the terminal in your server and run the below command:</p>



<pre class="wp-block-code"><code>curl -L https://cpanmin.us | perl - -M https://cpan.metacpan.org -n Mojolicious</code></pre>



<p><em><sup><span style="color:#cf2e2e" class="tadv-color">*source: <a href="https://mojolicious.org" target="_blank" rel="noreferrer noopener">https://mojolicious.org</a></span></sup></em></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1285" height="479" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-install.jpg" alt="" class="wp-image-309" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-install.jpg 1285w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-install-768x286.jpg 768w" sizes="auto, (max-width: 1285px) 100vw, 1285px" /></figure>



<p>That&#8217;s all, this will install the full Mojolicious framework.</p>



<h4 class="wp-block-heading">Method 2</h4>



<p>Alternatively, you can also install it with traditional CPAN command similar to installing any Perl module:</p>



<pre class="wp-block-code"><code>cpanm Mojolicious</code></pre>



<p>OR</p>



<pre class="wp-block-code"><code>perl -MCPAN -e shell
install Mojolicious</code></pre>



<p>This also installs full Mojolicious framework that required to build web applications.</p>



<p>Trust me when I say it, use the <strong>Method 1</strong>, it&#8217;s faster to install that way.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">&#8220;Hello World&#8221; with Mojolicious::Lite</h2>



<p>We have Mojolicious installed in our server by following the previous step, now lets go ahead and create a <em>lite_app</em> and try to bring the famous <strong>&#8220;Hello World&#8221;</strong> page live in that server.</p>



<p>You can create the <em>lite_app</em> using the below command. <em>lite_app</em> are usually used for simple projects involving probably a single page. Let us create a <em>lite_app</em> called <strong>hellomojo</strong> using the command:</p>



<pre class="wp-block-code"><code>mojo generate lite_app hellomojo</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="955" height="357" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-new-lite-project.png" alt="" class="wp-image-311" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-new-lite-project.png 955w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-new-lite-project-768x287.png 768w" sizes="auto, (max-width: 955px) 100vw, 955px" /></figure>



<p>The above command will create a file called <strong>hellomojo</strong> in your current directory:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="786" height="404" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-new-lite-project-list.png" alt="" class="wp-image-312" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-new-lite-project-list.png 786w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-new-lite-project-list-768x395.png 768w" sizes="auto, (max-width: 786px) 100vw, 786px" /></figure>



<p>The <strong>hellomojo</strong> file created is a working sample webpage. You can start building your project on top of this file. The contents of the file will look something like this:</p>



<pre class="wp-block-code"><code>#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
  my $c = shift;
  $c->render(template => 'index');
};

app->start;
__DATA__

@@ index.html.ep
% layout 'default';
% title 'Welcome';
&lt;h1>Welcome to the Mojolicious real-time web framework!&lt;/h1>

@@ layouts/default.html.ep
&lt;!DOCTYPE html>
&lt;html>
  &lt;head>&lt;title>&lt;%= title %>&lt;/title>&lt;/head>
  &lt;body>&lt;%= content %>&lt;/body>
&lt;/html></code></pre>



<p>The sample file is easily understandable for anyone familiar with Perl. The contents after <strong><em>_DATA_</em></strong> is treated as templates and layouts that the code uses to display the web content. We will see more about templates and layouts when we build a test project with <em>full_app</em> in future sessions.</p>



<p>For our <strong>&#8220;Hello World&#8221;</strong> page, we will change the contents of hellomojo to look like this:</p>



<pre class="wp-block-code"><code>#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
  my $c = shift;
  $c->render(template => 'index');
};

app->start;
__DATA__

@@ index.html.ep
% layout 'default';
% title 'Hello World Tutorial with Mojolicious';
&lt;h1>Hello World!!&lt;/h1>

@@ layouts/default.html.ep
&lt;!DOCTYPE html>
&lt;html>
  &lt;head>&lt;title>&lt;%= title %>&lt;/title>&lt;/head>
  &lt;body>&lt;%= content %>&lt;/body>
&lt;/html></code></pre>



<p>We only changed the below two lines in the file i.e., the window title and the content.</p>



<p><code>% title 'Hello World Tutorial with Mojolicious';<br>&lt;h1&gt;Hello World!!&lt;/h1&gt;</code></p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Testing</h2>



<p>We changed the default sample page&#8217;s content to add our <strong>&#8220;Hello World&#8221;</strong> text. Now let&#8217;s go ahead and test the page. We can test the pages created in Mojolicious using the development web server <em><strong>morbo</strong></em>. Lets not waste any time and go ahead and execute the below command to run our <strong>hellomojo</strong> web app:</p>



<pre class="wp-block-code"><code>morbo hellomojo</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="733" height="254" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-morbo.jpg" alt="" class="wp-image-313"/></figure>



<p>We can see that our page is running. <strong><em>morbo</em></strong> also gives us the URL with port where our website is running:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="570" height="35" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-morbo-port.png" alt="" class="wp-image-314"/></figure>



<p>By default, morbo runs our pages on port 3000. Since <strong><em>morbo </em></strong>is a development web server, debugging is enabled by default and the web server runs in the foreground with debug messages. As we don&#8217;t see any errors on the terminal, the page looks fine.</p>



<p>We won&#8217;t be able to access the webpage from the local Desktop since port 3000 will not be open in the server. Either we open the port in the firewall, or use <a rel="noreferrer noopener" href="/ssh-tunneling/" target="_blank">SSH Tunneling</a>. I prefer SSH Tunneling, <a rel="noreferrer noopener" href="/ssh-tunneling/" target="_blank">read more about SSH Tunneling here</a>.</p>



<p>Let us go ahead and start a SSH Tunnel to our server from the local Desktop using <a href="/how-to-setup-ssh-keys/" target="_blank" rel="noreferrer noopener">SSH Keys</a>:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="965" height="250" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-ssh-tunnel.jpg" alt="" class="wp-image-315" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-ssh-tunnel.jpg 965w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-ssh-tunnel-768x199.jpg 768w" sizes="auto, (max-width: 965px) 100vw, 965px" /></figure>



<p>Now that the SSH Tunnel is active, lets go ahead and check our page from our browser using the server&#8217;s localhost IP(since SSH Tunnel is running) and morbo&#8217;s port(3000): http://127.0.0.1:3000</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="885" height="272" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo-hello-world-page.jpg" alt="" class="wp-image-317" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo-hello-world-page.jpg 885w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/morbo-hello-world-page-768x236.jpg 768w" sizes="auto, (max-width: 885px) 100vw, 885px" /></figure>



<p>Success!! We have a working &#8220;Hello World&#8221; page ready to be deployed.</p>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Deployment</h2>



<p>Now that we tested and made sure that our <strong>&#8220;Hello World&#8221;</strong> page is working fine, we will deploy it in the server so that it runs all the time. There are different production web servers which gets shipped with Mojolicious (you can <a href="https://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Hypnotoad" target="_blank" rel="noreferrer noopener">read more about it here</a>), I use <em><strong>hypnotoad</strong></em> &#8211; ALL GLORY TO THE HYPNOTOAD!. It&#8217;s a recommended production grade web server to run Mojolicious web apps.</p>



<p>The command to run your page using <strong><em>hypnotoad</em></strong> is similar to <em>morbo</em>:</p>



<pre class="wp-block-code"><code>hypnotoad hellomojo</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="803" height="314" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-hypno.jpg" alt="" class="wp-image-319" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-hypno.jpg 803w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-hypno-768x300.jpg 768w" sizes="auto, (max-width: 803px) 100vw, 803px" /></figure>



<p><strong><em>hypnotoad</em></strong> by default runs on port 8080(which can be changed ofcourse) and runs in the background. Lets fire up the terminal and establish a new <a rel="noreferrer noopener" href="/ssh-tunneling/" target="_blank">SSH Tunnel</a> to our web server on port 8080 this time. Now we can access our <strong>&#8220;Hello World&#8221;</strong> page using the webserver&#8217;s local host IP(because we are connected with SSH Tunnel) on port 8080: http://127.0.0.1:8080</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="944" height="321" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-ssh-tunnel-hypno.jpg" alt="" class="wp-image-320" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-ssh-tunnel-hypno.jpg 944w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-ssh-tunnel-hypno-768x261.jpg 768w" sizes="auto, (max-width: 944px) 100vw, 944px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="832" height="292" src="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-hypno-hello-world-page.png" alt="" class="wp-image-325" srcset="https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-hypno-hello-world-page.png 832w, https://thecurioustechnoid.com/wp-content/uploads/2020/06/mojo-hypno-hello-world-page-768x270.png 768w" sizes="auto, (max-width: 832px) 100vw, 832px" /></figure>



<p>There we have it. Our <strong>&#8220;Hello World&#8221;</strong> webpage is running to serve the whole world with it&#8217;s simplicity and humbleness.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p>This was a little introduction as to how to build and deploy Mojolicious apps. In the <a aria-label="undefined (opens in a new tab)" href="/mojolicious-part1-homepage/" target="_blank" rel="noreferrer noopener">next few sessions</a>, we will build a test project using Mojolicious <em>full_app</em> covering <a href="/mojolicious-part2-layouts-templates/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">templates</a>, <a href="/mojolicious-part2-layouts-templates/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">layouts</a>, <a href="/mojolicious-part-3-session-management/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">session management</a> and <a href="/mojolicious-part-4-database-management/" target="_blank" aria-label="undefined (opens in a new tab)" rel="noreferrer noopener">database connections</a>. Stay tuned.</p>



<p>I strongly suggest you to go through the video tutorials in <a rel="noreferrer noopener" href="http://mojocasts.com" target="_blank">this website</a> called the <a rel="noreferrer noopener" href="http://mojocasts.com" target="_blank">MojoCasts</a>. You can find tremendously useful tutorials on Mojolicious in that website. You can also check this <a rel="noreferrer noopener" href="https://dev.to/akuks/mojoforum-a-forum-in-mojolicious-part-1-4ojd" target="_blank">informative tutorial</a> written by Ashutosh in <a rel="noreferrer noopener" href="https://dev.to/akuks/mojoforum-a-forum-in-mojolicious-part-1-4ojd" target="_blank">dev.to</a>.</p>



<figure class="wp-block-embed-youtube aligncenter wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Mojolicious Web Development Tool - Introduction" width="640" height="360" src="https://www.youtube.com/embed/LC9UFVbBp2I?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
<p>The post <a href="https://thecurioustechnoid.com/mojolicious-intro-hello-world/">Mojolicious: &#8220;Hello World&#8221; with Mojolicious::Lite</a> appeared first on <a href="https://thecurioustechnoid.com">The Curious Technoid</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://thecurioustechnoid.com/mojolicious-intro-hello-world/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/

Page Caching using Disk: Enhanced 
Database Caching 27/60 queries in 0.008 seconds using Disk

Served from: thecurioustechnoid.com @ 2026-07-30 02:01:30 by W3 Total Cache
-->