How to hide a single ajax page from the panel


i created an ajax page to filter my projects. This page is in the root folder of the content and is available over http://my-domain/ajax-projects?filter=sold for example.

Can i hide this single ajax page from the kirby panel? I dont want to confuse the user, because this page is only to provide ajax calls.

If you’re willing to modify the core files, you can do what I did…

Edit “panel/app/snippets/pages/sidebar/subpage.php” (add the wrapping if statement)

<?php if($subpage->hidepage() != 'true'): ?>
  <a class="draggable" data-helper="<?php echo esc($subpage->title(), 'attr') ?>" data-text="<?php echo esc(dragText($subpage), 'attr') ?>" href="<?php _u($subpage, 'show') ?>">
    <?php i($subpage) ?><span><?php __($subpage->title()) ?></span>
    <small class="marginalia shiv shiv-left shiv-white"><?php __(n($subpage)) ?></small>
<?php endif; ?>

Create a new hidepage field at “site/fields/hidepage/hidepage.php”


class HidepageField extends BaseField {

  public function template() {
    return new Brick('input', null, array(
      'type'  => 'hidepage',
      'name'  => $this->name(),
      'value' => $this->value()

  public function element() {
    if($this->hidepage) {


In the content file add “hidepage: true”

Title: Settings


Hidepage: true
1 Like

Or rethink how you act on the url and use a custom route instead.

If your ajax page has no modifiable content, then it probably shouldn’t be in the content folder at all.

Thank´s for your answers,

first of all, i don´t realy want to modify the core of kirby. This would cause conflicts when the next update comes up.

I like the way with the custom routes much more. But in the ajax.php i have to load the kirby system that i can use all the helper functions like snippet() and so on. Is there a recommended way to do that?

There is, yes, but it may be unnecessary. It’s hard to give specific advice without knowing what your script actually needs to do.

    require(__DIR__ . DS . 'kirby' . DS . 'bootstrap.php');
    $kirby = kirby();

Custom routes could be defined in your config file, though.

    c::set('routes', array(
            'pattern' => 'ajax-projects/(:any)',
            'action'  => function($filter) {
                // Use your filter as appropriate to produce a $data array
                return response::json($data);

I have to load a snippet in my ajax request. I solved it now on the following way:

c::set('routes', array(
        'pattern' => 'ajax-projekte(:all)',
        'action'  => function($filter) {
	         header('X-Robots-Tag: noindex, follow');
		 snippet('project.list', array('pages' => site()->pages()));

That´s much better than my previous solution with the template. Thank´s for inspiration.

1 Like

Don’t know if this is the right place for this post or not, but I’d also like to see a simple way to hide a content page from the panel.

I have a ‘show all deadlines’ page that has no editable content of its own, but draws upon the deadlines that are associated with other site content. I would rather not have this page show up in the panel so the client doesn’t get confused on where he has to add new deadlines, and am not sure how to get started with custom routes.

I was thinking something like the current feature where you can hide subpages in the blueprint with “hide: true,” but have this option for the page itself at the top level of it’s associated blueprint file.

Thank you.

If your page has no modifiable content, then it probably shouldn’t be in the content folder at all. Unfortunately, one of Kirby’s limitations is that there is a tight coupling between the content file and the template used if you don’t probe beyond basic usage.

However, the router is really very flexible. Like, seriously flexible. It’s crazy how flexible it is. It’s worth using the router instead of content files for this sort of basic stuff. You could even wrap this in a plugin instead of setting it via c::set('routes' ...) if you wanted to keep your config lean. The source code is your best documentation at this point and is well worth reading. Kirby is small enough to understand pretty readily.

c::set('routes', array(
        'pattern' => 'custom/route',
        'action'  => function() {
            // Grab your collection of pages, eg. $collection
            $data = array('collection' => $collection)
            tpl::$data = array_merge(tpl::$data, array(
                'kirby' => kirby(),
                'site'  => site(),
                'pages' => site()->children(),
            ), $data);
            tpl::load(kirby()->roots()->templates() . DS . 'template.php');
1 Like

Anyways. It would be nice to hide a specific page from the panel.
In my example I want to hide the error-page for my users.

Something like this for the blueprint would be super cool.

title: Error
hide: true

Thanks for the explanation. I need to update my Kirby settings so I get notified when there’s a response to an interesting thread!

I’ll definitely be looking into this.

On another thread someone mentioned using CSS:

.nav > li > [data-helper="Error"], .nav > li > [data-helper="Ajax-projects"] {
 display: none;
1 Like

That may or may not have been my advice. I’ve given it before but not sure if it was to you. :smile:

@bastianallgeier, @distantnative it seems the sought after solution of having a high level “hide” in blueprint that hides the page even from the panel listings. I posted a sample achieving this goal above, but I’m not sure it was the code was very Bastian like as is, since it’s not well integrated into the system but rather feels like a band aid. It seems like I’m not the only one waiting to see this as a core feature though and it doesn’t seem like it’d take long to add. Perhaps it could be added to the todo list at least.