Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • adaures/castopod
  • mkljczk/castopod-host
  • spaetz/castopod-host
  • PatrykMis/castopod
  • jonas/castopod
  • ajeremias/castopod
  • misuzu/castopod
  • KrzysztofDomanczyk/castopod
  • Behel/castopod
  • nebulon/castopod
  • ewen/castopod
  • NeoluxConsulting/castopod
  • nateritter/castopod-og
  • prcutler/castopod
14 results
Select Git revision
Show changes
Showing
with 1658 additions and 42 deletions
---
title: Official Docker images
---
Castopod pushes 3 Docker images to the Docker Hub during its automated build
process:
- [**`castopod/castopod`**](https://hub.docker.com/r/castopod/castopod): an all
in one castopod image using nginx unit
- [**`castopod/app`**](https://hub.docker.com/r/castopod/app): the app bundle
with all of Castopod dependencies
- [**`castopod/web-server`**](https://hub.docker.com/r/castopod/web-server): an
Nginx configuration for Castopod
Additionally, Castopod requires a MySQL-compatible database. A Redis database
can be added as a cache handler.
## Supported tags
- `develop` [unstable], latest development branch build
- `beta` [stable], latest beta version build
- `latest` [stable], latest version build
- `1.x.x` [stable], specific version build (since `1.0.0`)
## Example usage
1. Install [docker](https://docs.docker.com/get-docker/) and
[docker-compose](https://docs.docker.com/compose/install/)
2. Create a `docker-compose.yml` file with the following:
```yml
version: "3.7"
services:
castopod:
image: castopod/castopod:latest
container_name: "castopod"
volumes:
- castopod-media:/var/www/castopod/public/media
environment:
MYSQL_DATABASE: castopod
MYSQL_USER: castopod
MYSQL_PASSWORD: changeme
CP_BASEURL: "https://castopod.example.com"
CP_ANALYTICS_SALT: changeme
CP_CACHE_HANDLER: redis
CP_REDIS_HOST: redis
CP_REDIS_PASSWORD: changeme
networks:
- castopod
- castopod-db
ports:
- 8000:8000
restart: unless-stopped
mariadb:
image: mariadb:11.2
container_name: "castopod-mariadb"
networks:
- castopod-db
volumes:
- castopod-db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: changeme
MYSQL_DATABASE: castopod
MYSQL_USER: castopod
MYSQL_PASSWORD: changeme
restart: unless-stopped
redis:
image: redis:7.2-alpine
container_name: "castopod-redis"
command: --requirepass changeme
volumes:
- castopod-cache:/data
networks:
- castopod
volumes:
castopod-media:
castopod-db:
castopod-cache:
networks:
castopod:
castopod-db:
```
You have to adapt some variables to your needs (e.g. `CP_BASEURL`,
`MYSQL_ROOT_PASSWORD`, `MYSQL_PASSWORD` and `CP_ANALYTICS_SALT`).
3. Setup a reverse proxy for TLS (SSL/HTTPS)
TLS is mandatory for ActivityPub to work. This job can easily be handled by
a reverse proxy, for example with [Caddy](https://caddyserver.com/):
```
#castopod
castopod.example.com {
reverse_proxy localhost:8000
}
```
4. Run `docker-compose up -d`, wait for it to initialize and head on to
`https://castopod.example.com/cp-install` to finish setting up Castopod!
5. You're all set, start podcasting! 🎙️🚀
## Environment Variables
- **castopod/castopod** and **castopod/app**
| Variable name | Type (`default`) | Default |
| ------------------------------------- | ----------------------- | ---------------- |
| **`CP_BASEURL`** | string | `undefined` |
| **`CP_MEDIA_BASEURL`** | ?string | `CP_BASEURL` |
| **`CP_ADMIN_GATEWAY`** | ?string | `"cp-admin"` |
| **`CP_AUTH_GATEWAY`** | ?string | `"cp-auth"` |
| **`CP_ANALYTICS_SALT`** | string | `undefined` |
| **`CP_DATABASE_HOSTNAME`** | ?string | `"mariadb"` |
| **`CP_DATABASE_NAME`** | ?string | `MYSQL_DATABASE` |
| **`CP_DATABASE_USERNAME`** | ?string | `MYSQL_USER` |
| **`CP_DATABASE_PASSWORD`** | ?string | `MYSQL_PASSWORD` |
| **`CP_DATABASE_PREFIX`** | ?string | `"cp_"` |
| **`CP_CACHE_HANDLER`** | [`"file"` or `"redis"`] | `"file"` |
| **`CP_REDIS_HOST`** | ?string | `"localhost"` |
| **`CP_REDIS_PASSWORD`** | ?string | `null` |
| **`CP_REDIS_PORT`** | ?number | `6379` |
| **`CP_REDIS_DATABASE`** | ?number | `0` |
| **`CP_EMAIL_SMTP_HOST`** | ?string | `undefined` |
| **`CP_EMAIL_FROM`** | ?string | `undefined` |
| **`CP_EMAIL_SMTP_USERNAME`** | ?string | `"localhost"` |
| **`CP_EMAIL_SMTP_PASSWORD`** | ?string | `null` |
| **`CP_EMAIL_SMTP_PORT`** | ?number | `25` |
| **`CP_EMAIL_SMTP_CRYPTO`** | [`"tls"` or `"ssl"`] | `"tls"` |
| **`CP_ENABLE_2FA`** | ?boolean | `undefined` |
| **`CP_MEDIA_FILE_MANAGER`** | ?string | `undefined` |
| **`CP_MEDIA_S3_ENDPOINT`** | ?string | `undefined` |
| **`CP_MEDIA_S3_KEY`** | ?string | `undefined` |
| **`CP_MEDIA_S3_SECRET`** | ?string | `undefined` |
| **`CP_MEDIA_S3_REGION`** | ?string | `undefined` |
| **`CP_MEDIA_S3_BUCKET`** | ?string | `undefined` |
| **`CP_MEDIA_S3_PROTOCOL`** | ?number | `undefined` |
| **`CP_MEDIA_S3_PATH_STYLE_ENDPOINT`** | ?boolean | `undefined` |
| **`CP_MEDIA_S3_KEY_PREFIX`** | ?string | `undefined` |
| **`CP_DISABLE_HTTPS`** | ?[`0` or `1`] | `undefined` |
| **`CP_MAX_BODY_SIZE`** | ?number (with suffix) | `512M` |
| **`CP_PHP_MEMORY_LIMIT`** | ?number (with suffix) | `512M` |
| **`CP_TIMEOUT`** | ?number | `900` |
- **castopod/web-server**
| Variable name | Type | Default |
| ---------------------- | --------------------- | ------- |
| **`CP_APP_HOSTNAME`** | ?string | `"app"` |
| **`CP_MAX_BODY_SIZE`** | ?number (with suffix) | `512M` |
| **`CP_TIMEOUT`** | ?number | `900` |
---
title: Installation
sidebarDepth: 3
title: How to install Castopod?
---
# How to install Castopod?
import { Aside } from "@astrojs/starlight/components";
Castopod was thought-out to be easy to install. Whether using dedicated or
shared hosting, you can install it on most PHP-MySQL compatible web servers.
::: info Note
This section of the documentation will help you set up Castopod for production.
If you are looking to partake in the development of Castopod, you may skip to
the contributing section.
:::
## Requirements
- PHP v8.0 or higher
- MySQL version 5.7 or higher or MariaDB version 10.2 or higher
- PHP v8.4 or higher
- MySQL version 8.4 or higher or MariaDB version 11.4 or higher
- HTTPS support
- An [ntp-synced clock](https://wiki.debian.org/NTP) to validate federation's
incoming requests
### PHP v8.0 or higher
### PHP v8.4 or higher
PHP version 8.0 or higher is required, with the following extensions installed:
PHP version 8.4 or higher is required, with the following extensions installed:
- [intl](https://php.net/manual/en/intl.requirements.php)
- [libcurl](https://php.net/manual/en/curl.requirements.php)
......@@ -43,14 +36,6 @@ Additionally, make sure that the following extensions are enabled in your PHP:
> We recommend using [MariaDB](https://mariadb.org).
::: warning Warning
Castopod only works with supported MySQL 5.7 or higher compatible databases. It
will break with the previous MySQL v5.6 for example as its end of life was on
February 5, 2021.
:::
You will need the server hostname, database name, username and password to
complete the installation process. If you do not have these, please contact your
server administrator.
......@@ -58,7 +43,8 @@ server administrator.
#### Privileges
User must have at least these privileges on the database for Castopod to work:
`CREATE`, `ALTER`, `DELETE`, `EXECUTE`, `INDEX`, `INSERT`, `SELECT`, `UPDATE`.
`CREATE`, `ALTER`, `DELETE`, `EXECUTE`, `INDEX`, `INSERT`, `SELECT`, `UPDATE`,
`REFERENCES`, `CREATE VIEW`.
### (Optional) FFmpeg v4.1.8 or higher for Video Clips
......@@ -90,29 +76,19 @@ want to generate Video Clips. The following extensions must be installed:
4. Add **cron tasks** on your web server for various background processes
(replace the paths accordingly):
- For social features to work properly, this task is used to broadcast social
activities to your followers on the fediverse:
```bash
* * * * * /path/to/php /path/to/castopod/public/index.php scheduled-activities
```
- For having your episodes be broadcasted on open hubs upon publication using
[WebSub](https://en.wikipedia.org/wiki/WebSub):
```bash
* * * * * /usr/local/bin/php /castopod/public/index.php scheduled-websub-publish
* * * * * /path/to/php /path/to/castopod/spark tasks:run >> /dev/null 2>&1
```
- For Video Clips to be created (see
[FFmpeg requirements](#ffmpeg-v418-or-higher-for-video-clips)):
```bash
* * * * * /path/to/php /path/to/castopod/public/index.php scheduled-video-clips
```
**Note** - If you do not add this cron task, the following Castopod features
will not work:
> These tasks run **every minute**. You may set the frequency depending on
> your needs: every 5, 10 minutes or more.
- Importing a podcast from an existing RSS feed
- Broadcasting social activities to your followers in the fediverse
- Broadcasting episodes to open hubs using
[WebSub](https://en.wikipedia.org/wiki/WebSub)
- Generating video clips -
[requires FFmpeg](#optional-ffmpeg-v418-or-higher-for-video-clips)
### (recommended) Install Wizard
......@@ -121,13 +97,103 @@ want to generate Video Clips. The following extensions must be installed:
2. Follow the instructions on your screen.
3. Start podcasting!
::: info Note
<Aside>
The install script writes a `.env` file in the package root. If you cannot go
through the install wizard, you can
[create and update the `.env` file manually](#alternative-manual-configuration).
through the install wizard, you can create and edit the `.env` file manually
based on the `.env.example` file.
</Aside>
### Using CLI
1. Create a `.env` file in the package root based on the `.env.example` file.
2. Initialize the database using:
```sh
php spark install:init-database
```
3. Create the superadmin user using:
```sh
php spark install:create-superadmin
```
4. Head on to your admin gateway to start podcasting!
### Email/SMTP setup
:::
Email configuration is required for some features to work properly (eg.
retrieving your forgotten password, sending instructions to premium subscribers,
…)
You may add your email configuration in your instance's `.env` like so:
```ini
# […]
email.fromEmail="your_email_address"
email.SMTPHost="your_smtp_host"
email.SMTPUser="your_smtp_user"
email.SMTPPass="your_smtp_password"
```
#### Email config options
| Variable name | Type | Default |
| ---------------- | -------------------- | ------------ |
| **`fromEmail`** | string | `undefined` |
| **`fromName`** | string | `"Castopod"` |
| **`SMTPHost`** | string | `undefined` |
| **`SMTPUser`** | string | `undefined` |
| **`SMTPPass`** | string | `undefined` |
| **`SMTPPort`** | number | `25` |
| **`SMTPCrypto`** | [`"tls"` or `"ssl"`] | `"tls"` |
### Media storage
By default, files are saved to the `public/media` folder using the file system.
If you need to relocate the `media` folder to a different location, you can
specify it in your `.env` file as shown below:
```ini
# […]
media.root="media"
media.storage="/mnt/storage"
```
In this example, the files will be saved to the /mnt/storage/media folder. Make
sure to also update your web server configuration to reflect this change.
### S3
If you prefer storing your media files on an S3 compatible storage, you may
specify it in your `.env`:
```ini
# […]
media.fileManager="s3"
media.s3.endpoint="your_s3_host"
media.s3.key="your_s3_key"
media.s3.secret="your_s3_secret"
media.s3.region="your_s3_region"
```
#### S3 config options
| Variable name | Type | Default |
| ----------------------- | ------- | ----------- |
| **`endpoint`** | string | `undefined` |
| **`key`** | string | `undefined` |
| **`secret`** | string | `undefined` |
| **`region`** | string | `undefined` |
| **`bucket`** | string | `castopod` |
| **`protocol`** | number | `undefined` |
| **`pathStyleEndpoint`** | boolean | `false` |
| **`keyPrefix`** | string | `undefined` |
## Community packages
......@@ -142,29 +208,35 @@ self-hosting for you.
<div class="flex flex-wrap items-center gap-4">
<a href="https://install-app.yunohost.org/?app=castopod" target="_blank" rel="noopener noreferrer">
<img src="https://install-app.yunohost.org/install-with-yunohost.svg" alt="Install Castopod with YunoHost" class="align-middle" />
<a
href="https://install-app.yunohost.org/?app=castopod"
target="_blank"
rel="noopener noreferrer"
>
<img
src="https://install-app.yunohost.org/install-with-yunohost.svg"
alt="Install Castopod with YunoHost"
class="align-middle"
/>
</a>
<a href="https://github.com/YunoHost-Apps/castopod_ynh" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-4 py-[.3rem] mx-auto font-semibold text-center text-black rounded-md gap-x-1 border-2 border-solid border-[#333] hover:no-underline hover:bg-gray-100"><svg
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="1em" height="1em"
class="text-xl"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 2A10 10 0 0 0 2 12a10 10 0 0 0 6.84 9.49c.5.09.69-.21.69-.48l-.02-1.86c-2.51.46-3.16-.61-3.36-1.18-.11-.28-.6-1.17-1.02-1.4-.35-.2-.85-.66-.02-.67.79-.01 1.35.72 1.54 1.02.9 1.52 2.34 1.1 2.91.83a2.1 2.1 0 0 1 .64-1.34c-2.22-.25-4.55-1.11-4.55-4.94A3.9 3.9 0 0 1 6.68 8.8a3.6 3.6 0 0 1 .1-2.65s.83-.27 2.75 1.02a9.28 9.28 0 0 1 2.5-.34c.85 0 1.7.12 2.5.34 1.9-1.3 2.75-1.02 2.75-1.02.54 1.37.2 2.4.1 2.65.63.7 1.02 1.58 1.02 2.68 0 3.84-2.34 4.7-4.56 4.94.36.31.67.91.67 1.85l-.01 2.75c0 .26.19.58.69.48A10.02 10.02 0 0 0 22 12 10 10 0 0 0 12 2z"/></svg>Github
Repo</a>
<a
href="https://github.com/YunoHost-Apps/castopod_ynh"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center px-4 py-[.3rem] mx-auto font-semibold text-center text-black rounded-md gap-x-1 border-2 border-solid border-[#333] hover:no-underline hover:bg-gray-100"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="1em"
height="1em"
class="text-xl"
>
<path fill="none" d="M0 0h24v24H0z" />
<path d="M12 2A10 10 0 0 0 2 12a10 10 0 0 0 6.84 9.49c.5.09.69-.21.69-.48l-.02-1.86c-2.51.46-3.16-.61-3.36-1.18-.11-.28-.6-1.17-1.02-1.4-.35-.2-.85-.66-.02-.67.79-.01 1.35.72 1.54 1.02.9 1.52 2.34 1.1 2.91.83a2.1 2.1 0 0 1 .64-1.34c-2.22-.25-4.55-1.11-4.55-4.94A3.9 3.9 0 0 1 6.68 8.8a3.6 3.6 0 0 1 .1-2.65s.83-.27 2.75 1.02a9.28 9.28 0 0 1 2.5-.34c.85 0 1.7.12 2.5.34 1.9-1.3 2.75-1.02 2.75-1.02.54 1.37.2 2.4.1 2.65.63.7 1.02 1.58 1.02 2.68 0 3.84-2.34 4.7-4.56 4.94.36.31.67.91.67 1.85l-.01 2.75c0 .26.19.58.69.48A10.02 10.02 0 0 0 22 12 10 10 0 0 0 12 2z" />
</svg>
Github Repo
</a>
</div>
### Install with Docker
If you wish to use Docker to install Castopod, it is possible thanks to
[Romain de Laage](https://mamot.fr/@rdelaage)!
<a href="https://gitlab.utc.fr/picasoft/projets/services/castopod" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-4 py-2 mx-auto font-semibold text-center text-white rounded-md shadow gap-x-1 bg-[#1282d7] hover:no-underline hover:bg-[#0f6eb5]">Install
with
Docker<svg viewBox="0 0 24 24" width="1em" height="1em" class="text-xl text-pine-200"><path fill="currentColor" d="m16.172 11-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z"></path></svg></a>
::: info Note
Given high demand for docker, we plan on maintaining an official Castopod Docker
image directly into the Castopod repository.
:::
---
title: Security concerns
---
import { Aside } from "@astrojs/starlight/components";
Castopod is built on top of [CodeIgniter4](https://codeigniter.com/), a PHP
framework that encourages
[good security practices](https://codeigniter.com/user_guide/concepts/security.html).
To maximize your instance's safety and prevent any malicious attack, we
recommend you update all your Castopod files permissions after installation or
updates (to avoid any prior permission error):
- `writable/` folder must be **readable** and **writable**.
- `public/media/` folder must be **readable** and **writable**.
- any other file must be set to **readonly**.
For instance, if you are using Apache or NGINX with Ubuntu you may do the
following:
```bash
sudo chown -R root:root /path/to/castopod
sudo chown -R www-data:www-data /path/to/castopod/writable
sudo chown -R www-data:www-data /path/to/castopod/public/media
```
## Third-party Plugins
<Aside type="caution" title="Disclaimer">
Installing untrusted third-party plugins on Castopod carries inherent security
risks, such as unauthorized access to sensitive user data, data breaches, data
tampering, and injecting malicious code.
</Aside>
Since v2's [Plugins Architecture](../../plugins), Castopod can be extended with
all sorts of cool features. Anyone can choose to create their own plugins and
even share them with the community.
👉 Plugins are a way to inject code in parts of Castopod through
[Hooks](../../plugins/hooks).
Now, if you create your own plugin and install it in your own Castopod, that
means you control both the code that gets injected and the environment: all is
good!
But as for **third-party plugins**, you must treat them as a **potential
security risk _by default_**:
1. Make sure you **trust the source before installing any third-party plugin**
2. **Review the plugin's code** yourself if you can or
[ask developers from the community for help](https://castopod.org/chat)
---
title: How to update Castopod?
---
import { Aside } from "@astrojs/starlight/components";
After installing Castopod, you may want to update your instance to the latest
version in order to enjoy the latest features ✨, bug fixes 🐛 and performance
improvements ⚡.
## Update instructions
0. ⚠️ Before any update, we highly recommend you backup your Castopod files and
database.
- cf.
[Should I make a backup before updating?](#should-i-make-a-backup-before-updating)
1. Go to the
[releases page](https://code.castopod.org/adaures/castopod/-/releases) and
see if your instance is up to date with the latest Castopod version
- cf.
[Where can I find my Castopod version?](#where-can-i-find-my-castopod-version)
2. Download the latest release package named `Castopod Package`, you may choose
between the `zip` or `tar.gz` archives
- ⚠️ Make sure you download the Castopod Package and **NOT** the Source Code
- Note that you can also download the latest package from
[castopod.org](https://castopod.org/)
3. On your server:
- Remove all files except `.env` and `public/media`
- Copy the new files from the downloaded package into your server
<Aside>
You may need to reset files permissions as during the install process.
Check [Security Concerns](./security).
</Aside>
4. Update your database schema from your `Castopod Admin` > `About` page or by
running:
```bash
php spark castopod:database-update
```
5. Clear your cache from your `Castopod Admin` > `Settings` > `general` >
`Housekeeping`
6. ✨ Enjoy your fresh instance, you're all done!
<Aside>
Releases may come with additional update instructions (see
[releases page](https://code.castopod.org/adaures/castopod/-/releases)).
- cf.
[I haven't updated my instance in a long time… What should I do?](#i-havent-updated-my-instance-in-a-long-time-what-should-i-do)
</Aside>
## Fully Automated updates
> Coming soon... 👀
## Frequently asked questions (FAQ)
### Where can I find my Castopod version?
Go to your Castopod admin panel, the version is displayed on the bottom left
corner.
Alternatively, you can find the version in the `app > Config > Constants.php`
file.
### I haven't updated my instance in a long time… What should I do?
No problem! Just get the latest release as described above. Only, when going
through the release instructions (4), perform them sequentially, from the oldest
to the newest.
> You may want to backup your instance depending on how long you haven't updated
> Castopod.
For example, if you're on `v1.0.0-alpha.42` and would like to upgrade to
`v1.0.0-beta.1`:
0. (highly recommended) Make a backup of your files and database.
1. Download the latest release, overwrite your files whilst keeping `.env` and
`public/media`.
2. Go through each release update instructions sequentially (from oldest to
newest) starting with `v1.0.0-alpha.43`, `v1.0.0-alpha.44`,
`v1.0.0-alpha.45`, …, `v1.0.0-beta.1`.
3. ✨ Enjoy your fresh instance, you're all done!
### Should I make a backup before updating?
We advise you do, so you don't lose everything if anything goes wrong!
More generally, we advise you make regular backups of your Castopod files and
database to prevent you from losing it all…
---
sidebarDepth: 2
title: Welcome 👋
---
# Welcome 👋
[![release-badge]][release]&nbsp;[![license-badge]][license]&nbsp;[![contributions-badge]][contributions]&nbsp;[![semantic-release-badge]][semantic-release]&nbsp;[![crowdin-badge]][crowdin]&nbsp;[![discord-badge]][discord]&nbsp;[![stars-badge]][stars]
import { LinkCard } from "@astrojs/starlight/components";
Castopod is a free & open-source hosting platform made for podcasters who want
engage and interact with their audience.
......@@ -13,16 +11,7 @@ Castopod is easy to install and was built on top of
[CodeIgniter4](https://codeigniter.com/), a powerful PHP framework with a very
small footprint.
::: info Status
Castopod is currently in **beta** but already quite stable and used by
podcasters around&nbsp;the&nbsp;world!
:::
<div class="flex items-center">
<a href="/getting-started/install" class="inline-flex items-center px-4 py-2 mx-auto font-semibold text-center text-white rounded-full shadow gap-x-1 bg-pine-500 hover:no-underline hover:bg-pine-600">Install<svg viewBox="0 0 24 24" width="1em" height="1em" class="text-xl text-pine-200"><path fill="currentColor" d="m16.172 11-5.364-5.364 1.414-1.414L20 12l-7.778 7.778-1.414-1.414L16.172 13H4v-2z"></path></svg></a>
</div>
<LinkCard title="Install" href="./getting-started/install" />
## Features
......@@ -49,6 +38,7 @@ podcasters around&nbsp;the&nbsp;world!
- 🔗 &nbsp;Funding links
- 📲 &nbsp;listen-to-click ads
- 🤝 &nbsp;value4value / WebMonetization
- 💎 &nbsp;Premium podcasts
- 📡 &nbsp;Publish your episodes everywhere with RSS:
- 📱 &nbsp;On all indexes and apps: Podcast Index, Apple Podcasts, Spotify,
Google Podcasts, Deezer, Podcast Addict, Podfriend, …
......@@ -57,8 +47,9 @@ podcasters around&nbsp;the&nbsp;world!
- 📤 &nbsp;Move your podcast out of Castopod
- 🔀 &nbsp;Multi-tenant: host as many podcasts as you want
- 👥 &nbsp;Multi-user: add contributors and set roles
- 🌎 &nbsp;i18n support: translated in English, French & Polish with more to
come!
- 🌎 &nbsp;i18n support: translated in English, French, Polish, German,
Brazilian Portuguese, Spanish, simplified Chinese… and
[many more](https://translate.castopod.org)!
## Motivation
......@@ -86,14 +77,14 @@ This project is pushed by the open-source community, and specifically by the
We believe that a solution is not necessarily right for everyone, it highly
depends on your needs. So, here are comparisons with other tools to help you to
gauge whether Castopod is the right fit for&nbsp;you.
gauge whether Castopod is the right fit for you.
### Castopod vs Wordpress
Castopod is often referred to as "the Wordpress for podcasts" because of the
similarities between the two. In some ways this is true. And actually, Castopod
was greatly inspired by the Wordpress ecosystem, seeing the ease of adoption
from the community and the number of websites running&nbsp;it.
from the community and the number of websites running it.
Just like Wordpress, Castopod is free & open source, built using PHP with a
MySQL database and is packaged in a way that you can easily install on most web
......@@ -105,7 +96,7 @@ website online.
On the other hand, Castopod is meant to address the podcasters needs
specifically, focusing on podcasting, and nothing else. You don't need any
plugin to get you started on your podcasting&nbsp;journey.
plugin to get you started on your podcasting journey.
This allows optimizing the processes specific to podcasting: ranging from the
creation of your podcasts and the publication of new episodes all the way to
......@@ -153,20 +144,21 @@ That being said, there are two main differences with other podcasting solutions:
## Contributing
Love Castopod and would like to help? Take a look at the following documentation
to get you&nbsp;started.
to get you started.
### Code of conduct
Castopod has adopted a Code of Conduct that we expect project participants to
adhere to. Please read the
[CODE_OF_CONDUCT manual](https://code.castopod.org/adaures/castopod/-/blob/beta/CODE_OF_CONDUCT.md)
so that you can understand what actions will and will not be&nbsp;tolerated.
[CODE_OF_CONDUCT manual](https://code.castopod.org/adaures/castopod/-/blob/develop/CODE_OF_CONDUCT.md)
so that you can understand what actions will and will not be tolerated.
### Contributing guide
Read our [contributing guide](./contributing/guidelines.md) to learn about our
development process, how to propose bugfixes and improvements, and how to build
and test your changes to Castopod.
Read our
[contributing guide](https://code.castopod.org/adaures/castopod/-/blob/develop/CONTRIBUTING.md)
to learn about our development process, how to propose bugfixes and
improvements, and how to build and test your changes to Castopod.
## Contact
......@@ -191,26 +183,12 @@ The ongoing development of Castopod is made possible with the support of its
backers. If you'd like to help, please consider
[sponsoring Castopod's development](https://opencollective.com/castopod/contribute).
<div class="flex flex-wrap gap-x-16 gap-y-8">
<a href="https://adaures.com/" target="_blank" rel="noopener noreferrer"><img src="/images/sponsors/adaures.svg" alt="Ad Aures Logo" class="h-16" /></a>
<a href="https://nlnet.nl/project/Castopod/" target="_blank" rel="noopener noreferrer"><img src="/images/sponsors/nlnet.svg" alt="NLnet Logo" class="h-16" /></a>
</div>
[![Ad Aures Logo](../../../assets/images/sponsors/adaures.svg)](https://adaures.com/)
[![NLnet Logo](../../../assets/images/sponsors/nlnet.svg)](https://nlnet.nl/)
## License
[GNU Affero General Public License v3.0](https://choosealicense.com/licenses/agpl-3.0/)
Copyright © 2020-present, [Ad Aures](https://adaures.com/).
https://img.shields.io/gitlab/v/release/2?color=brightgreen&gitlab_url=https%3A%2F%2Fcode.castopod.org%2F&include_prereleases&label=release
https://img.shields.io/github/license/ad-aures/castopod?color=blue
https://img.shields.io/badge/contributions-welcome-brightgreen.svg
https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
https://img.shields.io/github/stars/ad-aures/castopod?style=social
[release]: https://code.castopod.org/adaures/castopod/-/releases
[license]: https://code.castopod.org/adaures/castopod/-/blob/beta/LICENSE.md
[contributions]: https://code.castopod.org/adaures/castopod/-/issues
[semantic-release]: https://github.com/semantic-release/semantic-release
[discord]: https://castopod.org/discord
[stars]: https://github.com/ad-aures/castopod/stargazers
[crowdin]: https://translate.castopod.org/project/castopod
---
title: Creating a Plugin
---
import { FileTree, Steps, Badge } from "@astrojs/starlight/components";
In order to get started, you first need to
[setup your Castopod dev environment](https://code.castopod.org/adaures/castopod/-/blob/develop/CONTRIBUTING-DEV.md).
## 1. Create the plugin folder
You'll first need to create your [plugin folder](./#plugin-folder-structure) in
the `plugins/` directory.
### Using the create command <Badge text="Recommended" size="small" />
To quickly get you started, you can have a folder generated for you using the
following CLI command:
```sh
php spark plugins:create
```
👉 You will be prompted for metadata and hooks usage to have a skeleton plugin
project generated for you!
### Manual setup
<Steps>
1. create a plugin folder inside a vendor directory
<FileTree>
- plugins
- acme
- **hello-world/**
- …
</FileTree>
2. add a manifest.json file
<FileTree>
- hello-world
- **manifest.json**
</FileTree>
See the [manifest reference](./manifest).
3. add the Plugin.php class
<FileTree>
- hello-world
- manifest.json
- **Plugin.php**
</FileTree>
</Steps>
## 2. Build your plugin
Now that your plugin folder is set, you can start working on your Plugin's logic
by implementing [the hooks](./hooks) needed.
### Settings forms
You can prompt users for data through settings forms.
These forms can be built declaratively using the
[settings attribute](./manifest#settings) in your manifest.
```json
// manifest.json
{
"settings": {
"general": {
"field-key": {
"type": "text",
"label": "Enter a text"
}
},
"podcast": {
"field-key": {
"type": "text",
"label": "Enter a text for this podcast"
}
},
"episode": {
"field-key": {
"type": "type",
"label": "Enter a text for this episode"
}
}
}
}
```
This example will generate settings forms at 3 levels:
- `general`: a general form to prompt data to be used by the plugin
- `podcast`: a form for each podcast to prompt for podcast specific data
- `episode`: a form for each episode to prompt for episode specific data
The data can then be accessed in the Plugin class methods via helper methods
taking in the field key:
```php
$this->getGeneralSetting('field-key');
$this->getPodcastSetting($podcast->id, 'field-key');
$this->getEpisodeSetting($episode->id, 'field-key');
```
---
title: Hooks reference
---
Hooks are methods of the Plugin class, they are executed in parts of the
Castopod codebase.
## List
| Hooks | Executes in |
| ---------------- | ----------- |
| rssBeforeChannel | RSS Feed |
| rssAfterChannel | RSS Feed |
| rssBeforeItem | RSS Feed |
| rssAfterItem | RSS Feed |
| siteHead | Website |
### rssBeforeChannel
This hook is executed just before rendering the `<channel>` tag in the Podcast
RSS feed using the given Podcast object.
Here is a good place to alter the Podcast object.
```php
public function rssBeforeChannel(Podcast $podcast): void
{
// …
}
```
### rssAfterChannel
This hook is executed after rendering all of the `<channel>` tags in the Podcast
RSS feed.
Here is a good place to add new tags to the generated channel.
```php
public function rssAfterChannel(Podcast $podcast, RssFeed $channel): void
{
// …
}
```
### rssBeforeItem
This hook is executed before rendering an `<item>` tag in the Podcast RSS feed
using the given Episode object.
Here is a good place to alter the Episode object.
```php
public function rssBeforeItem(Episode $episode): void
{
// …
}
```
### rssAfterItem
This hook is executed after rendering an `<item>`'s tags in the Podcast RSS
feed.
Here is a good place to add new tags to the generated item.
```php
public function rssAfterItem(Epsiode $episode, RssFeed $item): void
{
// …
}
```
### siteHead
This hook is executed in the public pages' `<head>` tag.
This is a good place to add meta tags, custom styles, and third-party scripts to
Castopod's public pages.
```php
public function siteHead(HtmlHead $head): void
{
// …
}
```
---
title: Castopod Plugins
---
import { FileTree, Aside, Tabs, TabItem } from "@astrojs/starlight/components";
Plugins are ways to extend Castopod's core features.
## Plugin folder structure
<FileTree>
- hello-world
- i18n
- en.json
- fr.json
- …
- icon.svg
- manifest.json // required
- LICENSE.md
- Plugin.php // required
- README.md
</FileTree>
Plugins reside in the `plugins/` directory under a `vendor/` folder, ie. the
organisation or person who authored the plugin.
<FileTree>
- **plugins**
- acme
- hello-world/
- …
- atlantis/
</FileTree>
### Plugin manifest (required)
The plugin manifest is a JSON file containing the plugin's metadata and
declarations.
This file will determine whether a plugin is valid or not. The minimal required
data being:
```json
// manifest.json
{
"name": "acme/hello-world",
"version": "1.0.0"
}
```
Checkout the [manifest.json reference](./manifest).
### Plugin class (required)
This is where the plugin's logic lives.
The Plugin class extends Castopod's BasePlugin class and implements one or more
[Hooks](./hooks) (methods) intended to be run throughout Castopod's codebase.
```php
// Plugin.php
<?php
declare(strict_types=1);
use Modules\Plugins\Core\BasePlugin;
class AcmeHelloWorldPlugin extends BasePlugin
{
// this rssBeforeChannel method is a Hook
public function rssBeforeChannel(Podcast $podcast): void
{
// …
}
}
```
<Aside type="note">
The Plugin class name is determined by its `vendor/name` pair.
For example, a plugin living under the `acme/hello-world` folder must be named
`AcmeHelloWorldPlugin`:
- the first letter of every word is capitalized (ie. PascalCase)
- any special caracter is removed
- the `Plugin` suffix is added
</Aside>
### Plugin README
The `README.md` file is loaded into the plugin's view page for the user to read
through.
It should be used for any additional information to help guide the user in using
the plugin.
### Plugin LICENSE
In addition to specifying [the license in the manifest](./manifest#license), you
may add a `LICENSE.md` file. Just as the `README.md` file, its contents will be
loaded into the plugin's view page for the user to read.
### Plugin icon
The plugin icon is displayed next to its title, it is an SVG file intended to
give a graphical representation of the plugin.
The icon should be squared, and be legible in a 64px by 64px circle.
### Internationalization (i18n)
Plugins can be translated. Translation strings live inside the `i18n` folder.
Translation files are JSON files named as locale keys:
<FileTree>
- **i18n**
- en.json // default locale
- fr.json
- de.json
- …
</FileTree>
Supported locales are:
`br`,`ca`,`de`,`en`,`es`,`fr`,`nn-no`,`pl`,`pt-br`,`sr-latn`,`zh-hans`.
The translation strings allow you to translate the title, description and
settings keys (ie. labels, hints, helpers, etc.).
<Tabs>
<TabItem label="English">
```json
// i18n/en.json
{
"title": "Hello, World!",
"description": "A Castopod plugin to greet the world!",
"settings": {
"general": {
"field-key": {
"label": "Enter a text",
"hint": "You can enter any type of character."
}
},
"podcast": {},
"episode": {}
}
}
```
</TabItem>
<TabItem label="French">
```json
// i18n/fr.json
{
"title": "Bonjour, le Monde !",
"description": "Un plugin castopod pour saluer le monde !",
"settings": {
"general": {
"field-key": {
"label": "Saisissez un texte",
"hint": "Vous pouvez saisir n'importe quel type de caractère."
}
},
"podcast": {},
"episode": {}
}
}
```
</TabItem>
</Tabs>
---
title: manifest.json reference
---
This page details the attributes of a Castopod Plugin's manifest, which must be
a JSON file.
### name (required)
The plugin name, including 'vendor-name/' prefix. Examples:
- acme/hello-world
- adaures/click
The name must be lowercase and consist of words separated by `-`, `.` or `_`.
The complete name should match
`^[a-z0-9]([_.-]?[a-z0-9]+)*\/[a-z0-9]([_.-]?[a-z0-9]+)*$`.
### version (required)
The plugin's semantic version (eg. 1.0.0) - see https://semver.org/
### description
The plugin's description. This helps people discover your plugin when listed in
repositories.
### authors
Array one or more persons having authored the plugin. A person is an object with
a required "name" field and optional "email" and "url" fields:
```json
{
"name": "Jean Deau",
"email": "jean.deau@example.com",
"url": "https://example.com/"
}
```
Or you can shorten the object into a single string:
```json
"Jean Deau <jean.deau@example.com> (https://example.com/)"
```
### homepage
The URL to the project homepage.
### license
**Default:** `"UNLICENSED"`
Specify a license for your plugin so that people know how they are permitted to
use it, and any restrictions you're placing on it.
### private
**Default:** `false`
Whether or not to publish the plugin in public directories. If set to `true`,
directories should refuse to publish the plugin.
### submodule
**Default:** `false`
Indicates whether the plugin is part of a monorepo (a single Git repository
containing multiple plugins). If `true`, the plugin shares its repository with
other plugins. In this case, releases should be tagged using the format
`<plugin-name>@<version>` (eg. `acme/hello-world@1.0.0`) to ensure proper
version indexing by plugin repositories.
### keywords
Array of strings to help your plugin get discovered when listed in repositories.
### minCastopodVersion
The minimal version of Castopod with which the plugin is compatible.
### hooks
List of hooks used by the plugin. If the hook is not specified, Castopod will
not run it.
### settings
Declare settings forms for persisting user data. The plugin's settings forms can
be declared at three levels: `general`, `podcast`, and `episode`.
Each level accepts one or more fields, identified by a key.
```json
{
"settings": {
"general": { // general settings form
"field-key": {
"type": "text", // default field type: a text input
"label": "Enter a text"
},
},
"podcast": {…}, // settings form for each podcast
"episode": {…}, // settings form for each episode
}
}
```
The `general`, `podcast`, and `episode` settings are of `Fields` object with
each property being a field key and the value being a `Field` object.
#### Field object
A field is a form element:
| Property | Type | Note |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| `type` | `checkbox`, `datetime`, `email`, `group`, `html`, `markdown`, `number`, `radio-group`, `rss`, `select-multiple`, `select`, `text`, `textarea`, `toggler`, `url` | Default is `text` |
| `label` (required) | `string` | Can be translated (see i18n) |
| `hint` | `string` | Can be translated (see i18n) |
| `helper` | `string` | Can be translated (see i18n) |
| `defaultValue` | `string` | You can specify multiple comma separated values for `select-multiple` |
| `validationRules` | `string` \| `array` | See [available validation rules](#available-validation-rules) |
| `optional` | `boolean` | Default is `false` |
| `options` | `Options` | Required for `radio-group`, `select-multiple`, and `select` types. |
| `multiple` | `boolean` | Default is `false` |
| `fields` | `Array<string, Field>` | Required for `group` type |
#### Options object
The `Options` object properties are option keys and the value is an `Option`.
##### Option object
| Property | Type | Note |
| ------------------ | -------- | ---------------------------- |
| `label` (required) | `string` | Can be translated (see i18n) |
| `description` | `string` | Can be translated (see i18n) |
### files
Array of file patterns that describes the entries to be included when your
plugin is installed.
### repository
Repository where the plugin's code lives. Helpful for people who want to
contribute.
#### Available validation rules
The following rules are a subset of
[CodeIgniter4's validation rules](https://codeigniter.com/user_guide/libraries/validation.html#available-rules).
| Rule | Parameter | Description | Example |
| --------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| alpha | No | Fails if field has anything other than alphabetic characters in ASCII. | |
| alpha_dash | No | Fails if field contains anything other than alphanumeric characters, underscores or dashes in ASCII. | |
| alpha_numeric | No | Fails if field contains anything other than alphanumeric characters in ASCII. | |
| alpha_numeric_punct | No | Fails if field contains anything other than alphanumeric, space, or this limited set of punctuation characters: `~` (tilde), `!` (exclamation), `#` (number), `$` (dollar), `%` (percent), `&` (ampersand), `*` (asterisk), `-` (dash), `_` (underscore), `+` (plus), `=` (equals), `\|` (vertical bar),`:`(colon),`.` (period). | |
| alpha_numeric_space | No | Fails if field contains anything other than alphanumeric or space characters in ASCII. | |
| alpha_space | No | Fails if field contains anything other than alphabetic characters or spaces in ASCII. | |
| decimal | No | Fails if field contains anything other than a decimal number. Also accepts a `+` or `-` sign for the number. | |
| differs | Yes | Fails if field does not differ from the one in the parameter. | `differs[field_name]` |
| exact_length | Yes | Fails if field length is not exactly the parameter value. One or more comma-separated values are possible. | `exact_length[5]` or `exact_length[5,8,12]` |
| greater_than | Yes | Fails if field is less than or equal to the parameter value or not numeric. | `greater_than[8]` |
| greater_than_equal_to | Yes | Fails if field is less than the parameter value, or not numeric. | `greater_than_equal_to[5]` |
| hex | No | Fails if field contains anything other than hexadecimal characters. | |
| in_list | Yes | Fails if field is not within a predetermined list. | `in_list[red,blue,green]` |
| integer | No | Fails if field contains anything other than an integer. | |
| is_natural | No | Fails if field contains anything other than a natural number: `0`, `1`, `2`, `3`, etc. | |
| is_natural_no_zero | No | Fails if field contains anything other than a natural number, except zero: `1`, `2`, `3`, etc. | |
| less_than | Yes | Fails if field is greater than or equal to the parameter value or not numeric. | `less_than[8]` |
| less_than_equal_to | Yes | Fails if field is greater than the parameter value or not numeric. | `less_than_equal_to[8]` |
| max_length | Yes | Fails if field is longer than the parameter value. | `max_length[8]` |
| min_length | Yes | Fails if field is shorter than the parameter value. | `min_length[3]` |
| not_in_list | Yes | Fails if field is within a predetermined list. | `not_in_list[red,blue,green]` |
| regex_match | Yes | Fails if field does not match the regular expression. | `regex_match[/regex/]` |
| valid_base64 | No | Fails if field contains anything other than valid Base64 characters. | |
| valid_date | Yes | Fails if field does not contain a valid date. Any string that `strtotime()` accepts is valid if you don't specify an optional parameter that matches a date format. | `valid_date[d/m/Y]` |
---
title: Welcome to the Castopod User Guide
---
import { LinkCard, CardGrid } from "@astrojs/starlight/components";
Welcome to the Castopod User Guide. This guide is divided into three parts:
<CardGrid>
<LinkCard title="Managing your instance" href="instance" />
<LinkCard title="Managing your podcasts" href="podcast" />
<LinkCard title="Website overview" href="website" />
</CardGrid>
---
title: Fediverse
---
## What is the Fediverse?
Wikipedia defines the Fediverse as:
> The fediverse is a collection of social networking services that can
> communicate with each other using a common protocol, ActivityPub. Users of
> different websites can send and receive status updates, multimedia files and
> other data across the network.
Your podcast is connected to the Fediverse and, for example, Mastodon users can
subscribe to your handle and will receive a message every time your podcast
publishes a new episode. You can also broadcast messages to your followers on
the Fediverse from your [home page](../website#home). Mastodon users can like
and share your posts.
## Manage Fediverse Blocks
You can block a Fediverse user or an entire domain to help stop harassment or
spam.
### Blocked Accounts
To block a specific Fediverse user, enter the user's handle in the **Account
Handle** text box. It should be in the format of `@user@domain.com`. Press
`Block` to block the user from following your podcast.
A list of all blocked accounts is shown below the **Account Handle** text box.
You can choose to unblock a user by pressing the `Unblock` button.
### Blocked Domains
To block an entire domain, enter the domain name such as `www.example.com` in
the **Domain Name** field and press `Block`.
A list of all blocked domains is shown below the **Domain Name** text box. You
can choose to unblock a domain by pressing the `Unblock` button.
---
title: Managing your instance
---
import { LinkCard, CardGrid } from "@astrojs/starlight/components";
## What is an instance?
Your podcast is hosted on your sever and connected to the [Fediverse](fediverse)
in what is called an _instance_. Your instance can manage multiple podcasts,
people and users, and host additional pages found on all of your podcasts.
Managing your instance, including podcasts, people, and users is separate from
the settings for each individual podcast.
## Ready to get started?
Learn more about adding podcasts, users, and more by clicking one of the links
below.
<CardGrid>
<LinkCard title="Create or import a podcast" href="podcast" />
<LinkCard
title="Manage the people involved with your podcast"
href="persons"
/>
<LinkCard title="Manage Fediverse integration" href="fediverse" />
<LinkCard
title="Manage users who can access the admin interface"
href="users"
/>
<LinkCard title="Add additional web pages" href="pages" />
<LinkCard title="Manage settings" href="settings" />
</CardGrid>
---
title: Pages
---
## Add Pages
You can add static pages linked from your podcast's home page. From the left
hand navigation, choose the `+` sign or click `Pages` -> `New Page`.
### Title
In the **Title** text box, enter the name for the page you are adding.
### Permalink
In the `Permalink` text box, enter the permalink if you want it different than
the title.
### Content
You can add your page content in the **Content** text box. You can use Markdown
to style your text.
When finished, press the `Create page` button. You can view your page from your
podcast's home page. It will be linked in the right hand side bar navigation.
## Delete or Edit a Page
After adding a page, you can delete the page or edit it by choosing `Pages` ->
`All Pages` from the instance navigation sidebar on the left. Press the
corresponding button to view the page, edit it, or delete it.
---
title: Manage Podcast contributors
---
The **Persons** section allows you to add podcast contributors. It is needed in
the Podcast section to assign roles and is also used on the **Credits** page
linked from your podcast's homepage.
From the left hand navigation, press `Persons` to expand the menu. To view a
list of all people that have been added to Castopod, press `All Persons`.
## Add a person
To add a person, press `New Person` from the left hand sidebar or press
`Create a person` from the upper right hand corner of the **All Persons** page
and fill out the following fields:
- **Avatar**: You can optionally add a picture or avatar of the person. Press
`Choose File` and upload a picture from your computer. It must be at least
400px wide and tall.
- **Full Name**: Enter the name as you want it displayed on your website.
- **Unique Name**: Enter a unique username for the person you are adding. This
will be displayed in the Podcasts secton when assigning this person a role.
- **Information URL**: Enter a URL for the person's homepage, profile, or social
media account to be linked from the [Credits page](../website/credits).
---
title: Create or import a podcast
---
import { Aside } from "@astrojs/starlight/components";
You can create a new podcast or import an existing podcast into Castopod in the
Podcasts section. If you are adding a second podcast to Castopod, see the
[Home page documentation](../website#home-page) for how that will change your
home page.
From the left hand navigation sidebar, press the `+` sign to the right of
Podcasts to create your first podcast.
## Podcast Identity
### Podcast Cover
To upload your podcast cover art, press the `Choose File` button and choose your
cover art from your computer. The cover art needs to be in JPG or PNG format and
a minimum of 1400px wide and tall with a maximum of 3000px wide and tall.
### Title
Enter the name of your podcast in the **Title** field.
### Description
Describe what your podcast is about. You can use Markdown to style the text and
you can resize the text box by pressing and holding the bottom right hand corner
of the text box.
### Type
Choose how your listeners should listen to your podcast. **Episodic** lets
listeners know they can consume your podcast in any order, such as an interview
podcast. Choose **Serial** if your episodes are meant to be listened to in
sequential order.
### Medium
Choose the type of audio for your podcast:
- **Podcast**: a standard podcast.
- **Music**: A feed of music organized into an "album" with each item a song
within the album.
- **Audiobook**: A specific type of audio with one item per feed, or where items
represent chapters within a book.
## Classification
### Language
From the dropdown menu, choose which language is spoken in your podcast.
### Category
Choose the category that represents your podcast, such as Arts, Comedy,
Technology, etc.
### Other categories (optional)
You can choose a second category in addition to the main category you set up.
### Parental advisory
Choose if your podcast has explicit content or swearing or choose Clean if your
podcast is suitable for everyone. You can also choose to leave this category as
undefined. When [creating a new episode](../podcast/episodes), you will also
have the opportunity to choose clean, explicit, or undefined on a per episode
basis.
## Author
### Owner name and email
Enter the owner name and email in the provided fields. This is only visible in
the RSS feed and is used by other podcasting platforms to verify your ownership
of your podcast. You can choose to remove the owner email from the public RSS
feed by using the provided toggle.
### Publisher
If your podcast is part of a podcast network or is produced by a company, enter
the publisher here.
### Copyright
You can optionally add the copyright holder in this field.
### Fediverse identity
Enter the handle (or nickname) for your podcast. This will allow people on
Mastodon and other Fediverse services to follow your podcast. Your handle will
be shown as @yourdomain.com@handle on the Fediverse.
To learn more about Fediverse integration, visit the
[Fediverse documentation page](../instance/fediverse).
### Podcast banner
Upload a banner image to be displayed at the top of your podcast's home page.
The banner must have a 3:1 ratio and be at least 1500px wide.
### Premium
Toggle this setting to set all episodes by default as premium. When creating an
episode, it will default to premium, and you can still choose to make some
episodes, trailers, or bonus content as free and public.
## Open Podcast Prefix Project (OP3)
The [Open Podcast Prefix Project](https://op3.dev) is an open source and trusted
third party analytics service. If you toggle this to enabled, you will be able
to view analytics for your podcast over time including the number of listens
over time, episode comparison charts, and more.
## Location
You can optionally add a real or fictitious location name in this field. When
[creating a new episode](../podcast/episodes) you also can add a location to an
individual episode.
## Advanced Parameters
You can optinally toggle the following settings:
- **Prevent podcast from being copied**: this locks your podcast and does not
allow other podcast platforms to import your podcast. If you decide in the
future to migrate away from Castopod to a new platform, this toggle will need
to be unchecked.
- **Podcast should be hidden from public catalogues**: If toggled, a best effort
is made to hide the entire podcast from appearing in Apple Podcasts, YouTube
Music, and any other third party podcast apps. (Not guaranteed)
- **Podcast will not be having new episodes**: If your podcast comes to an end,
you can toggle this to let listeners know there will not be new episodes.
## Import an existing podcast
When importing a podcast, make sure you own the rights for this podcast before
importing it. Copying and broadcasting a podcast without the proper rights is
piracy and is liable to prosecution.
### Import the podcast
To import a podcast, enter the podcast's **Feed URL**. The feed must be in XML
or RSS format. You may want to validate the feed to make sure there are no
errors in the RSS or XML feed prior to importing as errors may cause the import
to fail. One popular feed validator is
[Cast Feed Validator](https://www.castfeedvalidator.com) from Blubrry
Podcasting.
### Podcast information
Enter the handle for your podcast. This will be part of the URL for others to
interact with your podcast on the Fediverse. It will be
yourdomain.com@nameofyourpodcast.
Choose the language your podcast is recorded in from the drop down box.
Lastly, choose the Category of your podcast, such as Sports, Technology, Arts,
etc.
When complete, click Add import to queue. You will then be redirected to a
Podcast imports page to view the status of the import. You can refresh the page
to see the status of the import including the import duration and how many
episodes were imported when complete.
<Aside>
If your import times out, check your `max_execution_time` in your `PHP.ini`
file. You may need to increase it from 30 seconds (the default) to add more
time, such as 300 seconds (5 minutes) for larger podcasts.
</Aside>
---
title: Settings
---
To change or update the settings for your instance, choose `Settings` from the
left hand navigation.
## General settings
### Instance
#### Site Name
Update the name of your instance in the `Site name` text field.
#### Site Description
Update description of your instance in the `Site description` text box.
#### Site icon
You can upload a site icon, also known as a favicon, by pressing `Choose file`.
Site icons are what you see on your browser tabs, bookmarks, and shortcuts on
mobile devices. The image must be at least 500px tall and wide.
### Images
If you come across broken or missing images on your site, press
`Regenerate images`. This process may take time.
### Housekeeping
You can run various tasks for your instance:
- **Reset counts**: This will reset and recalculate counts for followers, posts,
and comments.
- **Rename episode files**: This option renames all episodes files to a random
name. If one of your private episodes leaks, toggle this setting to
effectively hide the episode.
- **Clear all cache**: This option will flush the Redis cache or writable /
cache files.
## Theme
You can choose one of six accent colors for your public pages.
## About
This shows general information about your instance including:
- Host name (typically your domain name)
- Castopod version
- PHP version
- Operating System
- Available languages
---
title: Users
---
Roles and permissions in Castopod are defined in two ways, **Instance** users
and [**Podcast**. contributors](../podcast/contributors). For a detailed list of
permissions, view the [Auth](../../getting-started/auth) page.
## Adding a User to the instance
You can add a user to your instance by choosing `Users` -> `New User` from the
left hand navigation menu. There are three roles you can assign to an instance
user:
- **Super Admin**: This user has complete control over Castopod including adding
or removing podcasts or users.
- **Manager**: This user can manage Castopod's content, such as adding or
importing a new podcast and managing people.
- **Podcaster**: This is for general users of Castopod who can access the admin
interface.
---
title: Analytics
---
Castopod comes with a number of different analytics and statistics about your
podcast(s). From the left hand navigation, choose `Analytics` to view the
various options.
## Audience overview
This page provides an overview of your episode's daily downloads, monthly
downloads, and daily bandwidth used.
## Unique listeners
View graphs of the number of daily and monthly users of your podcast. Use the
zoom function at the top of each graph to zoom in or out.
## Listening time
View graphs of your listener's daily and monthly cumulative listening time. Use
the zoom function at the top of each graph to zoom in or out.
## Players
This page provides four pie charts to view statistics for the last week:
- Episode downloads by player
- Episode downloads by service
- Episode downloads by device
- Episode downloads by operating system
You can hover over each graph and press the three dots to download statistics
for the graph you are hovering over. You can interact with the graphs to
download or print:
- Image (PNG, JPG, SVG, or PDF)
- Data (JSON, CSV, XLSX, HTML, or PDF)
- Print
## Locations
You can view where your listeners are located by choosing _Locations_. Two pie
charts are available showing episode downloads by country for the past week and
past year. At the bottom of the page, you can view a world map showing your
listener's locations.
## Time periods
Two bar graphs displaying the week day and time of day your listeners listen to
your podcsat.
## Web pages visits
You can view four pie charts showing information about web page visits:
- Web page visits by source (for the past week)
- Web page visits by source (for the past year)
- Web page visits by landing page
- Web page visits by browser
---
title: Broadcast your podcast
---
## Add your podcast to podcast directories
Listeners can add your RSS feed to their podcast app of choice to subscribe to
your podcast. Most listeners will find your podcast in a podcast directory, such
as Apple Podcasts, YouTube Music, Spotify, or the Podcast Index. These four are
the most popular podcast directories and a number of other directories pull
their data from Apple Podcasts.
Visit [Podnews](https://podnews.net/article/all-the-podcast-directories) to
learn how to add your podcast to most of the podcast directories.
Once your podcast is listed in the podcast directories, you can link to them on
your home page by choosing `Broadcast` from the left hand navigation.
### Podcasting Apps
Castopod provides the ability to link to a majority of podcast directories where
users can find your podcast. For each directory listed fill out the link to your
podcast in a specific directory and the ID. If you want an icon displayed on
your home page, toggle `Display in podcast homepage?`.
After pressing `Save` in the upper right hand corner, visit your home page to
see the icons with hyperlinks on the right hand side of your home page under
_Listen on_.
### Social Networks
If your podcast has a presence on social networks, Castopod provides the ability
to link to your social network profiles. Add the link to your profile page in
the text field and toggle if you want it displayed on your home page.
After pressing `Save` in the upper right hand corner, visit your home page to
see the icons with hyperlinks on the right hand side of your home page under
_Find your podcast on_.
---
title: Contributors
---
From the podcast dashboard, click **Contributors** to add or edit users to have
access to the podcast and its settings. For a detailed list of permissions, view
the [Auth](../../getting-started/auth) page.
## Roles
There are four roles you can assign a person to help manage your podcast.
### Admin
The admin user has complete control over the individual podcast.
### Editor
The editor has access to management functions including podcast import, managing
persons, creating or deleting episodes, and managing clips.
### Author
The autorh can manage content of the podcast, but cannot publish an episode.
They can manage [contributors](contributors), create clips, and create episodes.
### Guest
The guest can view the podcast dashboard and view episodes. They cannot edit or
add any content.