Merge branch 'dev' of rajukottedi/chirpy-blogging into prod

This commit is contained in:
Bangara Raju Kottedi 2024-04-06 04:26:57 +05:30 committed by Gogs
commit 5942fde518
15 changed files with 450 additions and 95 deletions

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1 @@
{"taxonomy":{"tags":["comment-system","hello","privacy","remark42","self-hosted","test","world"],"categories":[]}}

15
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
"[markdown]": {
"editor.fontSize": 14,
"editor.lineHeight": 26,
"editor.wordWrap": "wordWrapColumn",
"editor.wordWrapColumn": 64,
"editor.lineNumbers": "off",
"editor.quickSuggestions": {
"comments": "off",
"strings": "off",
"other": "off"
},
"editor.minimap.enabled": false
}
}

View File

@ -43,7 +43,7 @@ social:
- https://twitter.com/rajukottedi # change to your twitter homepage
# Uncomment below to add more social links
- https://www.facebook.com/RajuKottedi435
- https://www.linkedin.com/in/RajuKottedi
- https://in.linkedin.com/in/bangara-raju-kottedi-299072109
google_site_verification: # fill in to your verification string

View File

@ -1,8 +0,0 @@
---
title: Future Post
date: 2023-07-23 0:00:00 +0530
tags: [test, self-hosted]
---
# Future Post Modified

View File

@ -1,25 +0,0 @@
title: This is the Quiz Title
randomized: false
questions:
- type: "multiple-choice"
question: "What is your favorite color?"
items:
- choice: Red
correct: null
- choice: Blue
correct: null
- choice: Green
correct: null
followup: There is no correct answer to asking your favorite color! All choices would be good.
- type: "multiple-choice"
question: "True or False, Pittsburgh is West of Philadelphia"
items:
- choice: True
correct: true
- choice: False
correct: false
followup: |
The answer is True! Pittsburgh is 304.9 miles West of Philadelphia, or approximately
a car ride of 4 hours and 52 minutes. Buckle up!

View File

@ -0,0 +1,32 @@
<style>
main h3 {
margin: 10px
}
#post-series {
margin-top: 25px;
}
.card {
padding: 10px;
}
</style>
{% if page.series %}
{% assign posts = site.posts | where: "series", page.series | sort: 'date' %}
<div id="post-series">
<div class="card">
<div>
<h3>{{ page.series }}</h3>
<ol>
{% assign posts = site.posts | where: "series", page.series | sort: "date" %}
{% for post in posts %}
<li>{% if post.url == page.url %}{{ post.title }} {% else %}
<a href="{{ site.baseurl }}{{ post.url }}">{{ post.title }}</a>{% endif %}
</li>
{% endfor %}
</ol>
</div>
</div>
</div>
{% endif %}

49
_includes/thank-you.html Normal file
View File

@ -0,0 +1,49 @@
{% capture title %}{{ page.title }} - {{ site.title }}{% endcapture %}
{% assign title = title | uri_escape %}
{% assign url = page.url | absolute_url | url_encode %}
{% assign link = site.data.share.platforms[2].link | replace: 'TITLE', title | replace: 'URL', url %}
<style>
.thank-you {
border-left: 5px solid #959595;
margin: 1.5em 0;
padding: 0.5em 1em;
color: inherit;
font-style: italic;
margin-left: -20px;
font-style: italic;
}
</style>
<!-- Thank you message -->
<blockquote class="thank-you">
<p>Thank you for reading. I trust it provided value to you. Your feedback
is important, so please share your thoughts in the <a href="#remark42"><strong>comments</strong></a> below. If
you found it helpful, consider giving it a <a href="#topbar-wrapper" id="ty-like"><strong>like</strong></a> and
<a href="{{ link }}" target="_blank" rel="noopener" data-bs-toggle="tooltip" data-bs-placement="top"
aria-label="Linkedin" data-bs-original-title="Linkedin" aria-describedby="tooltip190113">
<strong>sharing</strong></a> it with others, also feel free to check out my [LinkedIn profile] - <a
href="{{ site.data.contact[1].url }}" target="_blank"><strong>Bangara Raju Kottedi</strong></a>.
</p>
</blockquote>
<script type="text/javascript">
function handleDelayedClick() {
setTimeout(function() {
// Actual click event handler function
heartIcon.click();
}, 1000); // Delay time in milliseconds
}
const tyLike = document.getElementById("ty-like");
tyLike.addEventListener("click", (event) => {
if (!heartIcon.classList.contains("liked")) {
handleDelayedClick();
}
else{
event.preventDefault();
}
});
</script>

View File

@ -2,11 +2,11 @@
layout: default
refactor: true
panel_includes:
- toc
- toc
tail_includes:
- related-posts
- post-nav
- comments
- related-posts
- post-nav
- comments
---
{% include lang.html %}
@ -23,7 +23,7 @@ tail_includes:
{{ site.data.locales[lang].post.posted }}
{% include datetime.html date=page.date tooltip=true lang=lang %}
</span>
<!-- lastmod date -->
{% if page.last_modified_at and page.last_modified_at != page.date %}
<span>
@ -32,55 +32,55 @@ tail_includes:
</span>
{% endif %}
</div>
<!-- post counter -->
<div id="likes-views">
{% include likes-views.html tooltip=true lang=lang %}
{% include comments-counter.html tooltip=true lang=lang %}
</div>
</div>
{% if page.image %}
{% capture src %}src="{{ page.image.path | default: page.image }}"{% endcapture %}
{% capture class %}class="preview-img{% if page.image.no_bg %}{{ ' no-bg' }}{% endif %}"{% endcapture %}
{% capture alt %}alt="{{ page.image.alt | xml_escape | default: "Preview Image" }}"{% endcapture %}
{% capture src %}src="{{ page.image.path | default: page.image }}"{% endcapture %}
{% capture class %}class="preview-img{% if page.image.no_bg %}{{ ' no-bg' }}{% endif %}"{% endcapture %}
{% capture alt %}alt="{{ page.image.alt | xml_escape | default: "Preview Image" }}"{% endcapture %}
{% if page.image.lqip %}
{%- capture lqip -%}lqip="{{ page.image.lqip }}"{%- endcapture -%}
{% endif %}
{% if page.image.lqip %}
{%- capture lqip -%}lqip="{{ page.image.lqip }}"{%- endcapture -%}
{% endif %}
<div class="mt-3 mb-3">
<img {{ src }} {{ class }} {{ alt }} w="1200" h="630" {{ lqip }}>
{%- if page.image.alt -%}
<figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption>
{%- endif -%}
</div>
<div class="mt-3 mb-3">
<img {{ src }} {{ class }} {{ alt }} w="1200" h="630" {{ lqip }}>
{%- if page.image.alt -%}
<figcaption class="text-center pt-2 pb-2">{{ page.image.alt }}</figcaption>
{%- endif -%}
</div>
{% endif %}
<div class="d-flex justify-content-between">
<!-- author(s) -->
<span>
{% if page.author %}
{% assign authors = page.author %}
{% assign authors = page.author %}
{% elsif page.authors %}
{% assign authors = page.authors %}
{% assign authors = page.authors %}
{% endif %}
{{ site.data.locales[lang].post.written_by }}
<em>
{% if authors %}
{% for author in authors %}
{% if site.data.authors[author].url -%}
<a href="{{ site.data.authors[author].url }}">{{ site.data.authors[author].name }}</a>
{%- else -%}
{{ site.data.authors[author].name }}
{%- endif %}
{% unless forloop.last %}{{ '</em>, <em>' }}{% endunless %}
{% endfor %}
{% for author in authors %}
{% if site.data.authors[author].url -%}
<a href="{{ site.data.authors[author].url }}">{{ site.data.authors[author].name }}</a>
{%- else -%}
{{ site.data.authors[author].name }}
{%- endif %}
{% unless forloop.last %}{{ '</em>, <em>' }}{% endunless %}
{% endfor %}
{% else %}
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>
<a href="{{ site.social.links[0] }}">{{ site.social.name }}</a>
{% endif %}
</em>
</span>
@ -91,54 +91,52 @@ tail_includes:
<!-- .d-flex -->
</div>
<!-- .post-meta -->
{% include post-series.html %}
</header>
<div class="content">
{{ content }}
{% if page.disable-ty != true %}
{% include thank-you.html %}
{% endif %}
</div>
<div class="post-tail-wrapper text-muted">
<!-- categories -->
{% if page.categories.size > 0 %}
<div class="post-meta mb-3">
<i class="far fa-folder-open fa-fw me-1"></i>
{% for category in page.categories %}
<a href="{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/">{{ category }}</a>
{%- unless forloop.last -%},{%- endunless -%}
{% endfor %}
</div>
<div class="post-meta mb-3">
<i class="far fa-folder-open fa-fw me-1"></i>
{% for category in page.categories %}
<a href="{{ site.baseurl }}/categories/{{ category | slugify | url_encode }}/">{{ category }}</a>
{%- unless forloop.last -%},{%- endunless -%}
{% endfor %}
</div>
{% endif %}
<!-- tags -->
{% if page.tags.size > 0 %}
<div class="post-tags">
<i class="fa fa-tags fa-fw me-1"></i>
{% for tag in page.tags %}
<a
href="{{ site.baseurl }}/tags/{{ tag | slugify | url_encode }}/"
class="post-tag no-text-decoration"
>
{{- tag -}}
</a>
{% endfor %}
</div>
<div class="post-tags">
<i class="fa fa-tags fa-fw me-1"></i>
{% for tag in page.tags %}
<a href="{{ site.baseurl }}/tags/{{ tag | slugify | url_encode }}/" class="post-tag no-text-decoration">
{{- tag -}}
</a>
{% endfor %}
</div>
{% endif %}
<div
class="
<div class="
post-tail-bottom
d-flex justify-content-between align-items-center mt-5 pb-2
"
>
">
<div class="license-wrapper">
{% if site.data.locales[lang].copyright.license.template %}
{% capture _replacement %}
{% capture _replacement %}
<a href="{{ site.data.locales[lang].copyright.license.link }}">
{{ site.data.locales[lang].copyright.license.name }}
</a>
{% endcapture %}
{{ site.data.locales[lang].copyright.license.template | replace: ':LICENSE_NAME', _replacement }}
{{ site.data.locales[lang].copyright.license.template | replace: ':LICENSE_NAME', _replacement }}
{% endif %}
</div>

View File

@ -1,9 +1,12 @@
---
title: Hello World
date: 2023-07-22 0:00:00 +0530
tags: [hello, world]
tags:
- hello world
slug: hello-world
description: Hello World
categories: []
disable-ty: true
---
# Hello World
## Hello World

View File

@ -1,10 +1,17 @@
---
title: Self-Hosted Commenting System
date: 2023-07-23 0:00:00 +0530
tags: [privacy, self-hosted, comment-system, remark42]
tags:
- privacy
- self-hosted
- comment-system
- remark42
categories:
- Open Source
- Services
---
# Privacy-focused lightweight commenting engine
## Privacy-focused lightweight commenting engine
## [Remark 42](https://remark42.com/)

View File

@ -0,0 +1,211 @@
---
title: SOLID Principles
description: Solid Principles
date: 2024-04-03T16:10:57.476Z
tags:
- code quality
- oops
categories:
- Programming
- Principles
image:
path: /assets/img/posts/solid-principles.jpg
slug: solid-principles
---
The SOLID principles are a set of **five design principles** that are intended to guide software development to create more **understandable**, **maintainable**, **extendable** and **scalable** code. These principles were introduced by **Robert C. Martin** (also known as Uncle Bob) in the early 2000s and have since become fundamental concepts in object-oriented design and programming. Here's a brief overview of each principle:
## 1. Single Responsibility Principle (SRP):
This principle states that a class should have **only one reason to change**. In other words, a class should have **only one responsibility or job**. By adhering to SRP, you ensure that classes are focused and have clear, understandable purposes, which makes them **easier to maintain and test**.
**Example**: *Think of a chef in a restaurant. Instead of having a chef who both cooks meals and serves customers, you'd want separate roles. The chef should focus on cooking delicious dishes, while a waiter takes care of serving customers.*
```c#
// Before
public class Chef
{
public void CookMeals() { /*...*/ }
public void ServeMeals() { /*...*/ }
}
// After
public class Chef
{
public void CookMeals() { /*...*/ }
}
public class Waiter
{
public void ServeMeals() { /*...*/ }
}
```
## 2. Open/Closed Principle (OCP):
This Principle suggests that software entities `(classes, modules, functions, etc.)` should be **open for extension** but **closed for modification**. This means that you should be able to **extend the behavior of a module without modifying its source code**. This is typically achieved through the use of **inheritance**, **polymorphism** and **parameters**.
**Example**: *Consider a shape drawing application. Instead of modifying the existing shape classes every time you need to add a new shape, you'd create a abstact class called **Shape** and implement it in different shape classes like **Circle**, **Square**, etc. Then, when you want to add a new shape, you create a new class that implements the Shape without modifying the existing code.*
```c#
// Before
public class Shape
{
public double CircleArea(double radius) { /*...*/ }
public double SquareArea(double sideLength) { /*...*/ }
}
// After
public abstract class Shape
{
public abstract double Area();
}
public class Circle : Shape
{
public override double Area() { /*...*/ }
}
public class Square : Shape
{
public override double Area() { /*...*/ }
}
```
## 3. Liskov Substitution Principle (LSP):
This Principle states that objects of a superclass should be substitutable with objects of its subclasses without affecting the correctness of the program. In simpler terms, **a subclass should behave in such a way that it does not break the functionality that the superclass expects**.
**Example**: *Consider a program that expects objects of type FlyingBird. According to LSP, if you have a class Swan that inherits from FlyingBird, you should be able to substitute an instance of Swan wherever you expect an FlyingBird without breaking the program's functionality.*
```c#
// Before
public abstract class Bird
{
public abstract void Fly() { /* I can fly */}
}
public abstract class Penguin : Bird
{
// Violating LSP principle (Penguin breaks the Bird's Fly functionality)
public override void Fly()
{
throw new NotImplementedException("Penguins can't fly!");
}
}
// After
public abstract class Bird
{
public abstract void Fly() { /* I can fly */}
}
public abstract class Swan : Bird
{
public override void Fly() { /* I can fly */ }
}
```
## 4. Interface Segregation Principle (ISP)
This Principle suggests that clients should not be forced to depend on interfaces they do not use. In other words, **interfaces should be fine-grained and specific to the client's needs**. This involves breaking large interfaces into smaller, more focused interfaces.
**Example**: *Lets consider **IPerson** interface which has methods to work and eat. **Robot** class cannot implement IPerson interface as it cannot eat. IPerson should be splitted in to smaller interfaces like **IEater** and **IWorker** so Robot can implement IWorker.*
```c#
// Before
public interface IPerson
{
void Work();
void Eat();
}
public class Robot : IPerson
{
public void Work() { /*...*/ }
public void Eat() { /*...*/ } // Doesn't make sense for a robot
}
// After
public interface IWorker
{
void Work();
}
public interface IEater
{
void Eat();
}
public class Robot : IWorker
{
public void Work() { /*...*/ }
}
public class Man : IEater, IWorker
{
public void Work() { /*...*/ }
public void Eat() { /*...*/ }
}
```
## 5. Dependency Inversion Principle (DIP)
This Principle states that high-level modules should not depend on low-level modules. Instead, **both should depend on abstractions**. This principle encourages the use of interfaces or abstract classes to decouple classes from their concrete implementations. Abstractions should not depend on details. Details should depend on abstractions.
**Example**: *If UserService directly depends on the concrete implementation of MySQLDatabase. This violates DIP since the high-level class UserService is directly dependent on a low-level class.
**If we want to switch to a different database system (e.g., PostgreSQL), we need to modify the UserService class**.
Instead of depending on concrete implementations, the high-level class UserService should depend on abstractions. Let's create a Database interface as an abstraction:*
```c#
// Before
/* Low-level module */
class MySQLDatabase {
getUserData(id: number): string {
// Logic to fetch user data from MySQL database
}
}
/* High-level module */
class UserService {
private database: MySQLDatabase;
constructor() {
this.database = new MySQLDatabase();
}
getUser(id: number): string {
return this.database.getUserData(id);
}
}
// After
/* Abstract interface (abstraction) for the low-level module */
interface Database {
getUserData(id: number): string;
}
/* low-level module implementing the Database interface */
class MySQLDatabase implements Database {
getUserData(id: number): string {}
}
/* low-level module implementing the Database interface */
class PostgreSQLDatabase implements Database {
getUserData(id: number): string {}
}
/* High-level module */
class UserService {
private database: Database;
constructor(database: Database) {
this.database = database;
}
getUser(id: number): string {
return this.database.getUserData(id);
}
}
```
This way, the UserService class depends on the Database abstraction, not on concrete implementations, fulfilling the Dependency Inversion Principle.
**Note:** I'm excited to share this post that's like a treasure chest filled with nuggets of wisdom from different articles I've come across. Some of the examples taken from these articles [1](https://dev.to/galwaycoder/the-solid-principles-in-software-design-explained-53n) [2](https://dev.to/lukeskw/solid-principles-theyre-rock-solid-for-good-reason-31hn).

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

70
frontmatter.json Normal file
View File

@ -0,0 +1,70 @@
{
"$schema": "https://frontmatter.codes/frontmatter.schema.json",
"frontMatter.taxonomy.contentTypes": [
{
"name": "default",
"pageBundle": false,
"previewPath": null,
"fields": [
{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Description",
"name": "description",
"type": "string"
},
{
"title": "Publishing date",
"name": "date",
"type": "datetime",
"default": "{{now}}",
"isPublishDate": true
},
{
"title": "Tags",
"name": "tags",
"type": "tags"
},
{
"title": "Categories",
"name": "categories",
"type": "categories"
},
{
"title": "image",
"name": "image",
"type": "fields",
"fields": [
{
"title": "path",
"name": "path",
"type": "image"
}
]
},
{
"title": "disable-ty",
"name": "disable-ty",
"type": "boolean"
}
]
}
],
"frontMatter.framework.id": "jekyll",
"frontMatter.content.publicFolder": "assets",
"frontMatter.preview.host": "http://localhost:4000",
"frontMatter.content.pageFolders": [
{
"title": "drafts",
"path": "[[workspace]]/_drafts"
},
{
"title": "posts",
"path": "[[workspace]]/_posts"
}
],
"frontMatter.git.enabled": true
}