PHPackages                             craftpulse/craft-timeloop - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. craftpulse/craft-timeloop

ActiveCraft-plugin[Utility &amp; Helpers](/categories/utility)

craftpulse/craft-timeloop
=========================

This Craft plugin will generate an array of dates between a start and end date based on frequency.

4.1.1(3y ago)6261[5 PRs](https://github.com/craftpulse/craft-timeloop/pulls)proprietaryPHPPHP ^8.0.2CI passing

Since Apr 22Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/craftpulse/craft-timeloop)[ Packagist](https://packagist.org/packages/craftpulse/craft-timeloop)[ RSS](/packages/craftpulse-craft-timeloop/feed)WikiDiscussions v5-develop Synced 1mo ago

READMEChangelog (10)Dependencies (5)Versions (34)Used By (0)

Timeloop plugin for Craft CMS 5.x
=================================

[](#timeloop-plugin-for-craft-cms-5x)

The timeloop plugin creates repeating dates without the need of complex inputs.

[![Screenshot](./resources/img/timeloop-banner.jpg)](./resources/img/timeloop-banner.jpg)

Requirements
------------

[](#requirements)

This plugin requires Craft CMS 5.0.0 or later.

Teamleader Plugin for Craft CMS 5.x
===================================

[](#teamleader-plugin-for-craft-cms-5x)

Seamlessly integrate **Teamleader Focus** with **Craft CMS** and **Formie forms** to manage contacts, companies, and deals efficiently.

Installation
------------

[](#installation)

### Standard Craft CMS Installation

[](#standard-craft-cms-installation)

1. Open your terminal and navigate to your Craft project: ```
    cd /path/to/project
    ```
2. Install the plugin via Composer: ```
    composer require craftpulse/craft-timeloop
    ```
3. Install the plugin: ```
    craft plugin/install timeloop
    ```

    Alternatively, activate it via **Settings → Plugins** in the Craft Control Panel.

### Installing on DDEV

[](#installing-on-ddev)

1. Install the Teamleader plugin: ```
    ddev composer require craftpulse/craft-timeloop
    ```
2. Install the plugin in Craft CMS: ```
    ddev craft plugin/install timeloop
    ```

---

3. In the Control Panel, go to Settings → Plugins and click the “Install” button.

Timeloop Overview
-----------------

[](#timeloop-overview)

The Timeloop plugin provides recurring dates based on a starting date and a regular loop period.

**Example**: Set a payment date for employees on the first of each month.

Configuring the Timeloop field.
-------------------------------

[](#configuring-the-timeloop-field)

The following configuration options that are available for the field:

- **ShowTimes**: When selected, this will give the ability to choose a starting time and end time for the recurring dates.

Using Timeloop
--------------

[](#using-timeloop)

### The Timeloop Model

[](#the-timeloop-model)

#### Getting the entered dates (returned as DateTime objects)

[](#getting-the-entered-dates-returned-as-datetime-objects)

Getting the start date for the loop (this includes the time set in `loopStartTime`):

```
    {{ entry.timeloop.loopStartDate | date('Y-m-d\\TH:i:sP') }}

```

Getting the end date for the loop (this includes the time set in `loopEndHour`):

```
    {{ entry.timeloop.loopEndDate | date('Y-m-d\\TH:i:sP') }}

```

Getting the start time for the loop:

```
    {{ entry.timeloop.loopStartTime | date('H:i:s') }}

```

Getting the end time for the loop:

```
    {{ entry.timeloop.loopEndTime | date('H:i:s') }}

```

Getting an array of dates between the selected start and end dates (Array with DateTime Objects):

```
    {% for date in entry.timeloop.dates %}
        {{ date | date('Y-m-d\\TH:i:sP') }}
    {% endfor %}

```

This generated set of dates takes all the field values into consideration (frequency, cycle and custom)

#### Upcoming Dates (returned as DateTime Objects)

[](#upcoming-dates-returned-as-datetime-objects)

Getting the first upcoming date:

```
    {{ entry.timeloop.upcoming | date('Y-m-d\\TH:i:sP') }}

```

Getting the next upcoming date:

```
    {{ entry.timeloop.nextUpcoming | date('Y-m-d\\TH:i:sP') }}

```

#### Get entries between certain dates

[](#get-entries-between-certain-dates)

If you want to fetch entries from a certain section between two dates. You can fetch them by giving the ElementsQuery with the name of the timeloop field, start and end date. This will return you an array of recurring dates per entry between this period. If no dates are defined, you will get an empty array. In the returned array, you can find the entry id, entry title and the dates.

```
    {%- set recurringEntries = recurringDates(craft.entries.section('events'), 'timeloop', '2021-01-01', '2022-02-01')  %}
    {% for recurringEntry in recurringEntries %}

            {{ recurringEntry.entryTitle }}: {{ recurringEntry.entryId }}
            {% for date in recurringEntry.dates %}
                {{ date | date('d/m/y H:i') }}
            {% endfor %}

    {% endfor %}

```

Returns this array layout

```
0 => [
    'entryId' => 1111
    'entryTitle' => 'Event title'
    'dates' => [
        0 => DateTime#1
        (
            [date] => '2022-01-01 00:00:00.000000'
            [timezone_type] => 3
            [timezone] => 'Europe/London'
        )
        1 => DateTime#2
        (
            [date] => '2022-01-08 00:00:00.000000'
            [timezone_type] => 3
            [timezone] => 'Europe/London'
        )
    ]
]

```

### Period Model

[](#period-model)

Getting the frequency (DateTimePeriod String):

```
    {{ entry.timeloop.period.frequency }}

```

Getting the cycle (Integer):

```
    {{ entry.timeloop.period.cycle }}

```

Displaying the selected days (Array):

```
    {% for day in entry.timeloop.period.days %}
        {{ day }}
    {% endfor %}

```

This will parse the names of the selected days when weekly has been chosen as frequency.

### Timestring Model

[](#timestring-model)

Get the ordinal of a monthly set loop (e.g. first, second, ..., last)

**warning:** If the frequency is not set to monthly, the returned value will be `null`.
**warning:** If the frequency is set to monthly and no timestring selection has been made, the returned value will be `none` as `String`.

```
    {{ entry.timeloop.timestring.ordinal ?? 'not set' }}

```

### Reminder Model (WIP - not ready for production)

[](#reminder-model-wip---not-ready-for-production)

### GraphQL

[](#graphql)

If you want to use the plugin through GraphQL, we've added a GraphQL Type to provide the field data.

You can get the DateTime Types from the data directly for

- `loopStartDate` will return the start date
- `loopStartTime` will return the start time, defaults to `00:00:00` when no start time has been entered or `showTimes` is set to false.
- `loopEndDate` will return the end date
- `loopEndTime` will return the end time, defaults to `23:59:59` when no end time has been entered or `showTimes` is set to false.
- `loopReminder`

#### Loop Period

[](#loop-period)

You can get the `loopPeriod` object as follows:

```
    loopPeriod {
        frequency
        cycle
        days
        timestring {
          ordinal
          day
        }
    }

```

- `frequency` will return the selected frequency ( P1D / P1W / P1M / P1Y )
- `cycle` will return the entered cycle value
- `days` will return an Array that contains the selected days of the week
- `timestring` will return an object that contains the `ordinal` (e.g. last) and `day` (e.g. saturday)

#### The Dates

[](#the-dates)

To get an array of formatted dates, use `dates`.

##### Dates arguments:

[](#dates-arguments)

- limit (Integer): add a limit of dates you want to return, default to `100`.
- futureDates (Boolean): if you want to show future dates only, default to `true`.

##### Dates directives:

[](#dates-directives)

`formatDateTime(timezone: "Europe/London" format: "d/m/Y")`

```
query{
  entries(section: "homepage"){
    id,
    ...on homepage_homepage_Entry{
      dateCreated,
      title,
      timeloop {
        loopReminder,
        loopStartDate,
        loopStartTime,
        loopEndDate,
        loopEndTime,
        loopPeriod,
        dates(limit: 5) @formatDateTime(format: "d/m/Y" )
      }
    }
  }
}
```

Timeloop Roadmap
----------------

[](#timeloop-roadmap)

Potential features for the future:

- Reminder Support
- Make the fieldtype translatable
- Provide language translations
- Add the possibility to blocklist dates
- Add holiday settings
- Localise holidays based on the CraftCMS timezone settings

And many more!

Brought to you by [CraftPulse](https://craft-pulse.com)

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance57

Moderate activity, may be stable

Popularity15

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 85.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~67 days

Recently: every ~184 days

Total

22

Last Release

424d ago

Major Versions

0.1.0 → 1.0.0-rc2021-05-06

v1.x-dev → 4.0.0-beta.12022-05-02

v4.x-dev → 5.0.0-beta.22025-03-12

PHP version history (2 changes)4.0.0-beta.1PHP ^8.0.2

5.0.0-beta.2PHP ^8.2.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/5cc936921e382ceab892ad03aa12acc365be0992e066c72b37004995847ca31e?d=identicon)[craftpulse](/maintainers/craftpulse)

---

Top Contributors

[![michtio](https://avatars.githubusercontent.com/u/5818021?v=4)](https://github.com/michtio "michtio (134 commits)")[![cookie10codes](https://avatars.githubusercontent.com/u/20947573?v=4)](https://github.com/cookie10codes "cookie10codes (20 commits)")[![EmilyRackliffe](https://avatars.githubusercontent.com/u/47784491?v=4)](https://github.com/EmilyRackliffe "EmilyRackliffe (2 commits)")

---

Tags

cmsCraftcraftcmscraft-plugintimeloop

###  Code Quality

TestsCodeception

### Embed Badge

![Health badge](/badges/craftpulse-craft-timeloop/health.svg)

```
[![Health](https://phpackages.com/badges/craftpulse-craft-timeloop/health.svg)](https://phpackages.com/packages/craftpulse-craft-timeloop)
```

###  Alternatives

[verbb/formie

The most user-friendly forms plugin for Craft.

101372.9k40](/packages/verbb-formie)[verbb/navigation

Create navigation menus for your site.

90683.7k17](/packages/verbb-navigation)[verbb/vizy

A flexible visual editor field for Craft.

4348.6k](/packages/verbb-vizy)[verbb/hyper

A user-friendly links field for Craft.

24130.9k9](/packages/verbb-hyper)[verbb/icon-picker

A slick field to pick icons from. Supports SVGs, Sprites, Webfonts, Font Awesome and more.

16162.4k4](/packages/verbb-icon-picker)[verbb/comments

Add comments to your site.

13753.1k](/packages/verbb-comments)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
