Skip to content
Open
2 changes: 2 additions & 0 deletions app/CustomTags/Gedcom7.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public function tags(): array
'FAM:*:ASSO:ROLE' => new RoleInEvent(I18N::translate('Role')),
'FAM:*:ASSO:ROLE:PHRASE' => new CustomElement(I18N::translate('Phrase')),
'FAM:*:DATE:TIME' => new TimeValue(I18N::translate('Time')),
'FAM:*:DATE:PHRASE' => new CustomElement(I18N::translate('Phrase')),
'FAM:*:PLAC:EXID' => new ExternalIdentifier(I18N::translate('External identifier')),
'FAM:*:PLAC:EXID:TYPE' => new ExternalIdentifierType(I18N::translate('Type')),
'FAM:*:SDATE' => new CustomElement(I18N::translate('Sort date')),
Expand Down Expand Up @@ -108,6 +109,7 @@ public function tags(): array
'INDI:*:ASSO:ROLE' => new RoleInEvent(I18N::translate('Role')),
'INDI:*:ASSO:ROLE:PHRASE' => new CustomElement(I18N::translate('Phrase')),
'INDI:*:DATE:TIME' => new TimeValue(I18N::translate('Time')),
'INDI:*:DATE:PHRASE' => new CustomElement(I18N::translate('Phrase')),
'INDI:*:PLAC:EXID' => new ExternalIdentifier(I18N::translate('External identifier')),
'INDI:*:PLAC:EXID:TYPE' => new ExternalIdentifierType(I18N::translate('Type')),
'INDI:*:SDATE' => new CustomElement(I18N::translate('Sort date')),
Expand Down
10 changes: 6 additions & 4 deletions app/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function __construct(string $date)
$calendar_date_factory = Registry::calendarDateFactory();

// Extract any explanatory text
if (preg_match('/^(.*) ?[(](.*)[)]/', $date, $match)) {
if (preg_match('/^(.*?) ?[(](.*)[)]/', $date, $match)) {
$date = $match[1];
$this->text = $match[2];
}
Expand Down Expand Up @@ -123,7 +123,7 @@ public function display(Tree|null $tree = null, string|null $date_format = null,
} else {
$d2 = $this->date2->format($date_format, $this->qual2);
}
// Con vert to other calendars, if requested
// Convert to other calendars, if requested
$conv1 = '';
$conv2 = '';
foreach ($calendar_format as $cal_fmt) {
Expand Down Expand Up @@ -180,7 +180,7 @@ public function display(Tree|null $tree = null, string|null $date_format = null,
case '':
$tmp = $d1 . $conv1;
if ($this->text !== '') {
$tmp .= '(' . e($this->text) . ')';
$tmp .= ' <span class="date phrase">' . e($this->text) . '</span>';
}
break;
case 'ABT':
Expand All @@ -197,7 +197,9 @@ public function display(Tree|null $tree = null, string|null $date_format = null,
break;
case 'INT':
/* I18N: Gedcom INT dates */
$tmp = I18N::translate('interpreted %s (%s)', $d1 . $conv1, e($this->text));
$tmp = I18N::translate('interpreted %s (%s)', $d1 . $conv1, '${DATE_PHRASE}');
$phrase = ($this->text == '') ? '' : '<span class="date phrase">' . e($this->text) . '</span>';
$tmp = str_replace('(${DATE_PHRASE})', $phrase, $tmp);
break;
case 'BEF':
/* I18N: Gedcom BEF dates */
Expand Down
10 changes: 10 additions & 0 deletions app/Elements/DateValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ public function edit(string $id, string $name, string $value, Tree $tree): strin
'<div class="form-text">' . (new Date($value))->display() . '</div>';
}

/**
* Should we collapse the children of this element when editing?
*
* @return bool
*/
public function collapseChildren(): bool
{
return true;
}

/**
* Escape @ signs in a GEDCOM export.
*
Expand Down
27 changes: 27 additions & 0 deletions app/Gedcom.php
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,33 @@ private function customSubTags(): array
$subtags['INDI:DEAT:DATE'][] = ['TIME', '0:1'];
}

if (Site::getPreference('CUSTOM_DATEPHRASE_TAGS') === '1') {
// needed when the fact date has an explicit translation set in function gedcom551Tags
$subtags['FAM:DIV:DATE'][] = ['PHRASE', '0:1'];
$subtags['FAM:ENGA:DATE'][] = ['PHRASE', '0:1'];
$subtags['FAM:MARB:DATE'][] = ['PHRASE', '0:1'];
$subtags['FAM:MARR:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:ADOP:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:BAPM:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:BARM:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:BASM:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:BIRT:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:BLES:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:BURI:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:CENS:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:CHR:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:CONF:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:CREM:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:DEAT:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:EMIG:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:EVEN:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:FCOM:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:IMMI:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:NATU:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:ORDN:DATE'][] = ['PHRASE', '0:1'];
$subtags['INDI:RESI:DATE'][] = ['PHRASE', '0:1'];
}

if (Site::getPreference('CUSTOM_GEDCOM_L_TAGS') === '1') {
$subtags['FAM'][] = ['_ASSO', '0:M'];
$subtags['FAM'][] = ['_STAT', '0:1'];
Expand Down
2 changes: 2 additions & 0 deletions app/Http/RequestHandlers/SiteTagsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
$custom_fam_nchi = Validator::parsedBody($request)->boolean('custom_fam_nchi', false);
$custom_resi_value = Validator::parsedBody($request)->boolean('custom_resi_value', false);
$custom_time_tags = Validator::parsedBody($request)->boolean('custom_time_tags', false);
$custom_datephrase_tags = Validator::parsedBody($request)->boolean('custom_datephrase_tags', false);

Site::setPreference('CUSTOM_FAMILY_TAGS', implode(',', $custom_family_tags));
Site::setPreference('CUSTOM_INDIVIDUAL_TAGS', implode(',', $custom_individual_tags));
Expand All @@ -57,6 +58,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
Site::setPreference('CUSTOM_FAM_NCHI', (string) $custom_fam_nchi);
Site::setPreference('CUSTOM_RESI_VALUE', (string) $custom_resi_value);
Site::setPreference('CUSTOM_TIME_TAGS', (string) $custom_time_tags);
Site::setPreference('CUSTOM_DATEPHRASE_TAGS', (string) $custom_datephrase_tags);

FlashMessages::addMessage(I18N::translate('The website preferences have been updated.'), 'success');

Expand Down
10 changes: 6 additions & 4 deletions app/Http/RequestHandlers/SiteTagsPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ public function handle(ServerRequestInterface $request): ResponseInterface
$custom_gedcom_l_tags = (bool) Site::getPreference('CUSTOM_GEDCOM_L_TAGS');

// GEDCOM 7 extensions
$custom_fam_fact = (bool) Site::getPreference('CUSTOM_FAM_FACT');
$custom_fam_nchi = (bool) Site::getPreference('CUSTOM_FAM_NCHI');
$custom_resi_value = (bool) Site::getPreference('CUSTOM_RESI_VALUE');
$custom_time_tags = (bool) Site::getPreference('CUSTOM_TIME_TAGS');
$custom_fam_fact = (bool) Site::getPreference('CUSTOM_FAM_FACT');
$custom_fam_nchi = (bool) Site::getPreference('CUSTOM_FAM_NCHI');
$custom_resi_value = (bool) Site::getPreference('CUSTOM_RESI_VALUE');
$custom_time_tags = (bool) Site::getPreference('CUSTOM_TIME_TAGS');
$custom_datephrase_tags = (bool) Site::getPreference('CUSTOM_DATEPHRASE_TAGS');

return $this->viewResponse('admin/tags', [
'all_family_tags' => $all_family_tags->sort()->all(),
Expand All @@ -71,6 +72,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface
'custom_fam_nchi' => $custom_fam_nchi,
'custom_resi_value' => $custom_resi_value,
'custom_time_tags' => $custom_time_tags,
'custom_datephrase_tags' => $custom_datephrase_tags,
'element_factory' => Registry::elementFactory(),
'title' => I18N::translate('GEDCOM tags'),
]);
Expand Down
7 changes: 7 additions & 0 deletions resources/css/_base.css
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,10 @@ a:hover, .btn-link:hover, .nav-link:hover {
.leaflet-bottom, .leaflet-top {
z-index: 999;
}

.date.phrase::before {
content: "(";
}
.date.phrase::after {
content: ")";
}
17 changes: 17 additions & 0 deletions resources/views/admin/tags.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use Fisharebest\Webtrees\Site;
* @var bool $custom_fam_nchi
* @var bool $custom_resi_value
* @var bool $custom_time_tags
* @var bool $custom_datephrase_tags
* @var ElementFactoryInterface $element_factory
* @var string $title
*/
Expand Down Expand Up @@ -971,6 +972,22 @@ use Fisharebest\Webtrees\Site;
</td>
</tr>

<tr>
<td>
<?= I18N::translate('Textual information that cannot be expressed in the date itself') ?>
</td>

<td>
<code dir="ltr">INDI:*:DATE:PHRASE</code>
<br>
<code dir="ltr">FAM:*:DATE:PHRASE</code>
</td>

<td>
<?= view('components/checkbox', ['id' => 'custom_datephrase_tags', 'name' => 'custom_datephrase_tags', 'label' => I18N::translate('show'), 'checked' => $custom_datephrase_tags]) ?>
</td>
</tr>

<tr>
<td>
<?= I18N::translate('Family fact') ?>
Expand Down
26 changes: 16 additions & 10 deletions resources/views/fact-date.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use Fisharebest\Webtrees\Registry;
*/

$factrec = $fact->gedcom();
$html = '';

// Recorded age
if (preg_match('/\n2 AGE (.+)/', $factrec, $match) === 1) {
Expand All @@ -42,18 +41,25 @@ if (preg_match('/\n2 WIFE\n3 AGE (.+)/', $factrec, $match) === 1) {
$wife_age = '';
}

// Calculated age
[, $tag] = explode(':', $fact->tag());

if (preg_match('/\n2 DATE (.+)/', $factrec, $match) === 1) {
$date = new Date($match[1]);
$html .= ' ' . $date->display($cal_link ? $record->tree() : null, null, true);
$date = '';
$html = '';
if (preg_match('/\n2 DATE\s(.+)/', $factrec) === 1) {
$htmlParts = [];
if (preg_match('/\n2 DATE (.+)/', $factrec, $match) === 1) {
$date = new Date($match[1]);
$htmlParts[] = $date->display($cal_link ? $record->tree() : null, null, true);
}
// Time isn't valid GEDCOM, but it is widely used.
if ($time && preg_match('/\n3 TIME (.+)/', $factrec, $match) === 1) {
$html .= '<span class="date">' . $match[1] . '</span>';
$htmlParts[] = '<span class="date time">' . $match[1] . '</span>';
}

if ($record instanceof Individual) {
$html .= join(' - ', $htmlParts);
if (preg_match('/2 DATE.*(?:\n[3-9].*)*\n3 PHRASE (.+)/', $factrec, $match) === 1) {
$html .= ' <span class="date phrase">' . $match[1] . '</span>';
}
if ($date !== '' && $record instanceof Individual) {
// Calculated age
[, $tag] = explode(':', $fact->tag());
if (
in_array($tag, Gedcom::BIRTH_EVENTS, true) &&
$record === $fact->record() &&
Expand Down