working prototype

This commit is contained in:
2023-12-04 00:01:37 +01:00
parent 8a035affe3
commit 2fb24dda9b
6 changed files with 359 additions and 283 deletions

251
templates/two_column.css Normal file
View File

@@ -0,0 +1,251 @@
{% macro css() %}
h1 {
/*font-weight: 800;*/
font-size: 3em;
padding: 0;
margin: 0;
margin-left: -0.1em;
/* text upper */
text-transform: uppercase;
}
h2 {
font-size: 1.1em;
padding: 0;
margin: 0;
}
body { min-height: 100vh; }
body {
padding-left: 0.5em;
margin: 0;
font-family: 'Roboto' ;
min-height: 200%;
}
.about-me-small, .company {
color: #39c0ed;
}
.about-me-title {
padding-top: 1em;
}
.about-me {
font-size: 8pt;
width: 90%;
}
.part-content > * {
padding-bottom: 0.2em;
}
.part {
padding-top: 1em;
font-size: 10pt;
}
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: normal;
align-content: normal;
width: 100%;
min-height: 23.37in; /* TODO: jak udelam aby tenhle flex koncil s tistenou strankou? */
}
.flex-items:nth-child(1) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
order: 0;
width: 70%;
}
.flex-items:nth-child(2) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
order: 0;
width: 30%;
background-color: gray;
}
.section-header {
border-bottom: 1px solid gray;
width: 99%;
margin-bottom: 1em;
}
.flex-container-experience {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: normal;
align-items: normal;
align-content: normal;
}
.flex-items-experience:nth-child(1) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
width: 70%;
order: 0;
}
.flex-items-experience:nth-child(2) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
text-align: right;
align-self: auto;
width: 30%;
margin-right: 1%;
order: 0;
}
.flex-container-experience-langdate {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: normal;
align-items: normal;
align-content: normal;
}
.flex-items-experience-langdate:nth-child(1) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
width: 85%;
order: 0;
}
.flex-items-experience-langdate:nth-child(2) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
text-align: right;
align-self: auto;
width: 15%;
margin-right: 1%;
order: 0;
}
.flex-container-skills {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: normal;
align-items: normal;
align-content: normal;
width: 99%;
}
.section-header .flex-container-skills {
width: 100%;
}
.header {
padding-top: 1em;
}
.flex-items-skills:nth-child(1) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
width: 50%;
order: 0;
}
.flex-items-skills:nth-child(2) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
text-align: left;
align-self: auto;
width: 50%;
order: 0;
}
.tech-name {
font-weight: 800;
}
.tech-level {
}
.job p {
margin: 0;
padding: 0;
}
.job:nth-child(n+3) {
padding-top: 10px;
margin: 0;
}
.contact-bar {
font-size: 11pt;
padding-left: 1em;
color: black;
}
.contact-bar i::after{
content: "\a";
white-space: pre;
}
.photo {
padding-bottom: 1em;
}
.contact-bar:first-child {
padding-top: 2em;
}
.email{
}
.icon {
height: 1em;
vertical-align:middle;
}
.bolder {
font-weight: 800;
}
.title {
font-weight: 800;
}
.experience-desc {
max-width: 98%
}
.languages {
font-size: 8pt;
}
{% endmacro css %}

View File

@@ -1,3 +1,6 @@
{% import "two_column.macros.tera" as macros %}
{% import "two_column.css" as css %}
<html>
<head>
<meta charset="UTF-8">
@@ -6,205 +9,7 @@
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:wght@400;800&family=Roboto&display=swap" rel="stylesheet">
<style>
h1 {
/*font-weight: 800;*/
font-size: 3em;
padding: 0;
margin: 0;
margin-left: -0.1em;
/* text upper */
text-transform: uppercase;
}
h2 {
font-size: 1.1em;
padding: 0;
margin: 0;
}
body { min-height: 100vh; }
body {
padding-left: 0.5em;
margin: 0;
font-family: 'Roboto' ;
min-height: 100%;
}
.about-me-small, .company {
color: #39c0ed;
}
.part-content > * {
padding-bottom: 0.2em;
}
.part {
padding-top: 1em;
font-size: 10pt;
}
.flex-container {
min-height: 100vh;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-items: normal;
align-content: normal;
width: 100%;
}
.flex-items:nth-child(1) {
display: block;
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
order: 0;
}
.flex-items:nth-child(2) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
order: 0;
width: 30%;
background-color: gray;
}
.section-header {
border-bottom: 1px solid gray;
width: 99%;
margin-bottom: 1em;
}
.flex-container-experience {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: normal;
align-items: normal;
align-content: normal;
}
.flex-items-experience:nth-child(1) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
width: 70%;
order: 0;
}
.flex-items-experience:nth-child(2) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
text-align: right;
align-self: auto;
width: 30%;
margin-right: 1%;
order: 0;
}
.flex-container-skills {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: normal;
align-items: normal;
align-content: normal;
width: 99%;
}
.section-header .flex-container-skills {
width: 100%;
}
.header {
padding-top: 1em;
}
.flex-items-skills:nth-child(1) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: auto;
width: 50%;
order: 0;
}
.flex-items-skills:nth-child(2) {
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
text-align: left;
align-self: auto;
width: 50%;
order: 0;
}
.tech-name {
font-weight: 800;
}
.tech-level {
}
.job p {
margin: 0;
padding: 0;
}
.job:nth-child(n+3) {
padding-top: 10px;
margin: 0;
}
.contact-bar {
font-size: 11pt;
padding-left: 1em;
color: black;
}
.contact-bar i::after{
content: "\a";
white-space: pre;
}
.photo {
padding-bottom: 1em;
}
.contact-bar:first-child {
padding-top: 2em;
}
.email{
}
.icon {
height: 1em;
vertical-align:middle;
}
.bolder {
font-weight: 800;
}
.title {
font-weight: 800;
}
{{css::css()}}
</style>
</head>
<body>
@@ -229,14 +34,14 @@
<div class="flex-items-skills">
{% for skill in cv.skills | filter(attribute="techtype",value="Language") %}
<div>
<span class="tech-name">{{ skill.name }}</span>{%if skill.skill %}<span class="tech-level"> ({{ skill.skill | lower}}){%endif %}</span>
<span class="tech-name">{{ skill.name }}</span>{%if skill.skill %}<span class="tech-level"> ({{ skill.skill | translate(lang=lang)}}){%endif %}</span>
</div>
{% endfor %}
</div>
<div class="flex-items-skills">
{% for skill in cv.skills | filter(attribute="techtype", value="Technology")%}
<div>
<span class="tech-name">{{ skill.name }}</span>{%if skill.skill %}<span class="tech-level"> ({{ skill.skill | lower}}){%endif %}</span>
<span class="tech-name">{{ skill.name }}</span>{%if skill.skill %}<span class="tech-level"> ({{ skill.skill | translate(lang=lang)}}){%endif %}</span>
</div>
{% endfor %}
</div>
@@ -257,14 +62,14 @@
<div class="flex-items-skills">
{% for skill in cv.skills | filter(attribute="techtype",value="Framework") %}
<div>
<span class="tech-name">{{ skill.name }}</span>{%if skill.skill %}<span class="tech-level"> ({{ skill.skill | lower}}){%endif %}</span>
<span class="tech-name">{{ skill.name }}</span>{%if skill.skill %}<span class="tech-level"> ({{ skill.skill | translate(lang=lang)}}){%endif %}</span>
</div>
{% endfor %}
</div>
<div class="flex-items-skills">
{% for skill in cv.skills | filter(attribute="techtype", value="Database")%}
<div>
<span class="tech-name">{{ skill.name }}</span>{%if skill.skill %}<span class="tech-level"> ({{ skill.skill | lower}}){%endif %}</span>
<span class="tech-name">{{ skill.name }}</span>{%if skill.skill %}<span class="tech-level"> ({{ skill.skill | translate(lang=lang)}}){%endif %}</span>
</div>
{% endfor %}
</div>
@@ -273,39 +78,28 @@
<div class="part">
<span class="bolder">{{"tools" | translate(lang=lang)}}:</span>
{% for skill in cv.skills | filter(attribute="techtype",value="Tool") | advanced_filter(attribute="skill", include_null="all") %}
{{ skill.name }}{% if skill.skill %} - {{skill.skill}}{% endif %},<!-- TODO: fix-me (empty "," if operating system empty) %-->
{{ skill.name }}{% if skill.skill %} - {{skill.skill | ranslate(lang=lang)}}{% endif %},<!-- TODO: fix-me (empty "," if operating system empty) %-->
{% endfor %}
<span class="bolder">{{"operating-systems" | translate(lang=lang)}}:</span>
{% for skill in cv.skills | filter(attribute="techtype",value="OperatingSystem") | advanced_filter(attribute="skill", include_null="all") %}
{{ skill.name }}</span>{% if skill.skill %} - {{skill.skill}}{% endif %}{% if not loop.last %},{% endif %}
{{ skill.name }}</span>{% if skill.skill %} - {{skill.skill | translate(lang=lang)}}{% endif %}{% if not loop.last %},{% endif %}
{% endfor %}
</div>
<div class="part">
<div class="section-header">
<h2>{{ "work-experience" | translate(lang=lang) }}</h2>
</div>
{% for job in cv.jobs | filter(attribute="jobtype", value="Contract") %}
<div class="job part-content">
<div class="flex-container-experience">
<div class="flex-items-experience">
<div class="title">{{ job.title }}</div>
<div class="languages">{{ job.languages }}</div>
<p>
{{ job.description | lang_entity(lang=lang) }}
</p>
</div>
<div class="flex-items-experience">
<div class="company">@{{ job.company }}</div>
<div class="dates">
{% if job.from | format_date(type="job") != job.from | format_date(type="job") %}
<div class="text-muted text-small mb-3">{{ job.from | format_date(type="job") }} - {{ job.to | format_date(type="job") }}</div>
{% else %}
<div class="text-muted text-small mb-3">{{ job.from | format_date(type="job") }}</div>
{% endif %}
</div>
</div>
</div>
{% for job in cv.jobs | filter(attribute="jobtype", value="Contract") | slice(end=2) %}
{{macros::job_row(job_entity=job)}}
{% endfor %}
</div>
<div style="page-break-after: always;">&nbsp;</div>
<div class="part">
<div class="section-header">
<h2>{{ "work-experience" | translate(lang=lang) }}</h2>
</div>
{% for job in cv.jobs | filter(attribute="jobtype", value="Contract") | slice(start=2) %}
{{macros::job_row(job_entity=job)}}
{% endfor %}
</div>
<div class="part">
@@ -313,27 +107,7 @@
<h2>{{ "work-freelance" | translate(lang=lang) }}</h2>
</div>
{% for job in cv.jobs | filter(attribute="jobtype", value="Freelance") %}
<div class="job part-content">
<div class="flex-container-experience">
<div class="flex-items-experience">
<div class="title">{{ job.title }}</div>
<div class="languages">{{ job.languages }}</div>
<p>
{{ job.description | lang_entity(lang=lang) }}
</p>
</div>
<div class="flex-items-experience">
<div class="company">@{{ job.company }}</div>
<div class="dates">
{% if job.from | format_date(type="job") != job.from | format_date(type="job") %}
<div class="text-muted text-small mb-3">{{ job.from | format_date(type="job") }} - {{ job.to | format_date(type="job") }}</div>
{% else %}
<div class="text-muted text-small mb-3">{{ job.from | format_date(type="job") }}</div>
{% endif %}
</div>
</div>
</div>
</div>
{{macros::job_row(job_entity=job)}}
{% endfor %}
</div>
<div class="part">
@@ -370,9 +144,7 @@
</div>
<div class="flex-items">
<div class="contact-bar">
<div class="photo">
<img class="img-thumbnail shadow-2-strong" src="{{ cv.person.email | gravatar_link }}" width="160" height="160"/>
</div>
{% if cv.person.social.facebook %}
<i class="fa-facebook"> {{ cv.person.social.facebook | strip_proto }}</i>
{% endif %}
@@ -402,6 +174,8 @@
<img alt="Phone" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNNi4xNzYgMS4zMjJsMi44NDQtMS4zMjIgNC4wNDEgNy44OS0yLjcyNCAxLjM0MWMtLjUzOCAxLjI1OSAyLjE1OSA2LjI4OSAzLjI5NyA2LjM3Mi4wOS0uMDU4IDIuNjcxLTEuMzI4IDIuNjcxLTEuMzI4bDQuMTEgNy45MzJzLTIuNzY0IDEuMzU0LTIuODU0IDEuMzk2Yy03Ljg2MiAzLjU5MS0xOS4xMDMtMTguMjU4LTExLjM4NS0yMi4yODF6bTEuOTI5IDEuMjc0bC0xLjAyMy41MDRjLTUuMjk0IDIuNzYyIDQuMTc3IDIxLjE4NSA5LjY0OCAxOC42ODZsLjk3MS0uNDc0LTIuMjcxLTQuMzgzLTEuMDI2LjVjLTMuMTYzIDEuNTQ3LTguMjYyLTguMjE5LTUuMDU1LTkuOTM4bDEuMDA3LS40OTctMi4yNTEtNC4zOTh6Ii8+PC9zdmc+" class="icon">
+{{cv.person.phone | insert_space_every(times=3)}}
</i>
<div class="about-me-title">{{ "about-me" | translate(lang=lang) }}</div>
<div class="about-me">{{ cv.person.about | lang_entity(lang=lang) }}</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,37 @@
{% macro job_row(job_entity) %}
<div class="job part-content">
<div class="flex-container-experience">
<div class="flex-items-experience">
<div class="title">{{ job_entity.title }}</div>
</div>
<div class="flex-items-experience">
<div class="company">@{{ job_entity.company }}</div>
</div>
</div>
<div class="flex-container-experience-langdate">
<div class="flex-items-experience-langdate">
<div class="languages">
{% if job_entity.languages and job_entity.technologies %}
{{ job_entity.languages | concat(with=job_entity.technologies) }}
{% elif job_entity.languages %}
{{job_entity.languages}}
{% elif job_entity.technologies %}
{{job_entity.technologies}}
{% endif %}
</div>
</div>
<div class="flex-items-experience-langdate">
<div class="dates">
{% if job_entity.from | format_date(type="job") != job_entity.to | format_date(type="job") %}
<div class="text-muted text-small mb-3">{{ job_entity.from | format_date(type="job") }} - {{ job_entity.to | format_date(type="job") }}</div>
{% else %}
<div class="text-muted text-small mb-3">{{ job_entity.from | format_date(type="job") }}</div>
{% endif %}
</div>
</div>
</div>
<p class="experience-desc">
{{ job_entity.description | lang_entity(lang=lang) }}
</p>
</div>
{% endmacro hello_world %}