Skip to content

Commit

Permalink
Merge pull request #929 from carstingaxion/feature/fragment-of-pr-831…
Browse files Browse the repository at this point in the history
…-endpoint-docs

new calendar endpoints | part 3/4 | endpoint docs
  • Loading branch information
mauteri authored Oct 22, 2024
2 parents e220c58 + cfef33b commit 2b29e2e
Show file tree
Hide file tree
Showing 3 changed files with 291 additions and 0 deletions.
226 changes: 226 additions & 0 deletions docs/developer/custom-url-endpoints/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# Custom URL Endpoints

GatherPress provides some different and custom URL endpoints, for example `/ical` and `/feed/ical`.

**Existing custom endpoints:**

- `example.org/event/my-sample-event/ical`

provides a download-able .ics file in ical format.

- `example.org/event/my-sample-event/outlook`

provides the same download-able file as an alias.

- `example.org/event/my-sample-event/google-calendar`

redirects to create a new event in *Google Calendar*.

- `example.org/event/my-sample-event/yahoo-calendar`

redirects to create a new event in *Yahoo Calendar*.

- `example.org/event/feed/ical`

provides a subscribe-able event feed in ical format with all events of the site.

- `example.org/venue/my-sample-venue/feed/ical`

provides a subscribe-able event feed in ical format with all events at that venue.

- `example.org/topic/my-sample-topic/feed/ical`

provides a subscribe-able event feed in ical format with all events grouped into that topic.

The most obvious functions to create such within WordPress seem to be [`add_feed()`](https://developer.wordpress.org/reference/functions/add_feed/) and [`add_rewrite_endpoint()`](https://developer.wordpress.org/reference/functions/add_rewrite_endpoint/) for this purpose.

Unfortunately both functions share a common pitfall, they are not restricitive to any post type at all. That would result in having a `/feed/ical` endpoint for all posts AND every other non-hierarchical, custom post type which seemed to be the wrong way to go. A lot of code would have had to be written, to patch this behavior and remove those superfluous endpoints.

That's why GatherPress created its own Endpoint ~~API~~ helper and tries to fix the mentioned problems before they appear.

## GatherPress' own Endpoint API

In opposite to the former mentioned WordPress core functions GatherPress Endpoint API is flexible enough to not *only* provide endpoints for GatherPress. You can utilize its classes to create a plenty of different endpoints for your post types and taxonomies as well.

In general, one endpoint can be created ...

- for individual posts
- for post type archives
- for taxonomy archives

It can be either ...

- a redirect

*or*

- a template to load


### Setup new endpoints

To create a new endpoint you will want to create a new instance of the *pure* [`Endpoint()`](https://github.com/GatherPress/gatherpress/tree/main/includes/core/classes/endpoints/class-endpoint.php) class or one of its sub-classes:

- [`Posttype_Single_Endpoint()`](https://github.com/GatherPress/gatherpress/tree/main/includes/core/classes/endpoints/class-posttype-single-endpoint.php)

for endpoints like `example.org/cpt/my-custom-post-type/new-endpoint`

- [`Posttype_Single_Feed_Endpoint()`](https://github.com/GatherPress/gatherpress/tree/main/includes/core/classes/endpoints/class-posttype-single-feed-endpoint.php)

for endpoints like `example.org/cpt/my-custom-post-type/feed/new-endpoint`

- [`Posttype_Feed_Endpoint()`](https://github.com/GatherPress/gatherpress/tree/main/includes/core/classes/endpoints/class-posttype-feed-endpoint.php)

for endpoints like `example.org/cpt/feed/new-endpoint`

- [`Taxonomy_Feed_Endpoint()`](https://github.com/GatherPress/gatherpress/tree/main/includes/core/classes/endpoints/class-taxonomy-feed-endpoint.php)

for endpoints like `example.org/ctax/feed/new-endpoint`

These classes help to select *where* an endpoint should run.

To become properly callable as URL, the endpoints needs to know *what* to do when some URL is requested. Therefore each `Endpoint()` needs to have at least one of either:

- [`Endpoint_Redirect()`](https://github.com/GatherPress/gatherpress/tree/main/includes/core/classes/endpoints/class-endpoint-redirect.php)

*or*

- [`Endpoint_Template()`](https://github.com/GatherPress/gatherpress/tree/main/includes/core/classes/endpoints/class-endpoint-template.php)

## Example 1 | Add events to *Office365 Calendar*

Example for a new redirection endpoint like `example.org/event/my-sample-event/office365-calendar`

- ### 1. Setup a new endpoint

Let's create an endpoint to immediately add an event to a *Office365 Calendar*, similar to the existing for *Google* and *Yahoo*.

![Screenshot from the 'Rewrite Analyzer' plugin page with a matching rewrite for office365-endpoint from this example.](./custom-url-endpoints__office365-calendar.png)

To set up a new endpoint for single events, use the [`Posttype_Single_Endpoint()`](https://github.com/GatherPress/gatherpress/tree/main/includes/core/classes/endpoints/class-posttype-single-endpoint.php) class.

```php
use GatherPress\Core\Endpoints\Posttype_Single_Endpoint;
use GatherPress\Core\Endpoints\Endpoint_Redirect;
```

```php
new Posttype_Single_Endpoint(
array(
new Endpoint_Redirect(
'office365-calendar',
array( $this, 'get_office365_calendar_link' )
),
),
'gatherpress_awesome_calendar',
);
```

> [!TIP]
> Run this on the `registered_post_type_{post_type}` action, to ensure that custom endpoints are registered after their post type is initialized. GatherPress will trigger php warnings if called too early or or with unsupported arguments.

- ### 2. Define the callback for the endpoint

```php
use GatherPress\Core\Event;
```

```php

/**
* Returns the office365 calendar URL for the current event.
*
* This method generates the appropriate URL for Office 365 Calendar.
* It uses the `Event` class to retrieve the necessary data for the event.
*
* @since 1.0.0
*
* @return string The URL to redirect the user to the appropriate calendar service.
*/
public function get_office365_calendar_link(): string {

$event = new Event( get_queried_object_id() );
$date_start = $event->get_formatted_datetime( 'Ymd', 'start', false );
$time_start = $event->get_formatted_datetime( 'His', 'start', false );
$date_end = $event->get_formatted_datetime( 'Ymd', 'end', false );
$time_end = $event->get_formatted_datetime( 'His', 'end', false );
// Format the start and end datetime in the required format
$startdt = sprintf('%sT%sZ', $date_start, $time_start);
$enddt = sprintf('%sT%sZ', $date_end, $time_end);
$venue = $event->get_venue_information();
$location = $venue['name'];
$description = $event->get_calendar_description();

if ( ! empty( $venue['full_address'] ) ) {
$location .= sprintf( ', %s', $venue['full_address'] );
}

$params = array(
'subject' => sanitize_text_field( $event->event->post_title ),
'body' => sanitize_text_field( $description ),
'startdt' => $startdt,
'enddt' => $enddt,
'location' => sanitize_text_field( $location ),
'path' => '/calendar/action/compose',
'rru' => 'addevent',
);

return add_query_arg(
rawurlencode_deep( $params ),
'https://outlook.office.com/calendar/0/deeplink/compose'
);
}
```

- ### 3. Use & retrieve the endpoint

To use the newly created endpoints, you can use `Endpoints::get_url()` and rely on the used WordPress core functions internally:

```php
use GatherPress\Core\Endpoints;
```

```php
Endpoints::get_url(
'office365-calendar'
get_queried_object_id(),
'gatherpress_awesome_calendar',
);
```




## Resources

- Full, working code from all examples as part of **GatherPress Awesome**.

Within [your GatherPress Awesome plugin](https://github.com/GatherPress/gatherpress-awesome), just enable it in `gatherpress-awesome/includes/classes/class-setup.php`

```php
// ENABLE or DISABLE
// Test adding some awesome endpoints!
// Awesome_Endpoints::get_instance(); // <-- Un-Comment to ENABLE
```

```php
// ENABLED
// Test adding some awesome endpoints!
Awesome_Endpoints::get_instance(); // <-- :tada:
```

### Testing & Validating

- [iCalendar Validator](https://icalendar.org/validator.html)
- [Monkeyman Rewrite Analyzer – WordPress plugin | WordPress.org](https://wordpress.org/plugins/monkeyman-rewrite-analyzer/)

### used & related from WordPress

-

#### *explicitly not used*, but related from WordPress

- [`add_feed()`](https://developer.wordpress.org/reference/functions/add_feed/)
- [`add_rewrite_endpoint()`](https://developer.wordpress.org/reference/functions/add_rewrite_endpoint/)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions docs/developer/theme-customizations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Theme customizations

1. [Template overrides](#template-overrides)
2. [Theme supports](#theme-supports)

## Template overrides

GatherPress provides different ways to customize its output via theme files. Some of this customization opportunities come from GatherPress, but the most are just pure WordPress. A site could provide one or more of the following templates from one of:

- a child theme’s `/templates` folder (if child theme is active).
- the theme’s `/templates` folder.

### Default template overrides

Following the [default WordPress template hierarchy](https://developer.wordpress.org/themes/templates/template-hierarchy).

#### Events

- `archive-gatherpress_event.(html|php)`
- `single-gatherpress_event.(html|php)`
- `single-gatherpress_event-{post_name}.(html|php)`
- `embed-gatherpress_event.php`

Due to [a known issue](https://developer.wordpress.org/themes/templates/template-hierarchy/#embed-hierarchy) embed templates can only be created as `.php` files.

#### Venues

- `single-gatherpress_venue.(html|php)`
- `single-gatherpress_venue-{post_name}.(html|php)`
- `embed-gatherpress_venue.php`

#### Topics

- `taxonomy-gatherpress_topic.(html|php)`
- `taxonomy-gatherpress_topic-{term_slug}.(html|php)`

### Overriding plugin template

In addition to the default theme files, a theme author could add the following templates to override special templates, normally provided by the GatherPress plugin:

- `gatherpress_ical-download.php`
- `gatherpress_ical-feed.php`

## Theme supports

GatherPress does respect [theme_supports](https://developer.wordpress.org/reference/functions/current_theme_supports/) definitions and will output the following pieces only if the current theme supports it.

- When **`automatic-feed-links`** are supported, GatherPress will add `rel="alternate"` links to the `<head>` of each view, with the URLs to the relevant iCal feed links. This will be:

- For all requests (`example.org/*`):
- `example.org/event/feed/ical`

- For singular event requests (`example.org/event/my-sample-event`):
- `example.org/event/feed/ical`
- `example.org/event/my-sample-event/ical`
- `example.org/venue/my-sample-venue/feed/ical` (if its not an Online-Event)
- `example.org/topic/my-sample-topic/feed/ical` (if a topic is selected)

- For singular venue requests (`example.org/venue/my-sample-venue`):
- `example.org/event/feed/ical`
- `example.org/venue/my-sample-venue/feed/ical`

- For topic term requests (`example.org/topic/my-sample-topic`):
- `example.org/event/feed/ical`
- `example.org/topic/my-sample-topic/feed/ical`

0 comments on commit 2b29e2e

Please sign in to comment.