<?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>web development Archives | The Curious Technoid</title>
	<atom:link href="https://thecurioustechnoid.com/tag/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>https://thecurioustechnoid.com/tag/web-development/</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.4</generator>

<image>
	<url>https://thecurioustechnoid.com/wp-content/uploads/2020/06/cropped-fav-1-32x32.png</url>
	<title>web development Archives | The Curious Technoid</title>
	<link>https://thecurioustechnoid.com/tag/web-development/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<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 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 fetchpriority="high" 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="(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 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="(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>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/

Page Caching using Disk: Enhanced 
Database Caching 28/49 queries in 0.007 seconds using Disk

Served from: thecurioustechnoid.com @ 2026-04-19 09:00:51 by W3 Total Cache
-->