CV orienté Base de Données
L'objectif était de traduire mon CV en page web de telle sorte que visuellement on soit très très proche. Vous pouvez comparez : CV 2018 Emmanuel PASQUIER et CV web D'un point de vue technique c'est entièrement généré par PHP avec une base de données. Le nom et l'entête sont stockés dans une ligne de la table de référence IDENTITY dont l'ID est celui d'une personne en particulier. Les sections sont définies pour tous les CV, et leur contenu est lié à l'ID du CV.
Ce qui fait que je pourrai tout à fait générer rapidement d'autres CV avec des modèles radicalement différents, bien au‑delà d'un simple reformatage CSS, ou partager cette structure pour d'autres personnes qui souhaiteraient l'utiliser sans se casser la tête avec du code HTML/CSS.
Pour profiter du format Web, j'ai ajouté un bouton en haut de la section "EXPÉRIENCES PROFESSIONNELLES" pour trier les expériences chronologiquement (par défaut, car ça convient mieux à mon cas où chaque expérience suit logiquement la précédente) ou anti‑chronologiquement (souvent préféré par les recruteurs).
Il y a aussi du contenu qui apparait dynamiquement, pour commenter des éléments sans alourdir l'aspect général de la page, qui reste conforme à l'esprit d'un CV papier.


Modèle Conceptuel de la base CV
Code HTML/JavaScript/PHP du CV

<!DOCTYPE html>
<html>
  <head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <link rel="stylesheet" type="text/css" href="CV.css">
  </head>
  <body>

    <script type="text/javascript">
var disp_el=null;
var sele_el=null;    
    
function HideElem()
{
  if (sele_el) return;
  if (!disp_el) return;
  disp_el.hide();
}    

function ShowElem(el,side)
{
  elemRect=el.getBoundingClientRect();
  bodyRect=document.body.getBoundingClientRect();
  if (side)
  {
    X=elemRect.right;  //X=$("#group_1").position().left-4;
    Y=elemRect.top-bodyRect.top;
    W=$("#group_1").outerWidth(false)+16;
  }
  else
  {
    X=elemRect.left-4;  //X=$("#group_1").position().left-4;
    Y=elemRect.bottom-bodyRect.top+2;
    W=$("#group_1").outerWidth(false)+6;
  }
  //alert("#"+this.id+"_sub"+ " displayed @ "+X+" / "+Y+"  width="+W);
  disp_el=$("#"+el.id+"_sub");
  disp_el.css({"top": Y, "left": X, "width": W}).show();
}

$(document).ready(function(){ //=============== jQuery ===============
  $(".side_line").hover(
    function() {
      if (sele_el) return;
      ShowElem(this,true);
    },
    function() {
      if (!sele_el) HideElem();
    }
  );    
  $(".side_line").click(
    function() {
      if (sele_el)
      {
        sele_el=null;
        HideElem();
      }
      else 
      {
        ShowElem(this,true);
        sele_el=disp_el;
      }
    }
  );
  $(".side_line_sub_t").click(
    function() 
    {
      sele_el=null;
      HideElem();
    }
  );  
  $(".has_sub_line").hover(
    function() {
      if (sele_el) return;
      ShowElem(this,false);
    },
    function() {
      if (!sele_el) HideElem();
    }
  );  
  $(".has_sub_line").click(
    function() {
      if (sele_el)
      {
        sele_el=null;
        HideElem();
      }
      else 
      {
        ShowElem(this,false);
        sele_el=disp_el;
      }
    }
  );
  $(".main_line_sub_t").click(
    function() 
    {
      sele_el=null;
      HideElem();
    }
  );  
//=============== jQuery END ===============
});

    
function OrderItem(id)
{
  el=document.getElementById("form_"+id);
  if (el)
  {
    el=el.children[0];
    if (el.value=='\u21D3') el.value='\u21D1'; else el.value='\u21D3';
    el=document.getElementById("group_"+id);
    el3=document.createElement("div");
    elc=el.childElementCount;
    for (i=0;i<elc;i++)
    {
      el2=el.lastChild;
      el3.appendChild(el2);
    }
    for (i=0;i<elc;i++)
    {
      el2=el3.firstChild;
      el.appendChild(el2);
    }
  }
}    </script>
    <?php
require ($_SERVER['DOCUMENT_ROOT'].'/Inc/DB.inc.php');
$DBCnx=DBConnect();

function InitCV()
{
  global $CVId,$DBCnx;
  
  $CVId=$_GET["CVId"];
  if ($CVId===NULL) $CVId=1;
  $Idents=$DBCnx->query('SELECT * FROM CV_IDENTITY WHERE ID='.$CVId);
  $count=0;
  foreach($Idents as $Ident)
  {
    $count++;
  }
  if ($count==0) exit('CV not found');
  return $Ident;
}

$Ident=InitCV();;
    ?>
    <div class="side_bar">
      <div class="portrait">
        <div class="nom"><?= $Ident["PRENOM"].' '.$Ident["NOM"]?></div>
        <img src="<?= 'Photo_'.$CVId.'.png'?>" class="photo">
        <div><?= $Ident["ETAT_CIVIL"]?></div>
      </div>

      <?php
$group=$DBCnx->query('SELECT ID,LIBELLE FROM CV_SIDE_GROUP ORDER BY ORD');
$isub=0;
foreach($group as $grp)
{
  echo '<div class="side_title">'.$grp["LIBELLE"].'</div>';
  $result=$DBCnx->query('SELECT LOGO, LIBELLE, VAL, IMG, TEXT FROM CV_SIDE_ITEM WHERE ORD>=0 AND ID_SIDE_GROUP='.$grp["ID"].' AND ID_CV='.$CVId.' ORDER BY ORD');
  foreach($result as $row)
  {
    if ($row["LIBELLE"]==' ')
    {
      echo '<hr>';
      continue;
    }
    $isub+=1;
    echo '<div class="side_line" id="side_item_'.$isub.'">';
    $val=$row["LOGO"];
    if ($val)
    {
      echo '<img src="'.$val.'.png" class="side_logo " width="20" >';
    }
    echo '<div class="side_text">'.$row["LIBELLE"].'</div>';
    $val=$row["VAL"];
    if ($val)
    {
      echo '<div id="note" class="side_img">';
      for ($i=0;$i<5;$i++)
      {
        if ($val>=2)
        {
          $v=2;
          $val=$val-2;
        }
        else
        {
          $v=$val;
          $val=0;
        }
        echo '<img src="Star'.$v.'.png" class="star">';
      }
      echo '</div>';
    }
    $val=$row["IMG"];
    if ($val)
    {
      $i=strpos($val,':');
      if ($i!==false)
      {
        $h=substr($val,$i+1,3);
        $val=substr($val,0,$i);
      }
      else unset($h);
      echo '<img src="'.$val.'.png" class="side_img"';
      if ($h) echo ' height='.$h;
      echo '>';
    }
    echo '</div>';
    if (!empty($row["TEXT"]))
    {
      echo '<div class="side_line_sub" id="side_item_'.$isub.'_sub">';
      echo '<div style="display: flex;flex-direction: row;"><div class="side_line_sub_b"></div>';
      echo '<div class="side_line_sub_t">'.$row["TEXT"].'</div></div>';
      echo '</div>';
    }
  }
}
      ?>
    </div id='sidebar'>

    <div class="main">
      <div class="header">
        <div class="title"><?= $Ident["TITRE"]?></div>
        <div class="sub_title"><?= $Ident["SOUS-TITRE"]?></div>
      </div>
      <?php
if(!empty($Ident["BASE_LINE"]))
{
  echo "<div class='sub_desc'>« $Ident[BASE_LINE] » </div>";
}
function DTF($DT,$F)
{
  if ($DT) return date_format(date_create($DT),$F); else return '';
}
function DTR($DT1,$DT2,$DTF)
{
  $ret=DTF($DT1,$DTF).' - '.DTF($DT2,$DTF);
  if ($ret==' - ') return ''; else return $ret;
}

if ($DBCnx)
{
  $group=$DBCnx->query('SELECT ID,LIBELLE,DT_ORDER FROM CV_MAIN_GROUP WHERE ORD IS NOT NULL ORDER BY ORD');
  $isub=0;
  foreach($group as $grp)
  {
    echo '<div class="main_group"><div class="main_group_title">'.$grp["LIBELLE"].'</div>';
    if (!is_null($grp["DT_ORDER"]))
    {
      echo '<form id="form_'.$grp["ID"].'" onsubmit="return false"><input type="submit" value="';
      if ($grp["DT_ORDER"]==0)
      {
        echo '&dArr;';
        $order='DT_DEBUT ASC, DT_FIN ASC, ';
      } else
      {
        echo '&uArr;';
        $order='DT_DEBUT DESC,DT_FIN DESC,';
      }
      echo '" onclick="OrderItem('.$grp["ID"].');"></form>';
    }
    else $order='';
    echo '</div>'; // main_group
    $result=$DBCnx->query('SELECT DT_DEBUT, DT_FIN, LIBELLE, SOCIETE, LIEU, POSTE, DESC_SOCIETE, DESC_POSTE, DESC_WORK FROM CV_MAIN_ITEM WHERE ID_MAIN_GROUP='.$grp["ID"].' AND ID_CV='.$CVId.' ORDER BY '.$order.' ORD');
    echo '<div id="group_'.$grp["ID"].'">';
    foreach($result as $row)
    {
      echo '<div';
      if ($row["DESC_WORK"]) 
      {
        $isub++;
        echo ' class="has_sub_line" id="main_item_'.$isub.'"';
      }
      echo '>';
      echo '<div class="main_line">';
      echo '<div class="main_label">'.DTR($row["DT_DEBUT"],$row["DT_FIN"],"m/Y").$row["LIBELLE"].'</div>';
      echo '<div class="main_header_"><div class="main_header"><div class="main_soc">'.$row["SOCIETE"].'</div>';
      if ($row["LIEU"]) echo '<div class="main_where">, '.$row["LIEU"].'</div>';
      $ds=$row["DESC_SOCIETE"];
      if ($ds)
      {
        $i=strpos($ds,'<br>');
        if ($i!==false)
        {
          $h=substr($ds,$i+4,30000);
          $ds=substr($ds,0,$i);
        } else $h='';
        if ($row["LIEU"]) $ds=' '.$ds;
        echo '<div class="main_soc_desc">'.$ds.'</div>';
        $ds=$h;
      }
      if ($row["POSTE"]) echo '<div class="main_poste">'.$row["POSTE"].'</div>';
      echo '</div>'; // main_header
      if ($ds) echo '<div class="main_soc_desc">'.$ds.'</div>';
      echo '</div>'; // main_header_
      echo '</div>'; // main_line
      if ($row["DESC_POSTE"]) echo '<div class="main_poste_desc">'.$row["DESC_POSTE"].'</div>';
      echo '</div>';
      if ($row["DESC_WORK"])
      {
        echo '<div class="work_desc" id="main_item_'.$isub.'_sub">';
        echo '<div style="display: flex;flex-direction: row;"><div class="main_line_sub_b"></div>';
        echo '<div class="main_line_sub_t">'.$row["DESC_WORK"].'</div></div></div>';
      }
    }
    echo '</div>';
  }
}
      ?>
    </div>
  </body>
</html>