Timeline

  • R6.1 2021 - present
    Implements new PHP 8 functionality and responsive GUI with improved usability, uses IntlDateFormatter for setting timezone offset and DST, PHP 8 compatibility
  • R6.0 2020 - 2022
    Unicode support, UTF-8 migration tools, implements full support for relative path, accent and case-sensitive page tag, new chat, details and info formatter along with new wrapper options, PHP 8.0 compatibility
  • R5.5 2018 - 2020
    Major refactoring of init system, new session handler, new URI router, new template engine, HTML5 support, new php-diff rendering methods, implements auth and form token, adds Bad Behaviour as extension, file link tracking, media link support, uses password_hash() and password_verify() API, PHP 7.0 – 7.4 compatibility


Copy and paste the mockup, HTML must be turned on and SafeHTML off in the page properties to make it work.

Evaluation

I tend more to do a formatter out of it, or an action, somehow we currently have no template support for formatters.
Then should we parse the text as Wiki syntax so the user can add links, images and additional formatting?


Simply put there is the CSS and the HTML and the data input as an array we provide which is then processed via foreach.


direction: 'l|r'
flag: 'Moscow|Amsterdam'
time: 'September 12-13, 2022|July 1 & 2, 2022'
description: 'PHP Russia 2022|Dutch PHP Conference 2022'

We need a format the user provide which gets then parsed into an array, JSON or a delimiter and line-break?
The format should be carefully selected for consistent use and further use in template boxes.

Formatter

%%(timeline)
JSON?

or

l | Moscow | September 12-13, 2022 | PHP Russia 2022
r | Amsterdam | July 1 & 2, 2022 | Dutch PHP Conference 2022
%%

Action

{{timeline

some format we can parse as array, suggestions/ideas?

}}

$tpl->enter('n_');

foreach ($items as $item)
{
	$tpl->direction		= $item['direction'];
	$tpl->flag		= $item['flag'];
	$tpl->time		= $item['time'];
	$tpl->description	= $item['description'];
}

$tpl->leave(); // n_

<ul class="timeline">
	[= n _ =
	<li>
		<div class="direction-[ ' direction ' ]">
			<div class="flag-wrapper">
				<span class="flag">[ ' flag ' ]</span>
				<span class="time-wrapper"><span class="time">[ ' time ' ]</span></span>
			</div>
			<div class="desc">[ ' description ' ]</div>
		</div>
	</li>
	=]
</ul>

Source

<!-- The Timeline -->
 
<ul class="timeline">
 
  <!-- Item 1 -->
  <li>
    <div class="direction-r">
      <div class="flag-wrapper">
        <span class="flag">Freelancer</span>
        <span class="time-wrapper"><span class="time">2013 - present</span></span>
      </div>
      <div class="desc">My current employment. Way better than the position before!</div>
    </div>
  </li>
  
  <!-- Item 2 -->
  <li>
    <div class="direction-l">
      <div class="flag-wrapper">
        <span class="flag">Apple Inc.</span>
        <span class="time-wrapper"><span class="time">2011 - 2013</span></span>
      </div>
      <div class="desc">My first employer. All the stuff I've learned and projects I've been working on.</div>
    </div>
  </li>
 
  <!-- Item 3 -->
  <li>
    <div class="direction-r">
      <div class="flag-wrapper">
        <span class="flag">Harvard University</span>
        <span class="time-wrapper"><span class="time">2008 - 2011</span></span>
      </div>
      <div class="desc">A description of all the lectures and courses I have taken and my final degree?</div>
    </div>
  </li>
  
</ul>

body {  
  margin: 0;
  padding: 0;
  background: rgb(230,230,230);
  
  color: rgb(50,50,50);
  font-family: 'Open Sans', sans-serif;
  font-size: 112.5%;
  line-height: 1.6em;
}
 
/* ================ The Timeline ================ */
 
.timeline {
  position: relative;
  width: 660px;
  margin: 0 auto;
  margin-top: 20px;
  padding: 1em 0;
  list-style-type: none;
}
 
.timeline:before {
  position: absolute;
  left: 50%;
  top: 0;
  content: ' ';
  display: block;
  width: 6px;
  height: 100%;
  margin-left: -3px;
  background: rgb(80,80,80);
  background: linear-gradient(to bottom, rgba(80,80,80,0) 0%, rgb(80,80,80) 8%, rgb(80,80,80) 92%, rgba(80,80,80,0) 100%);
  
  z-index: 5;
}
 
.timeline li {
  padding: 1em 0;
}
 
.timeline li:after {
  content: '';
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}
 
.direction-l {
  position: relative;
  width: 300px;
  float: left;
  text-align: right;
}
 
.direction-r {
  position: relative;
  width: 300px;
  float: right;
}
 
.flag-wrapper {
  position: relative;
  display: inline-block;
  
  text-align: center;
}
 
.flag {
  position: relative;
  display: inline;
  background: rgb(248,248,248);
  padding: 6px 10px;
  border-radius: 5px;
  
  font-weight: 600;
  text-align: left;
}
 
.direction-l .flag {
  box-shadow: -1px 1px 1px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.15);
}
 
.direction-r .flag {
  box-shadow: 1px 1px 1px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.15);
}
 
.direction-l .flag:before,
.direction-r .flag:before {
  position: absolute;
  top: 50%;
  right: -40px;
  content: ' ';
  display: block;
  width: 12px;
  height: 12px;
  margin-top: -10px;
  background: #fff;
  border-radius: 10px;
  border: 4px solid rgb(255,80,80);
  z-index: 10;
}
 
.direction-r .flag:before {
  left: -40px;
}
 
.direction-l .flag:after {
  content: '';
  position: absolute;
  left: 100%;
  top: 50%;
  height: 0;
  width: 0;
  margin-top: -8px;
  border: solid transparent;
  border-left-color: rgb(248,248,248);
  border-width: 8px;
  pointer-events: none;
}
 
.direction-r .flag:after {
  content: '';
  position: absolute;
  right: 100%;
  top: 50%;
  height: 0;
  width: 0;
  margin-top: -8px;
  border: solid transparent;
  border-right-color: rgb(248,248,248);
  border-width: 8px;
  pointer-events: none;
}
 
.time-wrapper {
  display: inline;
  
  line-height: 1em;
  font-size: 0.66666em;
  color: rgb(250,80,80);
  vertical-align: middle;
}
 
.direction-l .time-wrapper {
  float: left;
}
 
.direction-r .time-wrapper {
  float: right;
}
 
.time {
  display: inline-block;
  padding: 4px 6px;
  background: rgb(248,248,248);
}
 
.desc {
  margin: 1em 0.75em 0 0;
  
  font-size: 0.77777em;
  font-style: italic;
  line-height: 1.5em;
}
 
.direction-r .desc {
  margin: 1em 0 0 0.75em;
}
 
/* ================ Timeline Media Queries ================ */
 
@media screen and (max-width: 660px) {
 
.timeline {
  width: 100%;
  padding: 4em 0 1em 0;
}
 
.timeline li {
  padding: 2em 0;
}
 
.direction-l,
.direction-r {
  float: none;
  width: 100%;
 
  text-align: center;
}
 
.flag-wrapper {
  text-align: center;
}
 
.flag {
  background: rgb(255,255,255);
  z-index: 15;
}
 
.direction-l .flag:before,
.direction-r .flag:before {
  position: absolute;
  top: -30px;
  left: 50%;
  content: ' ';
  display: block;
  width: 12px;
  height: 12px;
  margin-left: -9px;
  background: #fff;
  border-radius: 10px;
  border: 4px solid rgb(255,80,80);
  z-index: 10;
}
 
.direction-l .flag:after,
.direction-r .flag:after {
  content: '';
  position: absolute;
  left: 50%;
  top: -8px;
  height: 0;
  width: 0;
  margin-left: -8px;
  border: solid transparent;
  border-bottom-color: rgb(255,255,255);
  border-width: 8px;
  pointer-events: none;
}
 
.time-wrapper {
  display: block;
  position: relative;
  margin: 4px 0 0 0;
  z-index: 14;
}
 
.direction-l .time-wrapper {
  float: none;
}
 
.direction-r .time-wrapper {
  float: none;
}
 
.desc {
  position: relative;
  margin: 1em 0 0 0;
  padding: 1em;
  background: rgb(245,245,245);
  box-shadow: 0 0 1px rgba(0,0,0,0.20);
  
  z-index: 15;
}
 
.direction-l .desc,
.direction-r .desc {
  position: relative;
  margin: 1em 1em 0 1em;
  padding: 1em;
  
  z-index: 15;
}
 
}
 
@media screen and (min-width: 400px ?? max-width: 660px) {
 
.direction-l .desc,
.direction-r .desc {
  margin: 1em 4em 0 4em;
}
 
}

Read comments (0 comments)