feat: initial development
This commit is contained in:
36
Blog.Server/Blog.Server.csproj
Normal file
36
Blog.Server/Blog.Server.csproj
Normal file
@@ -0,0 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NaiveHttpServer\NaiveHttpServer.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Handlebars.Net" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Views\index.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Static\css\feed.css">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Static\css\main.css">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Static\css\post.css">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Static\css\site.css">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
37
Blog.Server/Program.cs
Normal file
37
Blog.Server/Program.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// See https://aka.ms/new-console-template for more information
|
||||
|
||||
using HandlebarsDotNet;
|
||||
using NaiveHttpServer;
|
||||
|
||||
|
||||
var server = new Server("localhost", 3000);
|
||||
|
||||
var source = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "Views/index.html"));
|
||||
|
||||
var template = Handlebars.Compile(source);
|
||||
|
||||
var data = new {
|
||||
title = "My new post",
|
||||
body = "This is my first post!"
|
||||
};
|
||||
|
||||
var result = template(data);
|
||||
|
||||
// Build Routers
|
||||
var router = new RouterBuilder()
|
||||
.Get("/", async ctx =>
|
||||
{
|
||||
await ctx.Response.Html(result);
|
||||
}).Build();
|
||||
server
|
||||
.Use(Middlewares.Log)
|
||||
.Use(Middlewares.ExceptionHandling)
|
||||
.Use(Middlewares.StaticFile("css/", Path.Combine(Environment.CurrentDirectory,"Static/css/")))
|
||||
.Use(router)
|
||||
.Use(Middlewares.NotFound(documentUrl: "http://api.project.com/v1"));
|
||||
|
||||
server.Start();
|
||||
|
||||
Console.ReadKey();
|
||||
|
||||
server.Stop();
|
||||
74
Blog.Server/Static/css/feed.css
Normal file
74
Blog.Server/Static/css/feed.css
Normal file
@@ -0,0 +1,74 @@
|
||||
.blog-title {
|
||||
font-family: 'Roboto', serif;
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-size: 32px;
|
||||
line-height: 40px;
|
||||
color: var(--bs-info);
|
||||
}
|
||||
|
||||
.blog-nav-list {
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.blog-nav-list > li {
|
||||
float: left;
|
||||
padding-right: 0.25rem;
|
||||
color: #D9D9D9;
|
||||
}
|
||||
|
||||
.active-nav-item {
|
||||
color: var(--bs-info) !important;
|
||||
}
|
||||
|
||||
.box {
|
||||
box-sizing: border-box;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.blog-author-avatar {
|
||||
max-height: 32px;
|
||||
}
|
||||
|
||||
.blog-author {
|
||||
size: 14px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.post-link {
|
||||
color: #4f4f4f !important;
|
||||
}
|
||||
|
||||
.tag {
|
||||
border: 1px solid var(--bs-info);
|
||||
border-radius: 4px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 2px 16px;
|
||||
}
|
||||
|
||||
.static-avatar {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
margin: 0 0 0 -6px;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.author-profile-image, .avatar-wrapper {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #e3e9ed;
|
||||
border-radius: 100%;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
}
|
||||
205
Blog.Server/Static/css/main.css
Normal file
205
Blog.Server/Static/css/main.css
Normal file
@@ -0,0 +1,205 @@
|
||||
.timeline-card {
|
||||
position: relative;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.timeline-card:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
border-radius: 100%;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
top: 16px;
|
||||
left: -12px;
|
||||
border: 5px solid;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.timeline-body {
|
||||
border-left: 2px solid #E6E9ED;
|
||||
}
|
||||
|
||||
.timeline-card-primary:before {
|
||||
border-color: var(--bs-primary);
|
||||
}
|
||||
|
||||
.timeline-card-info:before {
|
||||
border-color: var(--bs-info);
|
||||
}
|
||||
|
||||
.timeline-card-secondary:before {
|
||||
border-color: var(--bs-secondary);
|
||||
}
|
||||
|
||||
.timeline-card-success:before {
|
||||
border-color: var(--bs-teal);
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1140px;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 1.25rem;
|
||||
line-height: 2.5rem;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
padding: 0;
|
||||
font-size: 1rem;
|
||||
line-height: 2.5rem;
|
||||
color: inherit;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.header-social .nav-link {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.nav-link:hover,
|
||||
.nav-link:focus {
|
||||
color: inherit;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.nav-item+.nav-item {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.cover {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.cover>img {
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.text-small {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.text-teal {
|
||||
color: var(--bs-teal);
|
||||
}
|
||||
|
||||
footer a:not(.nav-link) {
|
||||
color: inherit;
|
||||
border-bottom: 1px dashed;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.rounded-block {
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
@media (min-width: 48em) {
|
||||
.site-title {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
/* disable animations on mobile */
|
||||
[data-aos] {
|
||||
opacity: 1 !important;
|
||||
transform: translate(0) scale(1) !important;
|
||||
}
|
||||
|
||||
.p-5 {
|
||||
padding: 2.5rem 2rem !important;
|
||||
}
|
||||
|
||||
.portfolio-section .m-5 {
|
||||
margin: 2rem 0 1rem !important;
|
||||
}
|
||||
|
||||
.portfolio-reverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.portfolio-reverse .text-end {
|
||||
text-align: start !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
[data-aos] {
|
||||
opacity: 1 !important;
|
||||
transform: translate(0) scale(1) !important;
|
||||
}
|
||||
|
||||
body.bg-light {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.cover {
|
||||
height: 360px;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.cover>img {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shadow-1-strong {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.resume-container>.my-5 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.my-5.p-5 {
|
||||
padding: 1.5rem 0 !important;
|
||||
}
|
||||
|
||||
.about-section {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.skills-section,
|
||||
.work-experience-section,
|
||||
.education-section,
|
||||
.portfolio-section,
|
||||
.reference-section,
|
||||
.contact-section {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.page-break {
|
||||
padding-top: 5rem;
|
||||
page-break-before: always;
|
||||
}
|
||||
}
|
||||
51
Blog.Server/Static/css/post.css
Normal file
51
Blog.Server/Static/css/post.css
Normal file
@@ -0,0 +1,51 @@
|
||||
.blog-title {
|
||||
font-family: 'Roboto', serif;
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-size: 32px;
|
||||
line-height: 40px;
|
||||
color: var(--bs-info);
|
||||
}
|
||||
|
||||
.static-avatar {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
margin: 0 0 0 -6px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.author-profile-image, .avatar-wrapper {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #e3e9ed;
|
||||
border-radius: 100%;
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.post-author {
|
||||
color: #757575;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.wp-block-image > img {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
color: #757575;
|
||||
font-size: 75%;
|
||||
line-height: 1.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.post-content {
|
||||
padding: 0 170px 6vw;
|
||||
}
|
||||
}
|
||||
18
Blog.Server/Static/css/site.css
Normal file
18
Blog.Server/Static/css/site.css
Normal file
@@ -0,0 +1,18 @@
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
110
Blog.Server/Views/index.html
Normal file
110
Blog.Server/Views/index.html
Normal file
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="Ivan Laletin - Senior Fullstack Developer's website and blog">
|
||||
<meta property="og:title" content="Ivan Laletin - Senior Fullstack Developer" />
|
||||
<meta property="og:description" content="Ivan Laletin - Senior Fullstack Developer's website and blog">
|
||||
<meta property="og:site_name" content="Ivan Laletin">
|
||||
<meta property="og:type" content="profile" />
|
||||
<meta property="og:image" content="/images/I01P00012-min.webp" />
|
||||
<meta property="og:url" content="https://e1lama.ru" />
|
||||
<link rel="canonical" href="https://e1lama.ru">
|
||||
<meta property="og:locale" content="en_US">
|
||||
<meta property="profile:first_name" content="Ivan">
|
||||
<meta property="profile:last_name" content="Laletin">
|
||||
<meta property="profile:gender" content="male">
|
||||
<meta property="profile:username" content="e1lama">
|
||||
<title>Ivan Laletin - Senior Fullstack Developer</title>
|
||||
<link rel="icon" type="image/x-icon" href="~/favicon.ico">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="crossorigin" />
|
||||
<link rel="preload" as="style"
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:wght@600&family=Roboto:wght@300;400;500;700&display=swap" />
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:wght@600&family=Roboto:wght@300;400;500;700&display=swap"
|
||||
media="print" onload="this.media='all'" />
|
||||
<noscript>
|
||||
<link rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:wght@600&family=Roboto:wght@300;400;500;700&display=swap" />
|
||||
</noscript>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/3.2.0/mdb.min.css" rel="stylesheet" media="all">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" integrity="sha512-1cK78a1o+ht2JcaW6g8OXYwqpev9+6GqOkz9xmBN9iUUhIndKtxwILGWYOSibOKjLsEdjyjZvYDq/cZwNeak0w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<link href="/css/main.css" rel="stylesheet">
|
||||
<noscript>
|
||||
<style type="text/css">
|
||||
[data-aos] {
|
||||
opacity: 1 !important;
|
||||
transform: translate(0) scale(1) !important;
|
||||
}
|
||||
</style>
|
||||
</noscript>
|
||||
</head>
|
||||
<body class="bg-light" id="top">
|
||||
<header class="d-print-none">
|
||||
<div class="container text-center text-lg-left">
|
||||
<div class="pt-4 clearfix">
|
||||
<h1 class="site-title mb-0">Ivan Laletin</h1>
|
||||
<div class="site-nav">
|
||||
<nav role="navigation">
|
||||
<ul class="nav justify-content-center">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" title="Home" asp-area="" asp-page="/Index">
|
||||
<span
|
||||
class="menu-title">
|
||||
Home
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" title="Blog" asp-area="" asp-page="/Feed">
|
||||
<span
|
||||
class="menu-title">
|
||||
Blog
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main class="page-content">
|
||||
{{body}}
|
||||
</main>
|
||||
|
||||
<footer class="pt-4 pb-4 text-muted text-center d-print-none">
|
||||
<div class="container">
|
||||
<div class="my-3">
|
||||
<div class="h4">Ivan Laletin</div>
|
||||
<div class="footer-nav">
|
||||
<nav role="navigation">
|
||||
<ul class="nav justify-content-center">
|
||||
<li class="nav-item"><a class="nav-link" href="https://twitter.com/backndr" title="Twitter"><i
|
||||
class="fab fa-twitter"></i><span class="menu-title sr-only">Twitter</span></a>
|
||||
</li>
|
||||
<li class="nav-item"><a class="nav-link" href="https://github.com/HiveBeats" title="Github"><i
|
||||
class="fab fa-github"></i><span class="menu-title sr-only">Github</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-small">
|
||||
<!-- todo: add, now is missed -->
|
||||
<a href="./ivan.asc">PGP Public Key</a> Fingerprint: E4B4 1292 8F1A B309 7BB1 0D41 2F55 0236 0018 36A7
|
||||
</div>
|
||||
</div>
|
||||
<!-- Please feel free to buy me a coffee -->
|
||||
<!-- BTC: 1Nvb7A45ZGmS5zSSyDWWDFV7CnCYGKSUPV -->
|
||||
<!-- TON: EQAmDR5k0t-SBULTN4cv63MHweHuD-r3FNuvshfe86L4cA5M -->
|
||||
<!-- USDT (TRC20): TFPRYNgR5gLqE8WaLeDAf1RpWux2hdNdbK -->
|
||||
</footer>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mdb-ui-kit/3.2.0/mdb.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js" integrity="sha512-A7AYk1fGKX6S2SsHywmPkrnzTZHrgiVT7GcQkLGDe2ev0aWb8zejytzS8wjo7PGEXKqJOrjQ4oORtnimIRZBtw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<!--<script src="/js/main.js?ver=1.2.1"></script>-->
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user