summaryrefslogtreecommitdiff
path: root/resources/views/modules
diff options
context:
space:
mode:
Diffstat (limited to 'resources/views/modules')
-rw-r--r--resources/views/modules/families/sidebar.php77
-rw-r--r--resources/views/modules/family_nav/sidebar-family.php115
-rw-r--r--resources/views/modules/family_nav/sidebar.php21
-rw-r--r--resources/views/modules/googlemap/tab.php38
-rw-r--r--resources/views/modules/individuals/sidebar.php77
-rw-r--r--resources/views/modules/lightbox/tab.php16
-rw-r--r--resources/views/modules/media/tab.php21
-rw-r--r--resources/views/modules/notes/tab.php63
-rw-r--r--resources/views/modules/personal_facts/tab.php50
-rw-r--r--resources/views/modules/relatives/family.php215
-rw-r--r--resources/views/modules/relatives/tab.php155
-rw-r--r--resources/views/modules/sources_tab/tab.php51
-rw-r--r--resources/views/modules/tree/tab.php19
13 files changed, 918 insertions, 0 deletions
diff --git a/resources/views/modules/families/sidebar.php b/resources/views/modules/families/sidebar.php
new file mode 100644
index 0000000000..1d5d30a127
--- /dev/null
+++ b/resources/views/modules/families/sidebar.php
@@ -0,0 +1,77 @@
+<?php use Fisharebest\Webtrees\Html; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\Theme; ?>
+<?php use Fisharebest\Webtrees\View; ?>
+
+<form method="post" action="<?= e(Html::url('module.php' ,['mod' => 'families', 'mod_action' => 'ajax'])) ?>" onsubmit="return false;">
+ <input type="search" name="sb_fam_name" id="sb_fam_name" placeholder="<?= I18N::translate('Search') ?>">
+ <p>
+ <?php foreach ($initials as $letter => $count): ?>
+ <a href="<?= e(Html::url('module.php', ['mod' => 'families', 'mod_action' => 'ajax', 'alpha' => $letter])) ?>" class="sb_fam_letter">
+ <?php if ($letter === '@'): ?>
+ <?= I18N::translateContext('Unknown surname', '…') ?>
+ <?php elseif ($letter === ','): ?>
+ <?= I18N::translate('None') ?>
+ <?php elseif ($letter === ' '): ?>
+ <?= '&nbsp;' ?>
+ <?php else: ?>
+ <?= e($letter) ?>
+ <?php endif ?>
+ </a>
+ <?php endforeach ?>
+ </p>
+ <div id="sb_fam_content"></div>
+</form>
+
+<?php View::push('javascript') ?>
+<script>
+ var famloadedNames = [];
+
+ function fsearchQ() {
+ var query = $("#sb_fam_name").val();
+ if (query.length>1) {
+ $("#sb_fam_content").load("module.php?mod=families&mod_action=ajax&search=" + query);
+ }
+ }
+
+ var famtimerid = null;
+ $("#sb_fam_name").keyup(function(e) {
+ if (famtimerid) window.clearTimeout(famtimerid);
+ famtimerid = window.setTimeout("fsearchQ()", 500);
+ });
+ $("#sidebar-content-families").on("click", ".sb_fam_letter", function() {
+ $("#sb_fam_content").load(this.href);
+ return false;
+ });
+ $("#sidebar-content-families").on("click", ".sb_fam_surname", function() {
+ var element = $(this);
+ var surname = element.data("surname");
+ var alpha = element.data("alpha");
+
+ if (!famloadedNames[surname]) {
+ jQuery.ajax({
+ url: "module.php?mod=families&mod_action=ajax&alpha=" + encodeURIComponent(alpha) + "&surname=" + encodeURIComponent(surname),
+ cache: false,
+ success: function (html) {
+ $("div.name_tree_div", element.closest("li"))
+ .html(html)
+ .show("fast")
+ .css("list-style-image", "url(<?= Theme::theme()->parameter('image-minus') ?>)");
+ famloadedNames[surname] = 2;
+ }
+ });
+ } else if (famloadedNames[surname] === 1) {
+ famloadedNames[surname] = 2;
+ $("div.name_tree_div", $(this).closest("li"))
+ .show()
+ .css("list-style-image", "url(<?= Theme::theme()->parameter('image-minus') ?>)");
+ } else {
+ famloadedNames[surname] = 1;
+ $("div.name_tree_div", $(this).closest("li"))
+ .hide("fast")
+ .css("list-style-image", "url(<?= Theme::theme()->parameter('image-plus') ?>)");
+ }
+ return false;
+ });
+</script>
+<?php View::endpush() ?>
diff --git a/resources/views/modules/family_nav/sidebar-family.php b/resources/views/modules/family_nav/sidebar-family.php
new file mode 100644
index 0000000000..f5c60effb2
--- /dev/null
+++ b/resources/views/modules/family_nav/sidebar-family.php
@@ -0,0 +1,115 @@
+<?php use Fisharebest\Webtrees\Functions\Functions; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+
+<table class="table table-sm wt-facts-table wt-family-navigator-family">
+ <caption class="text-center wt-family-navigator-family-heading">
+ <a href="<?= e($family->url()) ?>">
+ <?= $title ?>
+ </a>
+ </caption>
+ <tbody>
+ <?php foreach ($family->getSpouses() as $spouse): ?>
+ <tr class="text-center wt-family-navigator-parent wt-gender-<?= $spouse->getSex() ?>">
+ <th class="text-nowrap align-middle wt-family-navigator-label" scope="row">
+ <?php if ($spouse === $individual): ?>
+ <?= Functions::getCloseRelationshipName($individual, $spouse) ?>
+ <i class="icon-selected"></i>
+ <?php elseif ($spouse->getPrimaryChildFamily() !== null): ?>
+ <div class="dropdown">
+ <a class="dropdown-toggle" href="#" role="button" id="dropdown-<?= e($spouse->getXref()) ?>" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <?= Functions::getCloseRelationshipName($individual, $spouse) ?>
+ </a>
+
+ <div class="dropdown-menu wt-family-navigator-dropdown">
+ <div class="dropdown-header wt-family-navigator-dropdown-heading">
+ <?= I18N::translate('Parents') ?>
+ </div>
+ <?php foreach ($spouse->getPrimaryChildFamily()->getSpouses() as $parent): ?>
+ <a class="dropdown-item" href="<?= e($parent->url()) ?>">
+ <?= $parent->getFullName() ?>
+ </a>
+ <?php endforeach ?>
+ </div>
+ </div>
+ <?php else: ?>
+ <?= Functions::getCloseRelationshipName($individual, $spouse) ?>
+ <?php endif ?>
+ </th>
+
+ <td class="wt-family-navigator-name">
+ <?php if ($spouse->canShow()): ?>
+ <a href="<?= e($spouse->url()) ?>">
+ <?= $spouse->getFullName() ?>
+ </a>
+ <div class="small">
+ <?= $spouse->getLifeSpan() ?>
+ </div>
+ <?php else: ?>
+ <?= $spouse->getFullName() ?>
+ <?php endif ?>
+ </td>
+ </tr>
+ <?php endforeach ?>
+
+ <?php foreach ($family->getChildren() as $child): ?>
+ <tr class="text-center wt-family-navigator-child wt-gender-<?= $child->getSex() ?>">
+ <th class="text-nowrap align-middle" scope="row">
+ <?php if ($child === $individual): ?>
+ <?= Functions::getCloseRelationshipName($individual, $child) ?>
+ <i class="icon-selected"></i>
+ <?php elseif ($child->getSpouseFamilies() !== []): ?>
+ <div class="dropdown">
+ <a class="dropdown-toggle" href="#" role="button" id="dropdown-<?= e($child->getXref()) ?>" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ <?= Functions::getCloseRelationshipName($individual, $child) ?>
+ </a>
+
+ <div class="dropdown-menu">
+ <?php foreach ($child->getSpouseFamilies() as $n => $in_laws): ?>
+ <?php if ($n > 0) : ?>
+ <div class="dropdown-divider"></div>
+ <?php endif ?>
+ <div class="dropdown-header wt-family-navigator-dropdown-heading">
+ <?= I18N::translate('Family') ?>
+ </div>
+
+ <?php foreach ($in_laws->getSpouses() as $sibling_in_law): ?>
+ <?php if ($sibling_in_law !== $child): ?>
+ <a class="dropdown-item" href="<?= e($sibling_in_law->url()) ?>">
+ <?= $sibling_in_law->getFullName() ?>
+ </a>
+ <?php endif ?>
+ <?php endforeach ?>
+
+ <ul>
+ <?php foreach ($in_laws->getChildren() as $child_in_law): ?>
+ <li>
+ <a class="dropdown-item" href="<?= e($child_in_law->url()) ?>">
+ <?= $child_in_law->getFullName() ?>
+ </a>
+ </li>
+ <?php endforeach ?>
+ </ul>
+ <?php endforeach ?>
+ </div>
+ </div>
+ <?php else: ?>
+ <?= Functions::getCloseRelationshipName($individual, $child) ?>
+ <?php endif ?>
+ </th>
+
+ <td>
+ <?php if ($child->canShow()): ?>
+ <a href="<?= e($child->url()) ?>">
+ <?= $child->getFullName() ?>
+ </a>
+ <div class="small">
+ <?= $child->getLifeSpan() ?>
+ </div>
+ <?php else: ?>
+ <?= $child->getFullName() ?>
+ <?php endif ?>
+ </td>
+ </tr>
+ <?php endforeach ?>
+ </tbody>
+</table>
diff --git a/resources/views/modules/family_nav/sidebar.php b/resources/views/modules/family_nav/sidebar.php
new file mode 100644
index 0000000000..7e4db8edd3
--- /dev/null
+++ b/resources/views/modules/family_nav/sidebar.php
@@ -0,0 +1,21 @@
+<div class="wt-sidebar-content wt-sidebar-family-navigator">
+ <!-- parent families -->
+ <?php foreach ($individual->getChildFamilies() as $family): ?>
+ <?= view('modules/family_nav/sidebar-family', ['individual' => $individual, 'family' => $family, 'title' => $individual->getChildFamilyLabel($family)]) ?>
+ <?php endforeach ?>
+
+ <!-- step parents -->
+ <?php foreach ($individual->getChildStepFamilies() as $family): ?>
+ <?= view('modules/family_nav/sidebar-family', ['individual' => $individual, 'family' => $family, 'title' => $individual->getStepFamilyLabel($family)]) ?>
+ <?php endforeach ?>
+
+ <!-- spouse and children -->
+ <?php foreach ($individual->getSpouseFamilies() as $family): ?>
+ <?= view('modules/family_nav/sidebar-family', ['individual' => $individual, 'family' => $family, 'title' => $individual->getSpouseFamilyLabel($family)]) ?>
+ <?php endforeach ?>
+
+ <!-- step children -->
+ <?php foreach ($individual->getSpouseStepFamilies() as $family): ?>
+ <?= view('modules/family_nav/sidebar-family', ['individual' => $individual, 'family' => $family, 'title' => $family->getFullName()]) ?>
+ <?php endforeach ?>
+</div>
diff --git a/resources/views/modules/googlemap/tab.php b/resources/views/modules/googlemap/tab.php
new file mode 100644
index 0000000000..2ffe34141a
--- /dev/null
+++ b/resources/views/modules/googlemap/tab.php
@@ -0,0 +1,38 @@
+<?php use Fisharebest\Webtrees\Html; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\View; ?>
+
+<div class="wt-map-tab py-4">
+ <div class="gm-wrapper">
+ <div class="gm-map"></div>
+ <?= $map_data ?>
+ </div>
+
+ <?php if ($is_admin): ?>
+ <div class="gm-options">
+ <a href="<?= e(Html::url('module.php', ['mod' => 'googlemap', 'mod_action' => 'admin_config'])) ?>">
+ <?= I18N::translate('Google Maps™ preferences') ?>
+ </a>
+ |
+ <a href="<?= e(Html::url('module.php', ['mod' => 'googlemap', 'mod_action' => 'admin_places'])) ?>">
+ <?= I18N::translate('Geographic data') ?>
+ </a>
+ </div>
+ <?php endif ?>
+</div>
+
+<?php View::push('javascript') ?>
+<script>
+ 'use strict';
+
+ // Load the module's CSS file
+ var newSheet=document.createElement("link");
+ newSheet.setAttribute("rel","stylesheet");
+ newSheet.setAttribute("type","text/css");
+ newSheet.setAttribute("href","<?= $google_map_css ?>");
+ document.head.appendChild(newSheet);
+
+</script>
+<script src="<?= e($google_map_js . '&callback=loadMap') ?>"></script>
+
+<?php View::endpush() ?>
diff --git a/resources/views/modules/individuals/sidebar.php b/resources/views/modules/individuals/sidebar.php
new file mode 100644
index 0000000000..086a26739b
--- /dev/null
+++ b/resources/views/modules/individuals/sidebar.php
@@ -0,0 +1,77 @@
+<?php use Fisharebest\Webtrees\Html; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\Theme; ?>
+<?php use Fisharebest\Webtrees\View; ?>
+
+<form method="post" action="<?= e(Html::url('module.php' ,['mod' => 'individuals', 'mod_action' => 'ajax'])) ?>" onsubmit="return false;">
+ <input type="search" name="sb_indi_name" id="sb_indi_name" placeholder="<?= I18N::translate('Search') ?>">
+ <p>
+ <?php foreach ($initials as $letter => $count): ?>
+ <a href="<?= e(Html::url('module.php', ['mod' => 'individuals', 'mod_action' => 'ajax', 'alpha' => $letter])) ?>" class="sb_indi_letter">
+ <?php if ($letter === '@'): ?>
+ <?= I18N::translateContext('Unknown surname', '…') ?>
+ <?php elseif ($letter === ','): ?>
+ <?= I18N::translate('None') ?>
+ <?php elseif ($letter === ' '): ?>
+ <?= '&nbsp;' ?>
+ <?php else: ?>
+ <?= e($letter) ?>
+ <?php endif ?>
+ </a>
+ <?php endforeach ?>
+ </p>
+ <div id="sb_indi_content"></div>
+</form>
+
+<?php View::push('javascript') ?>
+<script>
+ var loadedNames = [];
+
+ function isearchQ() {
+ var query = $("#sb_indi_name").val();
+ if (query.length > 1) {
+ $("#sb_indi_content").load("module.php?mod=individuals&mod_action=ajax&search=" + query);
+ }
+ }
+
+ var timerid = null;
+ $("#sb_indi_name").keyup(function (e) {
+ if (timerid) window.clearTimeout(timerid);
+ timerid = window.setTimeout("isearchQ()", 500);
+ });
+ $("#sidebar-content-individuals").on("click", ".sb_indi_letter", function () {
+ $("#sb_indi_content").load(this.href);
+ return false;
+ });
+ $("#sidebar-content-individuals").on("click", ".sb_indi_surname", function () {
+ var element = $(this);
+ var surname = element.data("surname");
+ var alpha = element.data("alpha");
+
+ if (!loadedNames[surname]) {
+ jQuery.ajax({
+ url: "module.php?mod=individuals&mod_action=ajax&alpha=" + encodeURIComponent(alpha) + "&surname=" + encodeURIComponent(surname),
+ cache: false,
+ success: function (html) {
+ $("div.name_tree_div", element.closest("li"))
+ .html(html)
+ .show("fast")
+ .css("list-style-image", "url(<?= Theme::theme()->parameter('image-minus') ?>)");
+ loadedNames[surname] = 2;
+ }
+ });
+ } else if (loadedNames[surname] === 1) {
+ loadedNames[surname] = 2;
+ $("div.name_tree_div", $(this).closest("li"))
+ .show()
+ .css("list-style-image", "url(<?= Theme::theme()->parameter('image-minus') ?>)");
+ } else {
+ loadedNames[surname] = 1;
+ $("div.name_tree_div", $(this).closest("li"))
+ .hide("fast")
+ .css("list-style-image", "url(<?= Theme::theme()->parameter('image-plus') ?>)");
+ }
+ return false;
+ });
+</script>
+<?php View::endpush() ?>
diff --git a/resources/views/modules/lightbox/tab.php b/resources/views/modules/lightbox/tab.php
new file mode 100644
index 0000000000..9c11577793
--- /dev/null
+++ b/resources/views/modules/lightbox/tab.php
@@ -0,0 +1,16 @@
+<div class="wt-album-tab py-4">
+ <?php foreach ($media_list as $media): ?>
+ <figure class="figure text-center col-sm-6 col-md-4 col-lg-3 col-xl-2 wt-album-tab-figure">
+ <?php foreach ($media->mediaFiles() as $media_file): ?>
+ <?php if ($media_file->isImage()): ?>
+ <?= $media_file->displayImage(100, 100, 'contain', ['class' => 'img-thumbnail wt-album-tab-image']) ?>
+ <?php endif ?>
+ <?php endforeach ?>
+ <figcaption class="figure-caption wt-album-tab-caption">
+ <a href="<?= e($media->url()) ?>">
+ <?= $media->getFullName() ?>
+ </a>
+ </figcaption>
+ </figure>
+ <?php endforeach ?>
+</div>
diff --git a/resources/views/modules/media/tab.php b/resources/views/modules/media/tab.php
new file mode 100644
index 0000000000..86343b3701
--- /dev/null
+++ b/resources/views/modules/media/tab.php
@@ -0,0 +1,21 @@
+<?php use Fisharebest\Webtrees\Functions\FunctionsPrintFacts; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+
+<div class="wt-media-tab py-4">
+ <table class="table wt-facts-table">
+ <?php foreach ($facts as $fact): ?>
+ <?php FunctionsPrintFacts::printMainMedia($fact, 1) ?>
+ <?php FunctionsPrintFacts::printMainMedia($fact, 2) ?>
+ <?php FunctionsPrintFacts::printMainMedia($fact, 3) ?>
+ <?php FunctionsPrintFacts::printMainMedia($fact, 4) ?>
+ <?php endforeach ?>
+
+ <?php if (empty($facts)): ?>
+ <tr>
+ <td colspan="2">
+ <?= I18N::translate('There are no media objects for this individual.') ?>
+ </td>
+ </tr>
+ <?php endif ?>
+ </table>
+</div>
diff --git a/resources/views/modules/notes/tab.php b/resources/views/modules/notes/tab.php
new file mode 100644
index 0000000000..64b248e135
--- /dev/null
+++ b/resources/views/modules/notes/tab.php
@@ -0,0 +1,63 @@
+<?php use Fisharebest\Webtrees\Functions\FunctionsPrintFacts; ?>
+<?php use Fisharebest\Webtrees\Html; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\View; ?>
+
+<div class="wt-notes-tab py-4">
+ <table class="table wt-facts-table">
+ <tr>
+ <td colspan="2">
+ <label>
+ <input id="show-level-2-notes" type="checkbox">
+ <?= I18N::translate('Show all notes') ?>
+ </label>
+ </td>
+ </tr>
+
+ <?php foreach ($facts as $fact): ?>
+ <?php FunctionsPrintFacts::printMainNotes($fact, 1) ?>
+ <?php FunctionsPrintFacts::printMainNotes($fact, 2) ?>
+ <?php FunctionsPrintFacts::printMainNotes($fact, 3) ?>
+ <?php FunctionsPrintFacts::printMainNotes($fact, 4) ?>
+ <?php endforeach ?>
+
+ <?php if (empty($facts)): ?>
+ <tr>
+ <td colspan="2">
+ <?= I18N::translate('There are no notes for this individual.') ?>
+ </td>
+ </tr>
+ <?php endif ?>
+
+ <?php if ($can_edit): ?>
+ <tr>
+ <th scope="row">
+ <?= I18N::translate('Note') ?>
+ </th>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'fact' => 'NOTE'])) ?>">
+ <?= I18N::translate('Add a note') ?>
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">
+ <?= I18N::translate('Shared note') ?>
+ </th>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'fact' => 'SHARED_NOTE'])) ?>">
+ <?= I18N::translate('Add a shared note') ?>
+ </a>
+ </td>
+ </tr>
+ <?php endif ?>
+ </table>
+</div>
+
+<?php View::push('javascript') ?>
+<script>
+ 'use strict';
+
+ persistent_toggle("show-level-2-notes", ".row_note2");
+</script>
+<?php View::endpush() ?>
diff --git a/resources/views/modules/personal_facts/tab.php b/resources/views/modules/personal_facts/tab.php
new file mode 100644
index 0000000000..743bb9eddf
--- /dev/null
+++ b/resources/views/modules/personal_facts/tab.php
@@ -0,0 +1,50 @@
+<?php use Fisharebest\Webtrees\Functions\FunctionsPrint; ?>
+<?php use Fisharebest\Webtrees\Functions\FunctionsPrintFacts; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\View; ?>
+
+<div class="wt-facts-tab py-4">
+ <table class="table wt-facts-table">
+ <tbody>
+ <tr>
+ <td colspan="2">
+ <label>
+ <input id="show-relatives-facts" type="checkbox" data-toggle="collapse" data-target=".wt-relation-fact">
+ <?= I18N::translate('Events of close relatives') ?>
+ </label>
+ <?php if ($has_historical_facts): ?>
+ <label>
+ <input id="show-historical-facts" type="checkbox" data-toggle="collapse" data-target=".wt-historic-fact">
+ <?= I18N::translate('Historical facts') ?>
+ </label>
+ <?php endif ?>
+ </td>
+ </tr>
+
+ <?php foreach ($facts as $fact): ?>
+ <?php FunctionsPrintFacts::printFact($fact, $individual) ?>
+ <?php endforeach ?>
+
+ <?php if (empty($facts)): ?>
+ <tr>
+ <td colspan="2">
+ <?= I18N::translate('There are no facts for this individual.') ?>
+ </td>
+ </tr>
+ <?php endif ?>
+
+ <?php if ($individual->canEdit()): ?>
+ <?php FunctionsPrint::printAddNewFact($individual->getXref(), $facts, 'INDI') ?>
+ <?php endif ?>
+ </tbody>
+ </table>
+</div>
+
+<?php View::push('javascript') ?>
+<script>
+ 'use strict';
+
+ persistent_toggle("show-relatives-facts", "tr.rela");
+ persistent_toggle("show-historical-facts", "tr.histo");
+</script>
+<?php View::endpush() ?>
diff --git a/resources/views/modules/relatives/family.php b/resources/views/modules/relatives/family.php
new file mode 100644
index 0000000000..50e4f5c3d7
--- /dev/null
+++ b/resources/views/modules/relatives/family.php
@@ -0,0 +1,215 @@
+<?php use Fisharebest\Webtrees\Date; ?>
+<?php use Fisharebest\Webtrees\Functions\Functions; ?>
+<?php use Fisharebest\Webtrees\GedcomTag; ?>
+<?php use Fisharebest\Webtrees\Html; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\Individual; ?>
+<?php use Fisharebest\Webtrees\Theme; ?>
+
+<table class="table table-sm wt-facts-table">
+ <caption>
+ <i class="icon-cfamily"></i>
+ <a href="<?= e($family->url()) ?>"><?= $label ?></a>
+ </caption>
+
+ <tbody>
+ <?php
+ $found = false;
+ foreach ($family->getFacts('HUSB', false, $fam_access_level) as $fact) {
+ $found |= !$fact->isPendingDeletion();
+ $person = $fact->getTarget();
+ if ($person instanceof Individual) {
+ $row_class = 'wt-gender-' . $person->getSex();
+ if ($fact->isPendingAddition()) {
+ $row_class .= ' new';
+ } elseif ($fact->isPendingDeletion()) {
+ $row_class .= ' old';
+ }
+ ?>
+ <tr class="<?= $row_class ?>">
+ <th scope="row">
+ <?= $individual === $person ? '<i class="icon-selected"></i>' : '' ?>
+ <?= Functions::getCloseRelationshipName($individual, $person) ?>
+ </th>
+ <td class="border-0 p-0">
+ <?= Theme::theme()->individualBoxLarge($person) ?>
+ </td>
+ </tr>
+ <?php
+ }
+ }
+ if (!$found && $family->canEdit()) {
+ ?>
+ <tr>
+ <th scope="row"></th>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_spouse_to_family', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'famtag' => 'HUSB'])) ?>">
+ <?= I18N::translate('Add a husband to this family') ?>
+ </a>
+ </td>
+ </tr>
+ <?php
+ }
+
+ $found = false;
+ foreach ($family->getFacts('WIFE', false, $fam_access_level) as $fact) {
+ $person = $fact->getTarget();
+ if ($person instanceof Individual) {
+ $found |= !$fact->isPendingDeletion();
+ $row_class = 'wt-gender-' . $person->getSex();
+ if ($fact->isPendingAddition()) {
+ $row_class .= ' new';
+ } elseif ($fact->isPendingDeletion()) {
+ $row_class .= ' old';
+ }
+ ?>
+
+ <tr class="<?= $row_class ?>">
+ <th scope="row">
+ <?= $individual === $person ? '<i class="icon-selected"></i>' : '' ?>
+ <?= Functions::getCloseRelationshipName($individual, $person) ?>
+ </th>
+ <td class="border-0 p-0">
+ <?= Theme::theme()->individualBoxLarge($person) ?>
+ </td>
+ </tr>
+ <?php
+ }
+ }
+ if (!$found && $family->canEdit()) { ?>
+ <tr>
+ <th scope="row"></th>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_spouse_to_family', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'famtag' => 'WIFE'])) ?>">
+ <?= I18N::translate('Add a wife to this family') ?>
+ </a>
+ </td>
+ </tr>
+
+ <?php } ?>
+
+ <?php
+ ///// MARR /////
+ $found = false;
+ $prev = new Date('');
+ foreach ($family->getFacts(WT_EVENTS_MARR . '|' . WT_EVENTS_DIV, true) as $fact) {
+ $found |= !$fact->isPendingDeletion();
+ if ($fact->isPendingAddition()) {
+ $row_class = 'new';
+ } elseif ($fact->isPendingDeletion()) {
+ $row_class = 'old';
+ } else {
+ $row_class = '';
+ }
+ ?>
+
+ <tr class="<?= $row_class ?>">
+ <th scope="row">
+ </th>
+ <td>
+ <?= GedcomTag::getLabelValue($fact->getTag(), $fact->getDate()->display() . ' — ' . $fact->getPlace()->getFullName()) ?>
+ </td>
+ </tr>
+
+ <?php
+ if (!$prev->isOK() && $fact->getDate()->isOK()) {
+ $prev = $fact->getDate();
+ }
+ }
+
+ if (!$found && $family->canShow() && $family->canEdit()) {
+ ?>
+ <tr>
+ <th scope="row">
+ </th>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'fact' => 'MARR'])) ?>">
+ <?= I18N::translate('Add marriage details') ?>
+ </a>
+ </td>
+ </tr>
+ <?php
+ }
+
+ ///// CHIL /////
+ $child_number = 0;
+ foreach ($family->getFacts('CHIL', false, $fam_access_level) as $fact) {
+ $person = $fact->getTarget();
+ if ($person instanceof Individual) {
+ $row_class = 'wt-gender-' . $person->getSex();
+ if ($fact->isPendingAddition()) {
+ $child_number++;
+ $row_class .= ' new';
+ } elseif ($fact->isPendingDeletion()) {
+ $row_class .= ' old';
+ } else {
+ $child_number++;
+ }
+ $next = new Date('');
+ foreach ($person->getFacts(WT_EVENTS_BIRT, true) as $bfact) {
+ if ($bfact->getDate()->isOK()) {
+ $next = $bfact->getDate();
+ break;
+ }
+ }
+ ?>
+
+ <tr class="<?= $row_class ?>">
+ <th scope="row">
+ <?php if ($individual === $person): ?>
+ <i class="icon-selected"></i>
+ <?php endif ?>
+
+ <?php if ($prev->isOK() && $next->isOK()): ?>
+ <div class="elderdate age">
+ <?php $days = $next->maximumJulianDay() - $prev->minimumJulianDay(); ?>
+ <?php if ($days < 0 || $child_number > 1 && $days > 1 && $days < 240): ?>
+ <i class="icon-warning"></i>
+ <?php endif ?>
+
+ <?php $months = round($days / 30); ?>
+ <?php if (abs($months) === 12 || abs($months) >= 24): ?>
+ <?= I18N::plural('%s year', '%s years', round($months / 12), I18N::number(round($months / 12))) ?>
+ <?php elseif ($months !== 0): ?>
+ <?= I18N::plural('%s month', '%s months', $months, I18N::number($months)) ?>
+ <?php endif ?>
+ </div>
+ <?php endif ?>
+
+ <?= Functions::getCloseRelationshipName($individual, $person) ?>
+ </th>
+ <td class="border-0 p-0">
+ <?= Theme::theme()->individualBoxLarge($person) ?>
+ </td>
+ </tr>
+ <?php
+ $prev = $next;
+ }
+ } ?>
+
+ <?php if ($family->canEdit()): ?>
+ <tr>
+ <th scope="row">
+ <?php if (count($family->getChildren()) > 1): ?>
+ <a href="<?= e(route('reorder-children', ['ged' => $family->getTree()->getName(), 'xref' => $family->getXref()])) ?>">
+ <i class="icon-media-shuffle"></i> <?= I18N::translate('Re-order children') ?>
+ </a>
+ <?php endif; ?>
+ </th>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_child_to_family', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'gender' => 'U'])) ?>">
+ <?php if ($type == 'FAMS'): ?>
+ <?= I18N::translate('Add a son or daughter') ?>
+ <?php else: ?>
+ <?= I18N::translate('Add a brother or sister') ?>
+ <?php endif ?>
+ </a>
+
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_child_to_family', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'gender' => 'M'])) ?>" class="icon-sex_m_15x15"></a>
+
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_child_to_family', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'gender' => 'F'])) ?>" class="icon-sex_f_15x15"></a>
+ </td>
+ </tr>
+ <?php endif ?>
+ </tbody>
+</table>
diff --git a/resources/views/modules/relatives/tab.php b/resources/views/modules/relatives/tab.php
new file mode 100644
index 0000000000..7e8ef2124e
--- /dev/null
+++ b/resources/views/modules/relatives/tab.php
@@ -0,0 +1,155 @@
+<?php use Fisharebest\Webtrees\Html; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\View; ?>
+
+<div class="wt-sources-tab py-4">
+ <table class="table table-sm wt-facts-table" role="presentation">
+ <tbody>
+ <tr>
+ <td>
+ <label>
+ <input id="show-date-differences" type="checkbox" checked>
+ <?= I18N::translate('Date differences') ?>
+ </label>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<?php if (empty($parent_families) && $can_edit): ?>
+ <table class="table table-sm wt-facts-table" role="presentation">
+ <tbody>
+ <tr>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_parent_to_individual', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'gender' => 'M'])) ?>">
+ <?= I18N::translate('Add a father') ?>
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_parent_to_individual', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'gender' => 'F'])) ?>">
+ <?= I18N::translate('Add a mother') ?>
+ </a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+<?php endif ?>
+
+<!-- Parents -->
+<?php foreach ($parent_families as $family): ?>
+ <?= view('modules/relatives/family', [
+ 'individual' => $individual,
+ 'family' => $family,
+ 'type' => 'FAMC',
+ 'label' => $individual->getChildFamilyLabel($family),
+ 'fam_access_level' => $fam_access_level,
+ ]) ?>
+<?php endforeach ?>
+
+<!-- step-parents -->
+<?php foreach ($step_parent_families as $family): ?>
+ <?= view('modules/relatives/family', [
+ 'individual' => $individual,
+ 'family' => $family,
+ 'type' => 'FAMC',
+ 'label' => $individual->getStepFamilyLabel($family),
+ 'fam_access_level' => $fam_access_level,
+ ]) ?>
+<?php endforeach ?>
+
+<!-- spouses -->
+<?php foreach ($spouse_families as $family): ?>
+ <?= view('modules/relatives/family', [
+ 'individual' => $individual,
+ 'family' => $family,
+ 'type' => 'FAMS',
+ 'label' => $individual->getSpouseFamilyLabel($family),
+ 'fam_access_level' => $fam_access_level,
+ ]) ?>
+<?php endforeach ?>
+
+<!-- step-children -->
+<?php foreach ($step_child_familiess as $family): ?>
+ <?= view('modules/relatives/family', [
+ 'individual' => $individual,
+ 'family' => $family,
+ 'type' => 'FAMS',
+ 'label' => $family->getFullName(),
+ 'fam_access_level' => $fam_access_level,
+ ]) ?>
+<?php endforeach ?>
+
+<?php if ($can_edit): ?>
+ <br>
+ <table class="table table-sm wt-facts-table" role="presentation">
+ <tbody>
+ <?php if (count($spouse_families) > 1): ?>
+ <tr>
+ <td>
+ <a href="<?= e(route('reorder-spouses', ['ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref()])) ?>">
+ <?= I18N::translate('Re-order families') ?>
+ </a>
+ </td>
+ </tr>
+ <?php endif ?>
+ <tr>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'addfamlink', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref()])) ?>">
+ <?= I18N::translate('Link this individual to an existing family as a child') ?>
+ </a>
+ </td>
+ </tr>
+ <?php if ($individual->getSex() !== 'F'): ?>
+ <tr>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_spouse_to_individual', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'sex' => 'F'])) ?>">
+ <?= I18N::translate('Add a wife') ?>
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'linkspouse', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'famtag' => 'WIFE'])) ?>">
+ <?= I18N::translate('Add a wife using an existing individual') ?>
+ </a>
+ </td>
+ </tr>
+ <?php endif ?>
+
+ <?php if ($individual->getSex() !== 'M'): ?>
+ <tr>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_spouse_to_individual', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'sex' => 'M'])) ?>">
+ <?= I18N::translate('Add a husband') ?>
+ </a>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'linkspouse', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'famtag' => 'HUSB'])) ?>">
+ <?= I18N::translate('Add a husband using an existing individual') ?>
+ </a>
+ </td>
+ </tr>
+ <?php endif ?>
+ <tr>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_child_to_individual', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'gender' => 'U'])) ?>">
+ <?= I18N::translate('Add a child to create a one-parent family') ?>
+ </a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+<?php endif ?>
+</div>
+
+<?php View::push('javascript') ?>
+<script>
+ 'use strict';
+
+ persistent_toggle("show-date-differences", ".elderdate");
+</script>
+<?php View::endpush() ?>
diff --git a/resources/views/modules/sources_tab/tab.php b/resources/views/modules/sources_tab/tab.php
new file mode 100644
index 0000000000..0918076156
--- /dev/null
+++ b/resources/views/modules/sources_tab/tab.php
@@ -0,0 +1,51 @@
+<?php use Fisharebest\Webtrees\Functions\FunctionsPrintFacts; ?>
+<?php use Fisharebest\Webtrees\Html; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+<?php use Fisharebest\Webtrees\View; ?>
+
+<div class="wt-sources-tab py-4">
+ <table class="table wt-facts-table">
+ <tr>
+ <td colspan="2">
+ <label>
+ <input id="show-level-2-sources" type="checkbox">
+ <?= I18N::translate('Show all sources') ?>
+ </label>
+ </td>
+ </tr>
+
+ <?php foreach ($facts as $fact): ?>
+ <?php FunctionsPrintFacts::printMainSources($fact, 1) ?>
+ <?php FunctionsPrintFacts::printMainSources($fact, 2) ?>
+ <?php endforeach ?>
+
+ <?php if (empty($facts)): ?>
+ <tr>
+ <td colspan="2">
+ <?= I18N::translate('There are no source citations for this individual.') ?>
+ </td>
+ </tr>
+ <?php endif ?>
+
+ <?php if ($can_edit): ?>
+ <tr>
+ <th scope="row">
+ <?= I18N::translate('Source') ?>
+ </th>
+ <td>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $individual->getTree()->getName(), 'xref' => $individual->getXref(), 'fact' => 'SOUR'])) ?>">
+ <?= I18N::translate('Add a source citation') ?>
+ </a>
+ </td>
+ </tr>
+ <?php endif ?>
+ </table>
+</div>
+
+<?php View::push('javascript') ?>
+<script>
+ 'use strict';
+
+ persistent_toggle("show-level-2-sources", ".row_sour2");
+</script>
+<?php View::endpush() ?>
diff --git a/resources/views/modules/tree/tab.php b/resources/views/modules/tree/tab.php
new file mode 100644
index 0000000000..aa5856c707
--- /dev/null
+++ b/resources/views/modules/tree/tab.php
@@ -0,0 +1,19 @@
+<?php use Fisharebest\Webtrees\View; ?>
+
+<div class="wt-tree-tab py-4">
+ <?= $html ?>
+</div>
+
+<?php View::push('javascript') ?>
+<script src="<?= e($treeview_js) ?>"></script>
+
+<script>
+ var newSheet=document.createElement("link");
+ newSheet.setAttribute("rel","stylesheet");
+ newSheet.setAttribute("type","text/css");
+ newSheet.setAttribute("href","<?= $treeview_css ?>");
+ document.head.appendChild(newSheet);
+
+ <?= $js ?>
+</script>
+<?php View::endpush() ?>