agentsclimarketplace

Building singlepages

Skill MacareuxDigital/concretecms-skills/building-singlepages

Agent Skills for Concrete CMS

Install
npx -y skills add MacareuxDigital/concretecms-skills --skill building-singlepages

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 9 stars9 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

This skill provides instructions and best practices for creating and managing single pages in Concrete CMS packages. Use this skill when you need to add custom dashboard pages, specific application logic pages, or any landing pages that don't follow the standard page type/template system.

SKILL.md

4.3 KB, as published. Nobody here has run it

Building Single Pages in Packages

Single pages are unique pages within a Concrete CMS site that are typically used for administrative dashboards, custom application logic, or specific landing pages that don't follow the standard page type/template system.

Creating a Single Page in a Package

1. File Structure

  • Controller: packages/your_package/controllers/single_page/your_page.php
  • View: packages/your_package/single_pages/your_page.php

The path to the single page is relative to these directories. For example, for a page at /dashboard/my_module/settings:

  • Controller: packages/your_package/controllers/single_page/dashboard/my_module/settings.php
  • View: packages/your_package/single_pages/dashboard/my_module/settings.php

2. Implementation

Controller

The controller should extend Concrete\Core\Page\Controller\DashboardPageController for dashboard pages, or Concrete\Core\Page\Controller\PageController for frontend pages.

<?php
namespace Concrete\Package\YourPackage\Controller\SinglePage\Dashboard\MyModule;

use Concrete\Core\Page\Controller\DashboardPageController;
use Concrete\Core\Package\PackageService;
use Concrete\Core\Config\Repository\Liaison;

class Settings extends DashboardPageController
{
    /**
     * Get package-specific configuration repository.
     */
    protected function getConfig(): ?Liaison
    {
        /** @var PackageService $packageService */
        $packageService = $this->app->make(PackageService::class);
        $package = $packageService->getClass('your_package_handle');
        if ($package) {
            return $package->getFileConfig();
        }

        return null;
    }

    public function view()
    {
        $config = $this->getConfig();
        $settingValue = $config->get('my_module.setting_key', 'default');
        $this->set('settingValue', $settingValue);
    }

    public function save()
    {
        if (!$this->token->validate('save_settings')) {
            $this->error->add($this->token->getErrorMessage());
        }

        if (!$this->error->has()) {
            $config = $this->getConfig();
            $config->save('my_module.setting_key', $this->post('settingValue'));
            $this->flash('success', t('Settings saved successfully.'));
            return $this->buildRedirect($this->action('view'));
        }
        
        $this->view();
    }
}

View

The view is a standard PHP file. For dashboard pages, it's typically wrapped in the dashboard theme.

<?php defined('C5_EXECUTE') or die("Access Denied."); ?>

<form method="post" action="<?= $view->action('save') ?>">
    <?= $token->output('save_settings') ?>
    
    <div class="form-group">
        <?= $form->label('settingValue', t('My Setting')) ?>
        <?= $form->text('settingValue', $settingValue) ?>
    </div>

    <div class="ccm-dashboard-form-actions-wrapper">
        <div class="ccm-dashboard-form-actions">
            <button class="float-end btn btn-primary" type="submit"><?= t('Save') ?></button>
        </div>
    </div>
</form>

3. Installation

In your package controller's install() or upgrade() method:

use Concrete\Core\Page\Single as SinglePage;

public function install()
{
    $pkg = parent::install();
    $page = SinglePage::add('/dashboard/my_module/settings', $pkg);
    if ($page) {
        $page->update(['cName' => 'My Settings']);
    }
    return $pkg;
}

Best Practices

  • Configuration: Use $package->getFileConfig() to get a configuration repository specific to your package. This avoids prefixing all keys with package.your_package_handle..
  • Security: Always use CSRF tokens ($token->output(), $token->validate()) in forms.
  • Redirection: For parent dashboard pages that should just redirect to a child, use $this->buildRedirectToFirstAccessibleChildPage() in the view() method of the parent controller and provide an empty view file. This approach ensures that the user is redirected only to a page they have permission to view.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.