简体   繁体   中英

How To Get Twig Template Engine Header Tags in PHP Function

I am trying to extend a Pico navigation plugin to exclude items from the navigation tree where the page's utilizes Twig template engine header tags.

My question is how do I get specific header tags from the .md files in the below PHP function and filter them to be excluded in the navigation tree?

The plugin currently implements the ability to omit items (pages and folders) from the tree with the following settings in a config.php file:

//  Exclude pages and/or folders from navigation header
$config['navigation']['hide_page'] = array('a Title', 'another Title');
$config['navigation']['hide_folder'] = array('a folder', 'another folder');

The current function in the plugs' file uses the above config.php as follows:

private function at_exclude($page) {

    $exclude = $this->settings['navigation'];
    $url = substr($page['url'], strlen($this->settings['base_url'])+1);
    $url = (substr($url, -1) == '/') ? $url : $url.'/';

    foreach ($exclude['hide_page'] as $p) {

        $p = (substr($p, -1*strlen('index')) == 'index') ? substr($p, 0, -1*strlen('index')) : $p;
        $p = (substr($p, -1) == '/') ? $p : $p.'/';

        if ($url == $p) {
            return true;
        }
    }

    foreach ($exclude['hide_folder'] as $f) {

        $f = (substr($f, -1) == '/') ? $f : $f.'/';
        $is_index = ($f == '' || $f == '/') ? true : false;

        if (substr($url, 0, strlen($f)) == $f || $is_index) {
            return true;
        }
    }
    return false;
}

I need to add the ability of omitting items (or pages) from the tree using the Twig header tags 'Type' and 'Status' like so in the .md files:

/*
Title: Post01 In Cat01
Description: This post01 in cat01
Date: 2013-10-28
Category:
Type: post      // Options: page, post, event, hidden
Status: draft   // Options: published, draft, review
Author: Me
Template: 
*/
...
The MarkDown content . . .

So if a user wants to remove items tagged with "post" in the 'type' tag and/or "draft" from the 'draft' tag (see header above), they would then add the linked tags in the array below that I added into the config.php:

//  Exclude taged items:
$config['navigation']['hide_status'] = array('draft', 'maybe some other status tag');
$config['navigation']['hide_type'] = array('post', 'etc');

I also added the following to the bottom of the at_exclude() function:

private function at_exclude($page) {
. . .
    foreach ($exclude['hide_staus'] as $s) {

        $s = $headers['status'];

        if ($s == 'draft' || 'review') {
            return true;
        }
    }

    foreach ($exclude['hide_type'] as $t) {

        $t = $headers['type'];

        if ($t == 'post' || 'hidden') {
            return true;
    }

    return true;
}
. . .

This is obviously not working for me (because my PHP knowledge is limited). Any help with what I am missing, doing wrong or how I can add this functionality will be greatly appreciated.

I dived into the (not so beautiful) Pico code and those are my findings.

First of all, Pico doesn't read every custom field you add to the content header. Instead, it has an internal array of fields to parse. Luckily, an hook called before_read_file_meta is provided to modify the array. In at_navigation.php we'll add:

/**
 * Hook to add custom file meta to the array of fields that Pico will read
 */
public function before_read_file_meta(&$headers)
{
    $headers['status'] = 'Status';
    $headers['type'] = 'Type';
}

This will result in Pico reading the headers, but it won't add the fields to the page data yet. We need another hook, get_page_data. In the same file:

/**
 * Hook to add the custom fields to the page data
 */
public function get_page_data(&$data, $page_meta)
{
    $data['status'] = isset($page_meta['status']) ? $page_meta['status'] : '';
    $data['type'] = isset($page_meta['type']) ? $page_meta['type'] : '';
}

Now, in the at_exclude function, we can add the new logic. (Instead of cycling, We configure an array of status and types we want to exclude, and we'll check if there is a match with the current page status/type)

private function at_exclude($page)
{
    [...]
    if(in_array($page['status'], $exclude['status']))
    {
        return true;
    }

    if(in_array($page['type'], $exclude['type']))
    {
        return true;
    };

    return false;
}

Now let's customize our config.php (I standardized the configuration with the plugin standards):

$config['at_navigation']['exclude']['status'] = array('draft', 'review');
$config['at_navigation']['exclude']['type'] = array('post');

All done!
But if you are just starting out, I'd advise you to use a more mature and recent flat file cms. Unless you are stuck with PHP5.3

I decided to simplify the function to omit it from the config.php since it really isn't needed to be set by the end-user. By doing so, the at_exclude() function is much simpler and quicker on the back-end by omitting all the checks via other files:

at_exclude {

  . . .

    $pt = $page['type'];
    $ps = $page['status'];

    $home = ($pt == "home");
    $post = ($pt == "post");
    $event = ($pt == "event");
    $hide = ($pt == "hide");

    $draft = ($ps == "draft");
    $review = ($ps == "review");

    $type = $home || $post || $event || $hide;
    $status = $draft || $review;

    if ( $type || $status ) {
        return true;
    };

    return false;
}

Obviously it needs some tidying up but you get the picture. Thnx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM