如何通过JavaScript修改TYPO3 session variable,在listAction中筛选日历记录?
解决方案:通过AJAX间接修改TYPO3 Session变量来控制日历记录显示
首先明确:你不能直接在客户端JavaScript里修改TYPO3的服务器端Session变量,因为Session数据存储在服务器(或对应存储介质),JS只能通过发送请求到服务器端接口来间接操作。不过实现你要的功能完全可行,下面是具体步骤:
1. 新增TYPO3控制器动作用于设置Session变量
在你的扩展控制器里添加一个专门处理Session设置的动作,比如setCalendarFilterAction,它负责接收前端传来的过滤参数,并写入FE用户的Session:
public function setCalendarFilterAction() { // 接收前端传来的过滤参数(比如要隐藏的记录类型、时间范围标识等) $filterParam = $this->request->getArgument('filter'); // 将参数存入FE用户Session,'calendar_filter'是自定义的Session键名 $GLOBALS['TSFE']->fe_user->setKey('ses', 'calendar_filter', $filterParam); // 保存Session变更 $GLOBALS['TSFE']->fe_user->storeSessionData(); // 返回JSON响应告知前端操作成功 $this->jsonResponse(['status' => 'success']); }
别忘了在扩展的ext_localconf.php里注册这个路由(如果用TYPO3 11+的Site Configuration,也可以在站点路由配置里添加对应规则)。
2. 在JavaScript中通过AJAX调用这个动作
当用户在日历上触发需要修改过滤规则的操作时,用AJAX发送请求到刚才的控制器动作,传递过滤参数。注意必须带上TYPO3的CSRF令牌,避免请求被拦截:
// 从页面获取TYPO3的CSRF令牌(通常会渲染在页面的全局变量或meta标签里) const csrfToken = document.querySelector('meta[name="csrf-token"]').content; // 定义要设置的过滤参数(比如要隐藏的记录ID集合、过滤类型等) const filterData = { filter: 'hide_past_events' // 示例参数,根据你的需求自定义 }; // 发送POST请求到控制器动作 fetch('/index.php?eID=your_extension&action=setCalendarFilter', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-TYPO3-CSRF-Token': csrfToken }, body: JSON.stringify(filterData) }) .then(response => response.json()) .then(data => { if (data.status === 'success') { // 成功后可以重新调用listAction获取更新后的日历数据 fetchCalendarData(); } });
3. 在listAction中读取Session变量并处理记录
现在在你的listAction里,读取之前存入Session的过滤参数,用它来调整查询条件,筛选需要返回的记录:
public function listAction() { // 读取Session中的过滤参数 $filter = $GLOBALS['TSFE']->fe_user->getKey('ses', 'calendar_filter'); // 构建查询,根据filter值添加过滤条件 $query = $this->calendarRepository->createQuery(); if ($filter === 'hide_past_events') { // 比如隐藏过去的事件,添加时间大于当前的条件 $query->matching( $query->greaterThan('startTime', time()) ); } // 其他过滤逻辑... $calendarRecords = $query->execute(); // 将记录转为JSON返回给JS $this->jsonResponse($calendarRecords); }
可选替代方案:直接传递参数(无需Session)
如果不需要在多个请求之间持久化过滤状态,其实可以跳过Session,直接在调用listAction时把过滤参数作为URL参数或POST数据传递,这样更简单:
// 调用listAction时直接带参数 fetch('/index.php?eID=your_extension&action=list&filter=hide_past_events', { headers: { 'X-TYPO3-CSRF-Token': csrfToken } }) .then(response => response.json()) .then(data => { // 更新日历显示 });
然后在listAction里直接获取参数:
$filter = $this->request->getArgument('filter');
这种方式适合临时过滤,不需要记住用户的选择;如果需要用户的过滤偏好在页面刷新后依然保留,那用Session的方式更合适。
内容的提问来源于stack exchange,提问作者Mondblut
相关产品推荐
相关产品推荐

