<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rajat Saxena</title>
    <description>The latest articles on DEV Community by Rajat Saxena (@rajatsx).</description>
    <link>https://dev.to/rajatsx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F375156%2F7d08f6a6-af8a-4801-9a0b-04d5072f4a54.jpg</url>
      <title>DEV Community: Rajat Saxena</title>
      <link>https://dev.to/rajatsx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rajatsx"/>
    <language>en</language>
    <item>
      <title>Building A LMS: What I Have Accomplished In Two Years</title>
      <dc:creator>Rajat Saxena</dc:creator>
      <pubDate>Sat, 06 Mar 2021 06:48:35 +0000</pubDate>
      <link>https://dev.to/rajatsx/building-a-lms-what-i-have-accomplished-in-two-years-29f6</link>
      <guid>https://dev.to/rajatsx/building-a-lms-what-i-have-accomplished-in-two-years-29f6</guid>
      <description>&lt;p&gt;I originally published this post on my Medium blog but I am reposting it here for the DEV.to community and to draw more attention to my project to be honest.&lt;/p&gt;




&lt;p&gt;Exactly two years ago, I embarked on a journey of creating my own little learning management system (aka LMS aka CMS for educators). I named it CourseLit and here is its landing page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://courselit.app"&gt;CourseLit - Sell online courses and digital downloads from your own website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have been a solo developer working on this open source project. I have detailed my reasons for building a LMS in this post, if you are wondering why would anyone be insane enough to develop his own CMS when there are many out there.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Creating a CMS is no easy task. There are features, design, security and many other things to take care of.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl687t94uq9yfp3m9pmk9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl687t94uq9yfp3m9pmk9.png" alt="My Production Site CodeLit.dev (Powered by CourseLit LMS)" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Coming back to my progress, I am going to divide this article into two parts i.e. Technical Front and Marketing Front.&lt;/p&gt;

&lt;p&gt;Till today, I have mostly focused on the technical front and it is going to be my primary focus until CourseLit hits 1.0-rc. I have done some marketing here and there but I have a lot to do in this area (suggestions most welcome).&lt;/p&gt;

&lt;p&gt;So, let's begin.&lt;/p&gt;

&lt;h1&gt;
  
  
  Technical Achievements
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Admin Dashboard
&lt;/h2&gt;

&lt;p&gt;The front-end app is a monolith which means that both the non-admin area and the admin area are the parts of the same Next.js app. Using the admin area, one can customize almost every aspect of her teaching site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5t4bgjezuu420pkn139a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5t4bgjezuu420pkn139a.png" alt="Admin Dashboard Of CourseLit" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of my development time goes towards bettering this area as I want the admins/creators to have a good time while authoring courses and managing sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Themes
&lt;/h2&gt;

&lt;p&gt;CourseLit uses Material-UI. Hence I created a way to load custom themes (based on Material-UI). I even created a separate repo to contain all the themes. One can copy/paste themes into CourseLit from there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/codelitdev/courselit-themes"&gt;CourseLit Themes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I intend to sell premium themes in future. That's a part of my monetization plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rich Text Editor/Viewer
&lt;/h2&gt;

&lt;p&gt;I spent a significant amount of time creating a rich text editor and viewer for CourseLit which makes it really easy for the users to create content. As of now, one can embed code snippets, Tweets, YouTube videos, images, links etc. in the text editor and it will be rendered appropriately to the end user.&lt;/p&gt;

&lt;p&gt;See this post of have a look at the text editor in action (in non-editable mode).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codelit.dev/post/2/working-with-shebangs-in-webpack-5"&gt;Working With Shebangs In Webpack 5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The editor is based on DraftJS and there is still a lot to be desired from the editor in its current form but it gets the job done. You can even build a make shift landing page using the editor if you want to.&lt;/p&gt;

&lt;p&gt;You can use the editor/viewer in your own React projects. Check this repo out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@courselit/rich-text"&gt;@courselit/rich-text - npm (npmjs.com)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installer
&lt;/h2&gt;

&lt;p&gt;I have dabbled with a lot of ways of installing CourseLit on a Linux machine. I first experimented with Ansible. I was able to create an installer using Ansible which downloads the dependencies, installs docker and then creates containers for the app and brings it up. It worked really well. But there was this small little problem!&lt;/p&gt;

&lt;p&gt;Since the inception of the project, I wanted the average user to be able to install CourseLit without any technical help. Asking the users to install Ansible so that they can run the playbook made the entire task, well…, technical enough.&lt;/p&gt;

&lt;p&gt;I later transitioned the project to offer a bash script which does everything the Ansible playbook did. Now, one just has to copy-paste a simple one liner and CourseLit gets installed in no time. 🥳🥳&lt;/p&gt;

&lt;h2&gt;
  
  
  Layouts
&lt;/h2&gt;

&lt;p&gt;A CMS allows its users to customize its appearance to their own wills. This means they would want to re-organize section(s) of the website as per their requirements.&lt;/p&gt;

&lt;p&gt;So, I built a system to swap in/out widgets on the live website depending upon requirements. I divided the non-admin UI of the website into zones i.e. Top, Aside, Bottom, Footer Right and Footer Left. One can add/remove widgets to/from the zones.&lt;br&gt;
The Layout Section in CourseLit's Admin DashboardThis brings us to the our next important topic, Widgets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Widgets
&lt;/h2&gt;

&lt;p&gt;I wanted to build a Wordpress like system where users could install any plugin they liked by a simple drag-and-drop operation. Unfortunately, JavaScript does not work like PHP and things need to be compiled beforehand.&lt;/p&gt;

&lt;p&gt;Hence, I created a way to load custom widgets, which are React components, by importing them into a special file courselit.json. Once you do that, the widgets become visible in the admin area from where users can control them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv1tmo9qzrs2nqr92act2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv1tmo9qzrs2nqr92act2.png" alt="Official Widgets In CourseLit" width="800" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Official widgets in CourseLitAs of now, I have created a few official Widgets like A Buttondown widget which one can use to collect emails. I have plans to introduce many more like Google Ads, Substack etc.&lt;/p&gt;

&lt;p&gt;One can build his own widget and integrate it with CourseLit but there is a challenge and I don't really know the workaround to this.&lt;/p&gt;

&lt;p&gt;The problem is, CourseLit is being offered as a collection of two Docker images, one for the backend and one for the frontend. &lt;strong&gt;If you want to build your own widget for CourseLit, you are required to import it in courselit.json file, then re-build the frontend's Docker image and plug it in.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don't really know a workaround to this situation. If you know something, I am all ears. Please get in touch on Twitter: &lt;a class="mentioned-user" href="https://dev.to/rajatsx"&gt;@rajatsx&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Role-Based Access Control (RBAC)
&lt;/h2&gt;

&lt;p&gt;CourseLit has three types of user privileges.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Super Admin&lt;/li&gt;
&lt;li&gt;The Creator&lt;/li&gt;
&lt;li&gt;The normal user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The super admin can do everything from the Admin dashboard. The creator can only author and publish his/her own courses. The normal user can only take courses and does not have access to the admin dashboard.&lt;/p&gt;

&lt;p&gt;This is one feature I really enjoyed building as it forces me to think how this can be misused if not configured properly from the very start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Regular CMS Stuff
&lt;/h2&gt;

&lt;p&gt;Since CourseLit is a LMS, one can easily author courses, manage site users, manage media and change various texts like Site title etc.&lt;/p&gt;

&lt;p&gt;I have also built a way to load third party scripts like Google Analytics and all. The end user does not need to know any coding for this. It can be done using the Admin dashboard.&lt;/p&gt;




&lt;p&gt;So those were the technical achievements. Let's see what all I have done on the marketing front in order to bring attention to CourseLit.&lt;/p&gt;

&lt;h1&gt;
  
  
  Marketing Achievements
&lt;/h1&gt;

&lt;h2&gt;
  
  
  The Product Landing Page
&lt;/h2&gt;

&lt;p&gt;I created the landing page using HTML and TailwindCSS. I am using GitHub pages to host the landing page of CourseLit.&lt;br&gt;
For the domain, I have hosted it on a sub-domain as I did not want to spend anything on a domain name for a project which does not make money.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A dollar not spent is a dollar saved. But I pay in Rupees. And you still got the point, right?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Documentation
&lt;/h2&gt;

&lt;p&gt;I am using &lt;a href="https://www.gitbook.com/"&gt;GitBook&lt;/a&gt; for hosting the documentation of the product. Again, I am on a free plan obviously.&lt;/p&gt;

&lt;p&gt;I am trying to keep the documentation as easy to follow and as updated as possible because good documentation leads to greater adoption.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codelit.gitbook.io/courselit/"&gt;CourseLit (gitbook.io)&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A YouTube Series
&lt;/h2&gt;

&lt;p&gt;I have a YouTube series where I document the journey of creating my own LMS. CourseLit gets a few eyeballs every now and then from this series. The series is not as hit as I imagined it to be but I still find it interesting to share my journey with others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=5T-8_AM75f4&amp;amp;list=PLUU3EzfPr916ZYp-qWlq9eHDhFLLxwTsw"&gt;Watch The Series Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any feedback about how to make it interesting, please let me know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding CourseLit To The Public Lists
&lt;/h2&gt;

&lt;p&gt;There are many awesome-tech lists on GitHub. I try to hunt the ones down where CourseLit can fit in. As of now, I have managed to get CourseLit listed on the awesome-nextjs list. Check it out here.&lt;/p&gt;

&lt;p&gt;unicodeveloper/awesome-nextjs: A curated list of awesome resources : books, videos, articles about using Next.js (A minimalistic framework for universal server-rendered React applications) (github.com)&lt;/p&gt;

&lt;p&gt;I am working on to get it listed on one more list i.e. awesome-selfhosted. 🤞&lt;/p&gt;




&lt;p&gt;There are a few things on the marketing front that I have planned for the future, once CourseLit is stable enough and I have figured the major parts out.&lt;/p&gt;

&lt;p&gt;A YouTube series of tutorials detailing how to use the software.&lt;br&gt;
Cold emailing the teachers, institutions and content creators who are currently using sites like Teachable, Thinkific or their own make-shift websites for running their own courses.&lt;/p&gt;




&lt;h2&gt;
  
  
  "SaaS"ifying CourseLit
&lt;/h2&gt;

&lt;p&gt;In its current form, CourseLit can be installed on a single Linux machine. It configures everything it needs. But it is a standalone piece of software. You can only have one installation of the software on a server and it serves only one site.&lt;/p&gt;

&lt;p&gt;In order to build a complete SaaS offering out of CourseLit, I need to figure out how to let users spin up their own version of CourseLit on demand. It has be economical as well. I am not some mega corporation who has enough money at his disposal.&lt;/p&gt;

&lt;p&gt;Currently, I am researching multi-tenant architectures and Kubernetes for this purpose as I don't have an expertise in this domain. If anybody knows anything, I am more than willing to listen.&lt;/p&gt;




&lt;p&gt;I thought I would complete the project in approximately one year but here I am. Software and deadlines!&lt;/p&gt;

&lt;p&gt;If you liked this write up, please upvote this post and follow me on social media as I will come back with more updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Twitter:&lt;/strong&gt; &lt;a href="https://twitter.com/rajatsx"&gt;@rajatsx&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;My YouTube Channel:&lt;/strong&gt; &lt;a href="https://www.youtube.com/codelitdev"&gt;CodeLit&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;YouTube Series About CourseLit:&lt;/strong&gt; &lt;a href="https://www.youtube.com/watch?v=5T-8_AM75f4&amp;amp;list=PLUU3EzfPr916ZYp-qWlq9eHDhFLLxwTsw"&gt;Watch&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;CourseLit's Discord:&lt;/strong&gt; &lt;a href="https://discord.gg/GR4bQsN"&gt;Join&lt;/a&gt;&lt;/p&gt;

</description>
      <category>saas</category>
      <category>opensource</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Debugging HAProxy containers</title>
      <dc:creator>Rajat Saxena</dc:creator>
      <pubDate>Sat, 02 May 2020 03:32:37 +0000</pubDate>
      <link>https://dev.to/rajatsx/debugging-haproxy-containers-3016</link>
      <guid>https://dev.to/rajatsx/debugging-haproxy-containers-3016</guid>
      <description>&lt;p&gt;HAProxy is a popular solution for load balancing and reverse proxy needs. So I will cut to the chase and show you how you can get more insights into your HAProxy container. &lt;/p&gt;

&lt;p&gt;In this guide, I am assuming the you are running the &lt;a href="https://hub.docker.com/_/haproxy"&gt;offical HAProxy image&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In order to debug your HAProxy container you need to have this program &lt;code&gt;socat&lt;/code&gt; installed on your HAProxy container. Using this program you can have insights related to the running instance of HAProxy inside the container. &lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;Dockerfile&lt;/code&gt;, add the following line to install &lt;code&gt;socat&lt;/code&gt; into your container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN apt-get update &amp;amp;&amp;amp; apt-get install -y socat &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now build and start your container normally. Once started, log into the container by issuing the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker exec -it &amp;lt;haproxy_container_id&amp;gt; sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After you are logged into the container, you can start the &lt;code&gt;socat&lt;/code&gt; program in interactive mode like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;socat /var/run/haproxy.sock stdio

prompt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can issue commands like &lt;code&gt;show acl&lt;/code&gt;, &lt;code&gt;show info&lt;/code&gt;, &lt;code&gt;show errors&lt;/code&gt;, &lt;code&gt;show env&lt;/code&gt; etc., to get more information about the running process. You can head over to this &lt;a href="https://www.youtube.com/channel/UCUmQhjjF9bsIaVDJUHSIIKw"&gt;document&lt;/a&gt; to see the full list of available commands.&lt;/p&gt;

&lt;p&gt;I hope someone will find this quick guide useful. Thanks for reading and check me out on &lt;a href="https://www.youtube.com/channel/UCUmQhjjF9bsIaVDJUHSIIKw"&gt;YouTube&lt;/a&gt; as I love sharing more development related tips.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
    </item>
    <item>
      <title>Effective Refactoring</title>
      <dc:creator>Rajat Saxena</dc:creator>
      <pubDate>Tue, 28 Apr 2020 10:22:23 +0000</pubDate>
      <link>https://dev.to/rajatsx/effective-refactoring-5el0</link>
      <guid>https://dev.to/rajatsx/effective-refactoring-5el0</guid>
      <description>&lt;p&gt;When you start working on some existing code, sooner or later you are going to bump into a situation where you have to refactor some part of that code. There can be many motivations behind that refactor. Maybe the code is too complex to maintain, maybe the code is doing just way too much and so on. So here are some quick tips regarding refactoring that code effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Write unit tests&lt;/strong&gt;&lt;br&gt;
Before you even think about changing that code, you have to make sure that you have written all the unit tests you need in order to refactor that code. These tests will ensure that you've refactored the code while maintaining the existing behaviour and you've not introduced new bugs while changing the code. Make sure you've written test cases to cover all branches (if-else, switch etc.) of the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Break it down&lt;/strong&gt;&lt;br&gt;
If the code in question is doing too many tasks i.e. fetching data, parsing data, doing computation on it, transforming the result etc., you need to break this code into several functions each doing a single task. This way you'll make your refactor more complaint to the notion of the &lt;a href="https://en.wikipedia.org/wiki/Single-responsibility_principle"&gt;single responsibility principle&lt;/a&gt;. Make sure you also write some more unit tests to test these new functions as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Touch base with original author(s)&lt;/strong&gt;&lt;br&gt;
If you have the original authors of that code still around, you can ask them to review your code. It is much easier for them to recall the intricate details about that code and scenarios they handled. They may tell you about some additional scenarios you should have considered while refactoring. Make them the reviewer of the PR for this refactor or get in touch with them in person, whatever floats your boat. If the original author(s) are not around, you can still ask other developers to review your refactored code so as to weed out code smells and things that look off.&lt;/p&gt;

&lt;p&gt;That's it for today. I build &lt;a href="https://codelit.github.io/courselit/"&gt;CourseLit&lt;/a&gt; and teach software development on &lt;a href="https://www.youtube.com/channel/UCUmQhjjF9bsIaVDJUHSIIKw"&gt;YouTube&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>refactorit</category>
      <category>codequality</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
