v94 必填项改成「标签红色加粗」,去掉红色星号 (#3)

需求(用户 2026-10-25):必填项原来在标题后面加一个红色星号,排版经常不齐。
改成「标题本身红色 + 加粗」——用户习惯后,看到红色加粗的标题就知道是必填。

CSS(assets/css/app.css):
- :root 新增 --req:#B03A2E、--req-w:700。
  · 不用 --red(#C0533F):那是动作红(删除按钮底色),当文字色放在暖纸底
    #F7F3EA 上对比度只有 ≈3.4:1,13-14px 标签偏浅;#B03A2E 约 4.6:1。
  · --req-w 必须 700 不能 650/600:本站标签基线字重本来就是 600
    (.form-grid > .field > label / .card .field > label / .mv-row > .mv-lb /
    .dt-range-label 四处都是 600),650 会被取整回 600 = 完全没加粗。
- 文件末尾新增「必填项统一标记」段,覆盖四种标签形态:
  label.is-req / .mv-lb.is-req / .dt-inline-lab.is-req / .dt-range-label.is-req,
  用 !important 打穿各宿主选择器的特异性(颜色与字重是语义标记,不该被面板样式盖掉)。
- 冒号跟着变红:.mv-lb::after / .dt-inline-lab::after 原本是灰色 400,
  只改标签本体会剩「红字 + 灰冒号」的半截效果。
- 包裹层兜底(.field.is-req > label 等),只作用直接子级 ——
  不写 .field.is-req label,那会把「提醒」那排 checkbox 的小标签一起染红。
- 深色主题给备用色 #F08A78。
- 保留 .mv-row > .mv-lb > i(万一有没清干净的星号不至于露灰星花,且静态断言会报出来)。

模板(16 个文件 / 30 处):
- _event_fields.php / _datetime.php 的标签闭包第三参数 $star → $req,
  $dtLabelStar → $dtLabelReq,删掉死引用 $evLabelStar。
- 其余 14 个模板把 `<i>*</i>` 换成给标签加 is-req 类。
- 用显式 .is-req 而不靠 required 属性反推:CSS 无父选择器,:has() 旧 WebView
  不可用,且影院名称/板块名本来就靠 JS 校验没有 required。

验证:
- 静态 _fb_v94_static.py 22/0,反向 9/9(含「--req-w 必须严格大于从 CSS 解析出的
  标签基线字重」,不写死 700)。
- 真浏览器 _fb_v94_req.py 63/0,反向 5/5(加粗/必须红/!important 必要性/
  星号必须消失/每形态单独覆盖,五类注入各自精确命中预期断言)。
- 全量流水线(含 60+ 套件)通过并部署。
- 线上真实页面 _fb_v94_live.py 31/0:观影「片名」、旅程「旅程名」、
  成员「姓名」、导航「网址/所属板块」实测 color=rgb(176,58,46) weight=700,
  同页非必填 color=rgb(44,35,29) weight=600,冒号同色,无星号。
This commit is contained in:
2026-10-26 06:45:38 +08:00
parent f1b09a2f41
commit daf5ca904e
17 changed files with 176 additions and 44 deletions
+9 -4
View File
@@ -44,7 +44,10 @@
* 为什么要它:用户 2026-10-12 第 2 条要求「日期范围:」与最新控件
* **在同一行**。宿主的 `.mv-grid` 行结构把标签与控件分在两行,
* 与其在 CSS 里跟行结构较劲,不如让控件**自带**标签 —— 位置确定。
* $dtLabelStar 标签后是否跟一颗必填星号(配 $dtLabel 用)
* $dtLabelReq 该标签是否表示**必填**(配 $dtLabel 用)。
* 🔴 v94 起不再画星号,而是给标签加 `.is-req`(红字加粗)。
* 参数名 v94 起从 `$dtLabelReq` 更名为 `$dtLabelReq`:它原来叫
* "加星",现在只表示"这是必填",旧名会让人以为还在画星号。
* $dtPlugin 🔴 v38 插件开关:'antd' = 由 app.js 把这两个端点升级成
* **Ant Design 的 RangePicker**(用户 2026-10-10 点名要的插件)。
* ⚠️ 只用在**起止成对**的两个端点上(见下),且**只在观影模块试点**;
@@ -73,7 +76,7 @@ $dtRange = (string)($dtRange ?? '');
所以这里不能用 `??` —— 得先看有没有这个键。 */
$dtHasLabel = array_key_exists('dtLabel', get_defined_vars());
$dtLabel = $dtHasLabel ? (string)$dtLabel : '';
$dtLabelStar = (bool)($dtLabelStar ?? false);
$dtLabelReq = (bool)($dtLabelReq ?? false);
/* 🔴 v38:插件开关(见文件头)。只在**起止成对**的场景下有意义 ——
RangePicker 天生就是"一个控件管两端",单点控件挂它反而多一个"确定"。
@@ -127,7 +130,9 @@ $dtCfg = ['name' => $dtName, 'seconds' => $dtSeconds, 'required' => $dtRequired,
而 `.dt-range.dt-cols > .field { flex: 1 1 250px }`(0,3,0)会盖过
`.dt-range > .dt-inline-lab { flex: 0 0 62px }`(0,2,0)——
实测标签被撑成 261px,把最新控件挤到右边去("不在同一行左侧"的观感)。 */ ?>
<span class="dt-inline-lab mv-lb"><?= e($dtLabel) ?><?= $dtLabelStar ? '<i>*</i>' : '' ?></span>
<?php /* 🔴 v94:必填不再画星号,改成标签自身红色加粗(`.is-req`)。
`$dtLabelReq` 参数名保持不变(调用点很多),语义已是"必填"。 */ ?>
<span class="dt-inline-lab mv-lb<?= $dtLabelReq ? ' is-req' : '' ?>"><?= e($dtLabel) ?></span>
<?php endif; ?>
<?php /* ⚠️ v44:不再套外层 `.field` —— 那会把 `.dt-input` 变成**孙子**,
于是 `> .dt-input` 那条宽泛的收起规则失效(日程"旧控件还在"就是这么来的)。
@@ -205,7 +210,7 @@ $dtCfg = ['name' => $dtName, 'seconds' => $dtSeconds, 'required' => $dtRequired,
<?php /* 用完即清,避免残留变量影响下一次 include */ unset(
$dtName, $dtValue, $dtRequired, $dtId, $dtSeconds, $dtCfg, $dtRange,
$dtDateType, $dtUseParts, $dtYearFrom, $dtYearTo, $dtPlugin, $dtUseAntd, $dtUseAntdSingle,
$dtHasLabel, $dtLabel, $dtLabelStar, $dtClass, $dtFieldId,
$dtHasLabel, $dtLabel, $dtLabelReq, $dtClass, $dtFieldId,
$dtTs, $dtTsTmp, $dtDate, $dtY, $dtMo, $dtD, $dtDays,
$dtHour, $dtMin, $dtSec,
$dtH, $dtM, $dtS, $hv, $mv, $sv, $dtYy, $dtMm, $dtDd
+1 -1
View File
@@ -70,7 +70,7 @@ $ownerSel = $isEdit && (int)($b['owner_id'] ?? 0) > 0 ? [(int)$b['owner_id']] :
<div class="form-grid">
<div class="field full">
<label for="bk-title">书名 *</label>
<label class="is-req" for="bk-title">书名</label>
<input class="input" id="bk-title" name="title" required
value="<?= e(old('title', $b['title'] ?? '')) ?>" placeholder="如:活着">
<?php if (!empty($errors['title'])): ?><span class="err"><?= e($errors['title']) ?></span><?php endif; ?>
+19 -9
View File
@@ -30,8 +30,14 @@ $evMv = !empty($evMvStyle);
否则用原来的 `.field` + `<label>`。
⚠️ 抽成闭包是为了**不在下面每处 if/else 手抄两遍结构** ——
抄两遍必然有一天两边不同步(v37 那种"改了 A 忘了 B"的坑)。
⚠️ 「必填星号」作为**参数**传(不要用 `use` 捕获 —— 闭包定义时那个变量还没赋值,
捕获到的是 null,星号永远不出现)。 */
⚠️ 「是否必填」作为**参数**传(不要用 `use` 捕获 —— 闭包定义时那个变量还没赋值,
捕获到的是 null,标记永远不出现)。
🔴🔴 v94(用户 2026-10-25):必填的表示法从「末尾加红色星号」改成
「标签本身红色加粗」,由 CSS 类 `.is-req` 驱动(样式见 `app.css` 末尾
「必填项统一标记」那段)。
⚠️ 第三个参数 v94 起从 `$star` 更名为 `$req`:它原来叫"画星",现在只表示
"这是必填" —— 名字不改会让后来者以为还在画星号,去 CSS 里找不存在的规则。 */
$evRowOpen = static function (string $full = '', bool $hidden = false) use ($evMv): string {
return '<div class="' . ($evMv ? 'mv-row' : 'field') . ($full !== '' ? ' ' . $full : '') . '"'
. ($hidden ? ' hidden' : '') . '>';
@@ -41,12 +47,14 @@ $evRowOpen = static function (string $full = '', bool $hidden = false) use ($evM
那三行排在它后面 ⇒ 拿不到。提到最前面,只算一次。 */
$evRp = \App\Repeat::parse((string)($evF['rrule'] ?? ''));
$evRepeating = (string)($evRp['freq'] ?? '') !== '';
$evLab = static function (string $text, string $for = '', bool $star = false) use ($evMv): string {
$evLab = static function (string $text, string $for = '', bool $req = false) use ($evMv): string {
$cls = $req ? ' is-req' : '';
if ($evMv) {
// 观影式:标签是 <span class="mv-lb">,冒号由 CSS ::after 给
return '<span class="mv-lb">' . $text . ($star ? '<i>*</i>' : '') . '</span>';
return '<span class="mv-lb' . $cls . '">' . $text . '</span>';
}
return '<label' . ($for !== '' ? ' for="' . e($for) . '"' : '') . '>' . $text . ($star ? ' *' : '') . '</label>';
return '<label' . ($for !== '' ? ' for="' . e($for) . '"' : '')
. ($cls !== '' ? ' class="' . trim($cls) . '"' : '') . '>' . $text . '</label>';
};
?>
<?php echo $evRowOpen('full'); ?>
@@ -160,19 +168,19 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
⚠️ 观影式:标签由 `_datetime.php` 内联(`$dtLabel`)—— 要的是与控件同行;
两列式(编辑整页):标签仍是 `.dt-range-label`,在两端之上。 */ ?>
<?php if (!$evMv): ?>
<span class="dt-range-label">日期范围 *</span>
<span class="dt-range-label is-req">日期范围</span>
<?php endif; ?>
<?php $dtName = 'starts_at'; $dtId = 'ev-start';
$dtValue = $evF['starts_at'] ?? null; $dtRequired = true;
$dtRange = 'start'; $dtPlugin = 'antd'; $dtClass = 'field ev-dt'; $dtFieldId = '';
if ($evMv) { $dtLabel = '日期范围'; $dtLabelStar = true; }
if ($evMv) { $dtLabel = '日期范围'; $dtLabelReq = true; }
require __DIR__ . '/../_datetime.php'; ?>
<?php $dtName = 'ends_at'; $dtId = 'ev-end';
$dtValue = $evF['ends_at'] ?? null; $dtRequired = false;
$dtRange = 'end'; $dtPlugin = 'antd';
$dtClass = 'field ev-dt'; $dtFieldId = 'ev-end-field';
/* 结束端点不重复标签(同一个范围控件,标签已经挂在开始那一端上) */
$dtLabel = ''; $dtLabelStar = false;
$dtLabel = ''; $dtLabelReq = false;
require __DIR__ . '/../_datetime.php'; ?>
</div><?php /* /dt-range */ ?>
<?php /* 🔴 v43(用户第 5 条):他要求把「结束留空即无明确结束」的那条提示去掉
@@ -356,5 +364,7 @@ $evLab = static function (string $text, string $for = '', bool $star = false) us
}
})();
</script>
<?php /* 🔴 v94:顺手去掉了 unset 列表里的 `$evLabelStar` —— 它在整个仓库里
**从来没有被赋过值**(只有这一行 unset 提到它),是历史遗留的死引用。 */ ?>
<?php unset($evF, $evAllDayDefault, $evIsAllDay, $evFields, $evAllDay, $evMv, $evMvStyle,
$evRowOpen, $evLab, $evLabelStar, $evRp, $evRepeating); ?>
$evRowOpen, $evLab, $evRp, $evRepeating); ?>
+3 -3
View File
@@ -95,7 +95,7 @@ $totalCount = count($allRows);
<?php endif; ?>
<div class="form-grid">
<div class="field">
<label for="cb-name">名字 *</label>
<label class="is-req" for="cb-name">名字</label>
<input class="input" id="cb-name" name="name" required
value="<?= e(old('name', $editing['name'] ?? '')) ?>" placeholder="如:体检 / 值日">
</div>
@@ -329,7 +329,7 @@ $totalCount = count($allRows);
<?= csrf_field() ?>
<div class="form-grid">
<div class="field">
<label for="im-cal">导进哪一本 *</label>
<label class="is-req" for="im-cal">导进哪一本</label>
<select class="select" id="im-cal" name="calendar_id">
<?php foreach ($cals as $c): ?>
<?php if (($c['kind'] ?? '') !== 'custom') { continue; } ?>
@@ -338,7 +338,7 @@ $totalCount = count($allRows);
</select>
</div>
<div class="field">
<label for="im-file">.ics 文件 *</label>
<label class="is-req" for="im-file">.ics 文件</label>
<?php /* 🔴 v30 用户第 1 条:$sdStage = false —— 导入型上传**不走暂存**。 */ ?>
<?php
$sdName = 'ics'; $sdId = 'im-file'; $sdAccept = '.ics,text/calendar';
+3 -3
View File
@@ -109,13 +109,13 @@ $backUrl = url('days');
<div class="mv-form-inner">
<div class="mv-grid">
<div class="mv-row">
<span class="mv-lb">叫什么<i>*</i></span>
<span class="mv-lb is-req">叫什么</span>
<input class="input" id="an-title" name="title" required
value="<?= e((string)$v('title')) ?>" placeholder="如:结婚纪念日">
</div>
<div class="mv-row">
<span class="mv-lb">按什么重复<i>*</i></span>
<span class="mv-lb is-req">按什么重复</span>
<select class="select" id="an-repeat" name="repeat_type">
<?php foreach (\App\Anniversary::REPEAT as $rk => $rv): ?>
<option value="<?= e($rk) ?>" <?= $repeat === $rk ? 'selected' : '' ?>><?= e($rv) ?></option>
@@ -144,7 +144,7 @@ $backUrl = url('days');
⚠️ `name="an_date"` 不是 `month/day` 本身 —— 它只是中间载体,
提交前脚本必把它拆好;服务端不读 an_date(days/save 读 month/day)。 */ ?>
<div class="mv-row">
<span class="mv-lb">日期<i>*</i></span>
<span class="mv-lb is-req">日期</span>
<div class="dt-input dt-antd-single" data-antd-date="1" id="an-date-wrap">
<?php /* 🔴🔴 v43(用户 2026-10-11 第 1 条):「日期那里多了一个控件,
只保留我们最新的控件就行,之前那种控件删除。」
+3 -3
View File
@@ -150,7 +150,7 @@ $ledMe = (int)($me ?? 0);
<input type="hidden" name="ledger_id" value="<?= $curId ?>">
<div class="form-grid">
<div class="field">
<label for="le-kind">类别 *</label>
<label class="is-req" for="le-kind">类别</label>
<select class="select" id="le-kind" name="kind">
<?php foreach (\App\Ledger::KINDS as $k => $v): ?>
<option value="<?= e($k) ?>"><?= e($v[2] . ' ' . $v[0]) ?><?= $v[1] === 'debt' ? '(负债)' : '' ?></option>
@@ -158,11 +158,11 @@ $ledMe = (int)($me ?? 0);
</select>
</div>
<div class="field">
<label for="le-title">名称 *</label>
<label class="is-req" for="le-title">名称</label>
<input class="input" id="le-title" name="title" required placeholder="如:工商银行定期">
</div>
<div class="field">
<label for="le-amount">金额(元)*</label>
<label class="is-req" for="le-amount">金额(元)</label>
<input class="input" id="le-amount" name="amount" required inputmode="decimal"
placeholder="如:120000.00">
<span class="tip">负债(贷款/信用卡)也填正数,系统按类别算成负债。</span>
+1 -1
View File
@@ -35,7 +35,7 @@ $canWrite = \App\Auth::canWrite();
<?php endif; ?>
<div class="form-grid">
<div class="field">
<label for="cname">影院名称 *</label>
<label class="is-req" for="cname">影院名称</label>
<input class="input" id="cname" name="name" required
value="<?= e(old('name', $editing['name'] ?? '')) ?>" placeholder="如:万达影城(IMAX 店)"
<?php /* 🔴 v47(用户 2026-10-13):「输入影院的名称的时候,应该自动的帮我补齐
+2 -2
View File
@@ -142,7 +142,7 @@ $fbAdd = !empty($fbAddModalAttr);
那一套是给普通页面表单用的,别为了弹框把它改掉。 */ ?>
<div class="mv-grid">
<div class="mv-row">
<label class="mv-lb" for="title">片名<i>*</i></label>
<label class="mv-lb is-req" for="title">片名</label>
<div class="db-title-row">
<input class="input" id="title" name="title" value="<?= e(old('title', $m['title'] ?? '')) ?>"
required autocomplete="off">
@@ -485,7 +485,7 @@ $mDelForms = []; // 收集起来,在表单**外面**统一渲染
<input class="input" name="place" placeholder="如:青岛" maxlength="100">
</div>
<div class="field">
<label>影院名称 *</label>
<label class="is-req">影院名称</label>
<?php /* 🔴 v47(用户 2026-10-13):与影院管理页同一套 —— 输入名称即联想,
选中后自动补齐「所在地方」与「详细地址」。
⚠️ 字段查找范围限定在本弹框内(`#cinemaNewForm`):
+6 -6
View File
@@ -307,12 +307,12 @@ $setItems = [
<input type="hidden" name="reuse_key" id="navReuseKey" value="">
<div class="form-grid">
<div class="field">
<label>网址 *</label>
<label class="is-req">网址</label>
<input class="input mono" name="url" id="navSiteUrl" required
value="<?= e((string)($editSite['url'] ?? '')) ?>" placeholder="https://example.com">
</div>
<div class="field">
<label>所属板块 *</label>
<label class="is-req">所属板块</label>
<select class="select" name="group_id" required>
<?php foreach ($allGroups as $g): ?>
<option value="<?= (int)$g['id'] ?>"
@@ -431,7 +431,7 @@ $setItems = [
<?php endif; ?>
<div class="form-grid">
<div class="field">
<label>板块名 *</label>
<label class="is-req">板块名</label>
<input class="input" name="name" required value="<?= e((string)($editGroup['name'] ?? '')) ?>"
placeholder="如 常用 / 工具">
</div>
@@ -497,7 +497,7 @@ $setItems = [
<?php endif; ?>
<div class="form-grid">
<div class="field">
<label>名称 *</label>
<label class="is-req">名称</label>
<input class="input" name="name" required value="<?= e((string)($editEngine['name'] ?? '')) ?>">
</div>
<div class="field">
@@ -506,13 +506,13 @@ $setItems = [
placeholder="留空自动生成">
</div>
<div class="field">
<label>搜索地址 *</label>
<label class="is-req">搜索地址</label>
<input class="input mono" name="search_url" required
value="<?= e((string)($editEngine['search_url'] ?? '')) ?>"
placeholder="https://cn.bing.com/search">
</div>
<div class="field">
<label>关键词参数 *</label>
<label class="is-req">关键词参数</label>
<input class="input mono" name="param"
value="<?= e((string)($editEngine['param'] ?? 'q')) ?>" placeholder="q">
<span class="tip">百度是 wd,搜狗是 query,多数是 q。</span>
+1 -1
View File
@@ -207,7 +207,7 @@ $fbAdd = !empty($fbAddModalAttr);
</div>
<div class="field">
<label for="name">姓名 *</label>
<label class="is-req" for="name">姓名</label>
<input class="input" id="name" name="name" value="<?= e(old('name', $person['name'] ?? '')) ?>" required>
<?php if (!empty($errors['name'])): ?><span class="err"><?= e($errors['name']) ?></span><?php endif; ?>
</div>
+1 -1
View File
@@ -37,7 +37,7 @@ $groups = $groups ?? [];
<?= csrf_field() ?>
<div class="form-grid">
<div class="field full">
<label for="imp-file">联系人文件 *</label>
<label class="is-req" for="imp-file">联系人文件</label>
<?php /* 🔴 v30:与 ics 导入同一条(用户第 1 条)—— 导入型上传**不走暂存**。
文件走 PHP 临时文件,路由读完即弃,不落存储、不建附件行。
⚠️ 不这么改的话,拖进来的文件只到暂存区、`<input>.files` 是空的,
+4 -4
View File
@@ -121,7 +121,7 @@ $myPerson = (int)\App\Auth::personId();
<div class="mv-form-inner">
<div class="mv-grid">
<div class="mv-row">
<span class="mv-lb">归属于谁<i>*</i></span>
<span class="mv-lb is-req">归属于谁</span>
<div class="mv-fill">
<?php
$ppName = 'owner_id';
@@ -136,7 +136,7 @@ $myPerson = (int)\App\Auth::personId();
</div>
</div>
<div class="mv-row">
<span class="mv-lb">标题<i>*</i></span>
<span class="mv-lb is-req">标题</span>
<input class="input" id="rs-title" name="title" required
value="<?= e($editing['title'] ?? '') ?>" placeholder="如:身份证 / 学位证">
</div>
@@ -392,7 +392,7 @@ $myPerson = (int)\App\Auth::personId();
<input type="hidden" name="id" value="">
<div class="res-pb">
<div class="field">
<label>归属于谁 *</label>
<label class="is-req">归属于谁</label>
<?php
$ppName = 'owner_id';
$ppPeople = $people;
@@ -405,7 +405,7 @@ $myPerson = (int)\App\Auth::personId();
?>
</div>
<div class="field">
<label>标题 *</label>
<label class="is-req">标题</label>
<input class="input" name="title" required>
</div>
<div class="field">
+1 -1
View File
@@ -48,7 +48,7 @@ $tkAddPeople = (array)($tkAddPeople ?? []);
控件占满剩余宽度),标题那一行在最前、其余字段依次跟上。 */ ?>
<div class="mv-grid">
<div class="mv-row">
<span class="mv-lb">任务名称<i>*</i></span>
<span class="mv-lb is-req">任务名称</span>
<input class="input" id="tk-title" name="title" required
placeholder="如:周末大扫除">
</div>
+1 -1
View File
@@ -68,7 +68,7 @@ $tkEmbed = !empty($tkEditEmbed);
同一件事在两个入口长得不一样,用户会以为"进了别的页面"。 */ ?>
<div class="mv-grid">
<div class="mv-row">
<span class="mv-lb">任务名称<i>*</i></span>
<span class="mv-lb is-req">任务名称</span>
<input class="input" id="tk-title" name="title" required value="<?= e((string)($tkT['title'] ?? '')) ?>">
</div>
<div class="mv-row">
+1 -1
View File
@@ -109,7 +109,7 @@ $tpShell = !isset($tpShell) ? !$tpEmbed : (bool)$tpShell;
<div class="mv-grid">
<?php /* ==================== ① 标题(左标签 + 右输入框,观影同款)==================== */ ?>
<div class="mv-row">
<span class="mv-lb">旅程名<i>*</i></span>
<span class="mv-lb is-req">旅程名</span>
<input class="input" id="t-title" name="title" required autofocus
value="<?= e(old('title', $t['title'] ?? '')) ?>" placeholder="如:青岛之行 · 2026 暑假">
<?php if (!empty($errors['title'])): ?><span class="err"><?= e($errors['title']) ?></span><?php endif; ?>
+2 -2
View File
@@ -156,7 +156,7 @@ $nfEmbed = !empty($nfEmbed);
<div class="form-grid">
<?php /* ---- 类型(TripLog 的第一个字段;第 17 批 第 2 条已补齐到 8 种)---- */ ?>
<div class="field">
<label for="nf-type">类型 *</label>
<label class="is-req" for="nf-type">类型</label>
<select class="select" id="nf-type" name="node_type">
<?php foreach ($types as $t): ?>
<?php $tn = (string)$t['name']; ?>
@@ -181,7 +181,7 @@ $nfEmbed = !empty($nfEmbed);
<?php /* ---- 标题 ---- */ ?>
<div class="field full">
<label for="nf-title">标题 *</label>
<label class="is-req" for="nf-title">标题</label>
<input class="input" id="nf-title" name="title" required
value="<?= e(old('title', $n['title'] ?? '')) ?>" placeholder="例如:出发去栈桥">
<?php if (!empty($errors['title'])): ?><span class="err"><?= e($errors['title']) ?></span><?php endif; ?>