summaryrefslogtreecommitdiff
path: root/resources
diff options
context:
space:
mode:
authorGreg Roach <fisharebest@gmail.com>2018-01-10 21:43:33 +0000
committerGreg Roach <fisharebest@gmail.com>2018-01-13 11:26:45 +0000
commit225e381f36d59b49c8cdac0060465fa5af2fc308 (patch)
tree89cdab8ff4f2fd708b54c292ed2339c2028d38a4 /resources
parent181186b616da35d9a7627f0b17fa144ff9355c99 (diff)
downloadwebtrees-225e381f36d59b49c8cdac0060465fa5af2fc308.tar.gz
webtrees-225e381f36d59b49c8cdac0060465fa5af2fc308.tar.bz2
webtrees-225e381f36d59b49c8cdac0060465fa5af2fc308.zip
Use views for genealogy objects
Diffstat (limited to 'resources')
-rw-r--r--resources/views/family-page.php62
-rw-r--r--resources/views/gedcom-record-page.php9
-rw-r--r--resources/views/individual-page.php46
-rw-r--r--resources/views/layouts/ajax.php5
-rw-r--r--resources/views/media-page.php9
-rw-r--r--resources/views/note-page.php9
-rw-r--r--resources/views/repository-page.php9
-rw-r--r--resources/views/source-page.php9
-rw-r--r--resources/views/tabs/album.php2
-rw-r--r--resources/views/tabs/facts.php50
-rw-r--r--resources/views/tabs/map.php38
-rw-r--r--resources/views/tabs/media.php21
-rw-r--r--resources/views/tabs/notes.php63
-rw-r--r--resources/views/tabs/relatives-family.php215
-rw-r--r--resources/views/tabs/relatives.php155
-rw-r--r--resources/views/tabs/sources.php51
-rw-r--r--resources/views/tabs/stories.php28
-rw-r--r--resources/views/tabs/treeview.php19
18 files changed, 737 insertions, 63 deletions
diff --git a/resources/views/family-page.php b/resources/views/family-page.php
index d91b55dc6f..d782118978 100644
--- a/resources/views/family-page.php
+++ b/resources/views/family-page.php
@@ -5,30 +5,34 @@
<?php use Fisharebest\Webtrees\Html; ?>
<?php use Fisharebest\Webtrees\I18N; ?>
<?php use Fisharebest\Webtrees\Theme; ?>
-<?php use Fisharebest\Webtrees\View; ?>
-<?php if ($family->isPendingDeletion()): ?>
- <?php if (Auth::isModerator($family->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This family has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $family->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $family->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
- <?php elseif (Auth::isEditor($family->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This family has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+<?php if ($record->isPendingDeletion()): ?>
+ <?php if (Auth::isModerator($record->getTree())): ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This family has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?php elseif (Auth::isEditor($record->getTree())): ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This family has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
-<?php elseif ($family->isPendingAddition()): ?>
- <?php if (Auth::isModerator($family->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This family has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $family->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $family->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
- <?php elseif (Auth::isEditor($family->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This family has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+<?php elseif ($record->isPendingAddition()): ?>
+ <?php if (Auth::isModerator($record->getTree())): ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This family has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?php elseif (Auth::isEditor($record->getTree())): ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This family has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php endif ?>
-<h2 class="wt-page-title">
- <?= $family->getFullName() ?>
-</h2>
+<div class="d-flex">
+ <h2 class="wt-page-title mx-auto">
+ <?= $record->getFullName() ?>
+ </h2>
+ <ul class="nav">
+ <?= $menu->bootstrap4() ?>
+ </ul>
+</div>
<table id="family-table" class="w-100" role="presentation">
<tr style="vertical-align:top;">
<td style="width: <?= Theme::theme()->parameter('chart-box-x') + 30 ?>px;">
- <?php FunctionsCharts::printFamilyChildren($family) ?>
+ <?php FunctionsCharts::printFamilyChildren($record) ?>
</td>
<td>
<table class="w-100" role="presentation">
@@ -38,16 +42,16 @@
</tr>
<tr>
<td colspan="2">
- <?php FunctionsCharts::printFamilyParents($family) ?>
- <?php if (Auth::isEditor($family->getTree())): ?>
- <?php if ($family->getHusband() === null): ?>
- <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_spouse_to_family', 'ged=' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'famtag' => 'HUSB'])) ?>>
+ <?php FunctionsCharts::printFamilyParents($record) ?>
+ <?php if (Auth::isEditor($record->getTree())): ?>
+ <?php if ($record->getHusband() === null): ?>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_spouse_to_family', 'ged=' => $record->getTree()->getName(), 'xref' => $record->getXref(), 'famtag' => 'HUSB'])) ?>>
<?= I18N::translate('Add a father') ?>
</a>
<br>
<?php endif ?>
- <?php if ($family->getWife() === null): ?>
- <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_spouse_to_family', 'ged=' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'famtag' => 'WIFE'])) ?>>
+ <?php if ($record->getWife() === null): ?>
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add_spouse_to_family', 'ged=' => $record->getTree()->getName(), 'xref' => $record->getXref(), 'famtag' => 'WIFE'])) ?>>
<?= I18N::translate('Add a mother') ?>
</a>
<br>
@@ -67,18 +71,18 @@
</tr>
<?php else: ?>
<?php foreach ($facts as $fact): ?>
- <?php FunctionsPrintFacts::printFact($fact, $family) ?>
+ <?php FunctionsPrintFacts::printFact($fact, $record) ?>
<?php endforeach ?>
<?php endif ?>
- <?php if (Auth::isEditor($family->getTree())): ?>
- <?php FunctionsPrint::printAddNewFact($family->getXref(), $facts, 'FAM') ?>
+ <?php if (Auth::isEditor($record->getTree())): ?>
+ <?php FunctionsPrint::printAddNewFact($record->getXref(), $facts, 'FAM') ?>
<tr>
<th scope="row">
<?= I18N::translate('Note') ?>
</th>
<td>
- <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'fact' => 'NOTE'])) ?>">
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $record->getTree()->getName(), 'xref' => $record->getXref(), 'fact' => 'NOTE'])) ?>">
<?= I18N::translate('Add a note') ?>
</a>
</td>
@@ -89,19 +93,19 @@
<?= I18N::translate('Shared note') ?>
</th>
<td class="optionbox">
- <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'fact' => 'SHARED_NOTE'])) ?>">
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $record->getTree()->getName(), 'xref' => $record->getXref(), 'fact' => 'SHARED_NOTE'])) ?>">
<?= I18N::translate('Add a shared note') ?>
</a>
</td>
</tr>
- <?php if ($family->getTree()->getPreference('MEDIA_UPLOAD') >= Auth::accessLevel($family->getTree())): ?>
+ <?php if ($record->getTree()->getPreference('MEDIA_UPLOAD') >= Auth::accessLevel($record->getTree())): ?>
<tr>
<th scope="row">
<?= I18N::translate('Media object') ?>
</th>
<td class="optionbox">
- <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add-media-link', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref()])) ?>">
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add-media-link', 'ged' => $record->getTree()->getName(), 'xref' => $record->getXref()])) ?>">
<?= I18N::translate('Add a media object') ?>
</a>
</td>
@@ -113,7 +117,7 @@
<?= I18N::translate('Source') ?>
</th>
<td>
- <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $family->getTree()->getName(), 'xref' => $family->getXref(), 'fact' => 'SOUR'])) ?>">
+ <a href="<?= e(Html::url('edit_interface.php', ['action' => 'add', 'ged' => $record->getTree()->getName(), 'xref' => $record->getXref(), 'fact' => 'SOUR'])) ?>">
<?= I18N::translate('Add a source citation') ?>
</a>
</td>
diff --git a/resources/views/gedcom-record-page.php b/resources/views/gedcom-record-page.php
index 36a2552141..5b02c60c0e 100644
--- a/resources/views/gedcom-record-page.php
+++ b/resources/views/gedcom-record-page.php
@@ -4,19 +4,18 @@
<?php use Fisharebest\Webtrees\Functions\FunctionsPrintFacts; ?>
<?php use Fisharebest\Webtrees\Functions\FunctionsPrintLists; ?>
<?php use Fisharebest\Webtrees\I18N; ?>
-<?php use Fisharebest\Webtrees\View; ?>
<?php if ($record->isPendingDeletion()): ?>
<?php if (Auth::isModerator($record->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This record has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This record has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($record->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This record has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This record has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php elseif ($record->isPendingAddition()): ?>
<?php if (Auth::isModerator($record->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This record has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This record has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $record->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($record->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This record has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This record has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php endif ?>
diff --git a/resources/views/individual-page.php b/resources/views/individual-page.php
index f954f3eb91..bb4f7fb24a 100644
--- a/resources/views/individual-page.php
+++ b/resources/views/individual-page.php
@@ -6,15 +6,15 @@
<?php if ($individual->isPendingDeletion()): ?>
<?php if (Auth::isModerator($individual->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This individual has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $individual->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $individual->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This individual has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $individual->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $individual->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($individual->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This individual has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This individual has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php elseif ($individual->isPendingAddition()): ?>
<?php if (Auth::isModerator($individual->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This individual has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $individual->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $individual->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This individual has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $individual->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $individual->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($individual->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This individual has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This individual has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php endif ?>
@@ -106,7 +106,7 @@
<ul class="nav nav-tabs flex-wrap">
<?php foreach ($tabs as $tab): ?>
<li class="nav-item">
- <a class="nav-link<?= $tab->isGrayedOut() ? ' text-muted' : '' ?>" data-toggle="tab" role="tab" data-href="<?= e($individual->url()), '&amp;action=ajax&amp;module=', $tab->getName() ?>" href="#<?= $tab->getName() ?>">
+ <a class="nav-link<?= $tab->isGrayedOut($individual) ? ' text-muted' : '' ?>" data-toggle="tab" role="tab" data-href="<?= e(route('individual-tab', ['xref' => $individual->getXref(), 'ged' => $individual->getTree()->getName(), 'module' => $tab->getName()])) ?>" href="#<?= $tab->getName() ?>">
<?= $tab->getTitle() ?>
</a>
</li>
@@ -115,15 +115,45 @@
<div class="tab-content">
<?php foreach ($tabs as $tab): ?>
<div id="<?= $tab->getName() ?>" class="tab-pane fade wt-ajax-load" role="tabpanel"><?php if (!$tab->canLoadAjax()): ?>
- <?= $tab->getTabContent() ?>
+ <?= $tab->getTabContent($individual) ?>
<?php endif ?></div>
<?php endforeach ?>
</div>
</div>
</div>
- <div class="col-sm-4">
- <?= $sidebar_html ?>
+ <div class="col-sm-4" id="sidebar" role="tablist">
+ <?php foreach ($sidebars as $sidebar): ?>
+ <div class="card">
+ <div class="card-header" role="tab" id="sidebar-header-<?= $sidebar->getName() ?>">
+ <div class="card-title mb-0">
+ <a data-toggle="collapse" data-parent="#sidebar" href="#sidebar-content-<?= $sidebar->getName() ?>" aria-expanded="<?= $sidebar->getName() === 'family_nav' ? 'true' : 'false' ?>" aria-controls="sidebar-content-<?= $sidebar->getName() ?>">
+ <?= $sidebar->getTitle() ?>
+ </a>
+ </div>
+ </div>
+ <div id="sidebar-content-<?= $sidebar->getName() ?>" class="collapse<?= $sidebar->getName() === 'family_nav' ? ' show' : '' ?>" role="tabpanel" aria-labelledby="sidebar-header-<?= $sidebar->getName() ?>">
+ <div class="card-body">
+ <?= $sidebar->getSidebarContent($individual) ?></div>
+ </div>
+ </div>
+ <?php endforeach ?>
</div>
</div>
+<?php View::push('javascript') ?>
+<script>
+ 'use strict';
+
+ // If the URL contains a fragment, then activate the corresponding tab.
+ // Use a prefix on the fragment, to prevent scrolling to the element.
+ var target = window.location.hash.replace("tab-", "");
+ var tab = $("#individual-tabs .nav-link[href='" + target + "']");
+ // If not, then activate the first tab.
+ if (tab.length === 0) {
+ tab = $("#individual-tabs .nav-link:first");
+ }
+ tab.tab("show");
+</script>
+<?php View::endpush() ?>
+
<?= view('modals/ajax') ?>
diff --git a/resources/views/layouts/ajax.php b/resources/views/layouts/ajax.php
new file mode 100644
index 0000000000..34ec603fd3
--- /dev/null
+++ b/resources/views/layouts/ajax.php
@@ -0,0 +1,5 @@
+<?php use Fisharebest\Webtrees\View; ?>
+
+<?= $content ?>
+
+<?= View::stack('javascript') ?>
diff --git a/resources/views/media-page.php b/resources/views/media-page.php
index 43509f5a8d..edc52f1a9d 100644
--- a/resources/views/media-page.php
+++ b/resources/views/media-page.php
@@ -7,19 +7,18 @@
<?php use Fisharebest\Webtrees\GedcomTag; ?>
<?php use Fisharebest\Webtrees\Html; ?>
<?php use Fisharebest\Webtrees\I18N; ?>
-<?php use Fisharebest\Webtrees\View; ?>
<?php if ($media->isPendingDeletion()): ?>
<?php if (Auth::isModerator($media->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This media object has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $media->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $media->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This media object has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $media->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $media->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($media->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This media object has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This media object has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php elseif ($media->isPendingAddition()): ?>
<?php if (Auth::isModerator($media->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This media object has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $media->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $media->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This media object has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $media->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $media->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($media->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This media object has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This media object has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php endif ?>
diff --git a/resources/views/note-page.php b/resources/views/note-page.php
index d0d0dc0dbb..b27791437a 100644
--- a/resources/views/note-page.php
+++ b/resources/views/note-page.php
@@ -5,19 +5,18 @@
<?php use Fisharebest\Webtrees\Functions\FunctionsPrintFacts; ?>
<?php use Fisharebest\Webtrees\Functions\FunctionsPrintLists; ?>
<?php use Fisharebest\Webtrees\I18N; ?>
-<?php use Fisharebest\Webtrees\View; ?>
<?php if ($note->isPendingDeletion()): ?>
<?php if (Auth::isModerator($note->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This note has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $note->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $note->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This note has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $note->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $note->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($note->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This note has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This note has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php elseif ($note->isPendingAddition()): ?>
<?php if (Auth::isModerator($note->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This note has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $note->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $note->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This note has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $note->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $note->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($note->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This note has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This note has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php endif ?>
diff --git a/resources/views/repository-page.php b/resources/views/repository-page.php
index 73113255de..c8fd4c251a 100644
--- a/resources/views/repository-page.php
+++ b/resources/views/repository-page.php
@@ -4,19 +4,18 @@
<?php use Fisharebest\Webtrees\Functions\FunctionsPrintFacts; ?>
<?php use Fisharebest\Webtrees\Functions\FunctionsPrintLists; ?>
<?php use Fisharebest\Webtrees\I18N; ?>
-<?php use Fisharebest\Webtrees\View; ?>
<?php if ($repository->isPendingDeletion()): ?>
<?php if (Auth::isModerator($repository->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This repository has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $repository->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $repository->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This repository has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $repository->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $repository->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($repository->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This repository has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This repository has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php elseif ($repository->isPendingAddition()): ?>
<?php if (Auth::isModerator($repository->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This repository has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $repository->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $repository->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This repository has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $repository->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $repository->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($repository->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This repository has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This repository has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php endif ?>
diff --git a/resources/views/source-page.php b/resources/views/source-page.php
index 16c9766817..aba7e6f26b 100644
--- a/resources/views/source-page.php
+++ b/resources/views/source-page.php
@@ -5,19 +5,18 @@
<?php use Fisharebest\Webtrees\Functions\FunctionsPrintLists; ?>
<?php use Fisharebest\Webtrees\Html; ?>
<?php use Fisharebest\Webtrees\I18N; ?>
-<?php use Fisharebest\Webtrees\View; ?>
<?php if ($source->isPendingDeletion()): ?>
<?php if (Auth::isModerator($source->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This source has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $source->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $source->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This source has been deleted. You should review the deletion and then %1$s or %2$s it.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $source->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $source->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($source->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This source has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This source has been deleted. The deletion will need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php elseif ($source->isPendingAddition()): ?>
<?php if (Auth::isModerator($source->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This source has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $source->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $source->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => /* I18N: %1$s is “accept”, %2$s is “reject”. These are links. */ I18N::translate( 'This source has been edited. You should review the changes and then %1$s or %2$s them.', '<a href="#" class="alert-link" onclick="accept_changes(\'' . $source->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'accept') . '</a>', '<a href="#" class="alert-link" onclick="reject_changes(\'' . $source->getXref() . '\');">' . I18N::translateContext('You should review the changes and then accept or reject them.', 'reject') . '</a>' ) . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php elseif (Auth::isEditor($source->getTree())): ?>
- <?= View::make('alerts/warning-dissmissible', ['alert' => I18N::translate('This source has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
+ <?= view('alerts/warning-dissmissible', ['alert' => I18N::translate('This source has been edited. The changes need to be reviewed by a moderator.') . ' ' . FunctionsPrint::helpLink('pending_changes')]) ?>
<?php endif ?>
<?php endif ?>
diff --git a/resources/views/tabs/album.php b/resources/views/tabs/album.php
index f9f41fda9a..9c11577793 100644
--- a/resources/views/tabs/album.php
+++ b/resources/views/tabs/album.php
@@ -1,4 +1,4 @@
-<div class="wt-album-tab row py-4">
+<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): ?>
diff --git a/resources/views/tabs/facts.php b/resources/views/tabs/facts.php
new file mode 100644
index 0000000000..743bb9eddf
--- /dev/null
+++ b/resources/views/tabs/facts.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/tabs/map.php b/resources/views/tabs/map.php
new file mode 100644
index 0000000000..376234adf9
--- /dev/null
+++ b/resources/views/tabs/map.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' => 'googlemaps', 'mod_action' => 'admin_config'])) ?>">
+ <?= I18N::translate('Google Maps™ preferences') ?>
+ </a>
+ |
+ <a href="<?= e(Html::url('module.php', ['mod' => 'googlemaps', '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/tabs/media.php b/resources/views/tabs/media.php
new file mode 100644
index 0000000000..86343b3701
--- /dev/null
+++ b/resources/views/tabs/media.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/tabs/notes.php b/resources/views/tabs/notes.php
new file mode 100644
index 0000000000..64b248e135
--- /dev/null
+++ b/resources/views/tabs/notes.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/tabs/relatives-family.php b/resources/views/tabs/relatives-family.php
new file mode 100644
index 0000000000..b14df2dfa8
--- /dev/null
+++ b/resources/views/tabs/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(Html::url('edit_interface.php', ['action' => '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/tabs/relatives.php b/resources/views/tabs/relatives.php
new file mode 100644
index 0000000000..f857740980
--- /dev/null
+++ b/resources/views/tabs/relatives.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('tabs/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('tabs/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('tabs/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('tabs/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(Html::url('edit_interface.php', ['action' => '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/tabs/sources.php b/resources/views/tabs/sources.php
new file mode 100644
index 0000000000..0918076156
--- /dev/null
+++ b/resources/views/tabs/sources.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/tabs/stories.php b/resources/views/tabs/stories.php
new file mode 100644
index 0000000000..198532c016
--- /dev/null
+++ b/resources/views/tabs/stories.php
@@ -0,0 +1,28 @@
+<?php use Fisharebest\Webtrees\Html; ?>
+<?php use Fisharebest\Webtrees\I18N; ?>
+
+<div class="wt-stories-tab py-4">
+ <?php foreach ($stories as $story): ?>
+ <div class="story_title descriptionbox center rela">
+ <?= e($story->title) ?>
+ </div>
+ <div class="story_body optionbox">
+ <?= $story->body ?>
+ </div>
+ <?php if ($is_editor): ?>
+ <div class="story_edit">
+ <a href="<?= e(Html::url('module.php', ['mod' => 'stories', 'mod_action' => 'admin_edit', 'block_id' => $story->block_id])) ?>">
+ <?= I18N::translate('Edit the story') ?>
+ </a>
+ </div>
+ <?php endif ?>
+ <?php endforeach ?>
+
+ <?php if ($is_manager && empty($stories)): ?>
+ <div>
+ <a href="<?= e(Html::url('module.php', ['mod' => 'stories', 'mod_action' => 'admin_edit', 'xref' => $individual->getXref()])) ?>">
+ <?= I18N::translate('Add a story') ?>
+ </a>
+ </div>
+ <?php endif ?>
+</div>
diff --git a/resources/views/tabs/treeview.php b/resources/views/tabs/treeview.php
new file mode 100644
index 0000000000..37197f75da
--- /dev/null
+++ b/resources/views/tabs/treeview.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","<?= $google_map_css ?>");
+ document.head.appendChild(newSheet);
+
+ <?= $js ?>
+</script>
+<?php View::endpush() ?>