You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Apostrophe的trainings-forms中从谷歌日历填充日期字段?

解决Apostrophe表单日期字段从谷歌日历动态填充的问题

我之前在Apostrophe CMS里处理过类似的动态表单字段需求,给你一步步拆解怎么实现:

第一步:在pageBeforeSend中获取并传递日历数据

你已经在trainings-forms-submit-widgets的pageBeforeSend里写了获取谷歌日历数据的代码,接下来要把这些数据绑定到对应的trainings-forms widget上。Apostrophe提供了self.apos.util.walk工具方法,可以遍历页面中的所有widget,找到目标表单后挂载数据:

module.exports = {
  construct: function(self, options) {
    self.pageBeforeSend = async function(req) {
      // --- 这里放你获取谷歌日历数据的异步代码 ---
      const { google } = require('googleapis');
      const calendar = google.calendar({ version: 'v3', auth: '你的授权凭证' });
      const calendarResponse = await calendar.events.list({
        calendarId: '你的谷歌日历ID',
        timeMin: new Date().toISOString(),
        maxResults: 10,
        singleEvents: true,
        orderBy: 'startTime',
      });
      // 提取出需要的日期格式,比如转为YYYY-MM-DD或者带时间的格式
      const availableDates = calendarResponse.data.items.map(event => {
        return event.start.dateTime || event.start.date;
      });

      // --- 找到trainings-forms widget并传递数据 ---
      if (req.data.page) {
        // 遍历页面所有widget,定位到trainings-forms类型的表单
        self.apos.util.walk(req.data.page, (widget) => {
          if (widget.type === 'trainings-forms') {
            // 把日历数据挂载到widget的自定义属性上,模板里就能直接用
            widget.availableTrainingDates = availableDates;
          }
        });
      }
    };
  }
};

第二步:在表单模板中渲染填充数据

接下来修改trainings-forms widget的模板文件(路径一般是lib/modules/trainings-forms/views/widget.html),根据你的日期字段类型(下拉框/输入框)来渲染数据:

示例1:下拉选择框

<div class="form-group">
  <label for="training-date">选择培训日期</label>
  <select id="training-date" name="training-date" required>
    {% for date in widget.availableTrainingDates %}
      <option value="{{ date }}">{{ date | date('YYYY-MM-DD HH:mm') }}</option>
    {% endfor %}
  </select>
</div>

示例2:日期输入框(默认填充第一个可用日期)

<div class="form-group">
  <label for="training-date">培训日期</label>
  <input 
    type="datetime-local" 
    id="training-date" 
    name="training-date" 
    value="{{ widget.availableTrainingDates[0] | date('YYYY-MM-DDTHH:mm') }}"
    required
  >
</div>

关键注意点

  • 因为谷歌日历API调用是异步操作,一定要用async/await包裹,确保数据获取完成后再传递给widget,避免出现空数据的情况。
  • self.apos.util.walk会遍历页面中所有区域(areas)里的widget,不管表单放在哪个区域都能定位到。
  • 如果你的表单有多个实例,这个方法会给所有trainings-forms widget都填充数据,要是需要针对特定实例,可以给widget加个自定义属性(比如widget.slug)来筛选。

内容的提问来源于stack exchange,提问作者Michał Sadowski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:59:09