Creating a Single Page


I have been reading through all the various posts and "documentation" on creating single pages, but have yet to find a single thing that explains exactly how to do it. It was easy under the pre-5.7 environment, just drop the PHP file in, register it, and bam, done. But not now.

I am specifically needing to create pages to do IPN and other types of processing wherein I definitely do not want the site's theme included, just the specific html needed for the processing.

It would be nice to place each single page under specific areas in the site, just to be clean and logical, but if they have to go under the root, at this point I don't care. Any specifics would be appreciated.

View Replies:
softwallcave replied on at Permalink Reply
How does one actually get rid of the theme for a single page?
How do I get the right view file rendered?

Files I have added:


Registered the single page so that it shows up under the /events pages, and without the controller referred to above, it renders the contents wrapped by the current theme. So now I want to get rid of the theme.

Set the controller namespace so it actually gets called:
namespace Application\Controller\SinglePage\Events;
use Concrete\Core\Page\Controller\PageController;
use Concrete\Theme\Elemental\PageTheme;
class ProcessStuff extends PageController {
   public function view() {
//      $pt = PageTheme::getByHandle('none');
//      if (is_object($pt)) {
//         $view = $this->getViewObject();
//         $view->setCustomPageTheme($pt);
         $this->render('process_stuff'/*, 'none'*/);
//      }

As you might note, I tried to get rid of the currently set theme, as I saw in the Concrete code that one likely should set the current theme (did not work because the built-in "none" theme is not actually registered, but that is a different question).

Anyway, the comments in renderSinglePageByFilename specify that one should pass "none" to the render method. I don't think this works because it just inserts "none" in the path to look for a package and does not actually pay attention to the parameter otherwise with regards to ignoring the theme.

Anyway, without the parameter, as shown above, the renderInnerContents method in /concrete/src/view/view.php is provided a source path for the single page view file as:


This is obviously completely wrong, and I have no idea why Concrete has decided to look at internal single pages rather than where the thing is actually registered.
softwallcave replied on at Permalink Reply
So yes, I was thinking that the built-in "none" theme had a corresponding built-in "none" package. Don't really know how that would be used otherwise, but in the end it did not matter.

Seems like the way to just override the output is to set the inner content file, which Concrete pays attention to because of legacy issues.

namespace Application\Controller\SinglePage\Events;
use Concrete\Core\Page\Controller\PageController;
use Concrete\Core\Foundation\Environment;
defined('C5_EXECUTE') or die("Access Denied.");
class ProcessStuff extends PageController {
   public function view() {
      $this->getViewObject()->setInnerContentFile(Environment::get()->getPath(DIRNAME_PAGES . '/events/process_stuff.php'));

And this displays only what is in the PHP file with no wrapper, doing what was so easy in pre-5.7+ versions.
JohntheFish replied on at Permalink Reply
Not sure exactly what you are looking for here. Perhaps it is a 'nothing' theme like my Themeless theme.
hutman replied on at Permalink Reply
You might look into creating a route with a corresponding class in the src directory. I believe this does require a package, but it might save you some time.
softwallcave replied on at Permalink Reply
Thanks. Looks like another option. What I have above also seems to work fine, and since the methods are declared as public, I presume it is OK to use them.
jasteele12 replied on at Permalink Reply
This can be so much simpler with a tools file. One of the first things I do on a new install is add this at the top of application/bootstrap/app.php:
<?php /* application/bootstrap/app.php */
    // fake legacy tools file functionality - John Steele
Route::register('/tools/{name}', function($name) {
    $name = trim($name);
    if ($name) {
        $file = 'application/tools/'. $name. '.php';
        if (file_exists($file)) {
            if (is_readable($file)) {
                include $file;
            } else {
                echo 'Tools file unreadable.';
        } else {
            echo 'No such tools file.';

Put any permission checking, etc. you want in application/tools/process_stuff.php and call like:

I use this all the time for cron jobs, quick one-offs, etc. Doesn't require multiple pages, package, registring. You just don't get versioning, but most of the time it doesn't matter

I'd love to see this added to the core, but since tools files have been "deprecated" (but still used by the core) I doubt it would happen if I made a PR :(