Problems, need help? Have a tip or advice? Post it here.
6 posts Page 1 of 1
Lets say I have a clonable template called "posts.php". I can view it by going to mydomain.com/posts/folder1/mypost.html, or mydomain.com/posts/, or mydomain.com/posts/folder1/, etc. As usual.

Is there any way to make others templates inherit "posts.php", so that if I go to mydomain.com/mynewtemplate/folder1/mypost.html it shows the posts.php template data.

I tried with routes but unfortunately I can't make it work because there are so many variables. In my example there's only one folder but in a real world scenario there may be three or four, or more nested folders, it's a never ending task.

If you're wondering why am I asking this; to have two kinds of clonables templates, templates that store data, and templates that display it.
brunosa wrote: If you're wondering why am I asking this; to have two kinds of clonables templates, templates that store data, and templates that display it.

Could you, please, give an example? It is an interesting setup.
trendoman wrote:
brunosa wrote: If you're wondering why am I asking this; to have two kinds of clonables templates, templates that store data, and templates that display it.

Could you, please, give an example? It is an interesting setup.


----- PAGES
--- Home - /index.php (normal page)
--- Blog - /blog.php
--- Locations - /locations.php
--- Cars - /cars.php
--- Contact - /contact.php (normal page)

Those templates inherit the data from other template. Also, they can hold editables of their own, like if it was the globals tag.

----- DATA
--- Blog - couch/data-templates/blog.php
--- Car - couch/data-templates/car.php
--- Location - couch/data-templates/location.php

These are non-executable templates. They basically just store information.

I like the idea of having models/data on the one hand, and views on the other.

I've made a addon in order to accomplish it, it works fine for folders, lists and page views. I should work on creating a few new tags to generate the links, but hmm, I don't know I feel like it may cause problems or even limit some functions. As I said, it does the job, it's a solution, but I don't think it's a nice solution because there's so much I don't understand about the core functions yet. Can you guys give me your opinion or review the code?


Code: Select all
<?php

    if ( !defined('K_COUCH_DIR') ) die();


    class CustomRoutes{

        function __construct()
        {
            global $FUNCS;

           
            $FUNCS->add_event_listener( 'add_template_params', array($this, 'add_template_params'));
            $FUNCS->register_tag( 'inheritroute', array($this, 'process_route'), 1, 0 );
        }

        function process_route($params)
        {
            global $FUNCS, $CTX, $PAGE, $DB, $TAGS;

            if(!$PAGE->tpl_inherit)
            {
                $TAGS->abort($this->param('No inherit.') ,new KNode(K_NODE_TYPE_ROOT));
            }
           

            if( isset($_GET['pname']) && $FUNCS->is_title_clean($_GET['pname']))
            {
                $page_name = $_GET['pname'];
            }
            else if( isset($_GET['fname']) && $FUNCS->is_title_clean($_GET['fname']))
            {
                $folder_name = $_GET['fname'];
            }



            if($page_name)
            {
                $param = array (
                    0 => array ( 'lhs' => 'masterpage', 'op' => '=', 'rhs' => $PAGE->tpl_inherit, ),
                    1 => array ( 'lhs' => 'page_name', 'op' => '=', 'rhs' => $page_name, ),
                );

                $PAGES = $TAGS->pages($param, new KNode(K_NODE_TYPE_ROOT), 0);

                $K_COUNT = $CTX->get('k_count');


                if($K_COUNT == 0)
                {
                    $TAGS->abort($this->param('No page found') ,new KNode(K_NODE_TYPE_ROOT));
                }

                if($K_COUNT > 1)
                {
                    $TAGS->abort($this->param('Multiple found') ,new KNode(K_NODE_TYPE_ROOT));
                }

                if( K_PRETTY_URLS && $_SERVER['REQUEST_METHOD']!='POST' && !$PAGE->parent_id && $CTX->script!='404.php')
                {
                    $url = $FUNCS->get_url();
                    $targetUrl = $this->buildURL();

                    if($url)
                    {
                       if($url != $targetUrl)
                       {
                        header( "Location: ".$targetUrl, TRUE, 301 );
                        die();
                       }
                    }
                }


                foreach($CTX->ctx[2]["_scope_"] as $CTX_KEY => $CTX_VAL)
                {
                    $CTX->set($CTX_KEY, $CTX_VAL, 'global');
                }

            }
            else if($folder_name)
            {

                $param = array (
                    0 => array ( 'lhs' => 'masterpage', 'op' => '=', 'rhs' => $PAGE->tpl_inherit, ),
                    1 => array ( 'lhs' => 'root', 'op' => '=', 'rhs' => $folder_name, ),
                    2 => array ( 'lhs' => 'include_custom_fields', 'op' => '=', 'rhs' => 1, ),
                );

                $FOLDERS = $TAGS->folders($param, new KNode(K_NODE_TYPE_ROOT));

                $K_COUNT = $CTX->get('k_total_folders');


                if($K_COUNT == 0)
                {
                    $TAGS->abort($this->param('No folder found') ,new KNode(K_NODE_TYPE_ROOT));
                }

                if($K_COUNT > 1)
                {
                    $TAGS->abort($this->param('Multiple found') ,new KNode(K_NODE_TYPE_ROOT));
                }

                foreach($CTX->ctx[2]["_scope_"] as $CTX_KEY => $CTX_VAL)
                {
                    $CTX->set($CTX_KEY, $CTX_VAL, 'global');
                }

                $CTX->set('k_is_folder', 1, 'global');
            }
        }

        function buildURL()
        {
            global $PAGE, $FUNCS, $CTX;

            $inherit_name = K_SITE_URL.$FUNCS->get_pretty_template_link($PAGE->tpl_inherit);
            $page_name = K_SITE_URL.$FUNCS->get_pretty_template_link($PAGE->tpl_name);


            $url = $FUNCS->get_url();

            $original_url = $CTX->ctx[2]["_scope_"]["k_page_link"];



            $new_url = str_replace($inherit_name, $page_name, $original_url);
           

            return $new_url;
        }


        function param($value)
        {
            return array ( 0 => array ( 'lhs' => NULL, 'op' => '=', 'rhs' => "$value", ), );
        }


        function add_template_params(&$attr_custom, $params, $node)
        {
            global $FUNCS, $PAGE, $CTX;

            $attr = $FUNCS->get_named_vars(
                array(
                    'inherit'=>'',
                    ),
                $params
            );
            $attr['inherit'] = trim($attr['inherit']);


            $attr_custom = array_merge($attr_custom, $attr);

            $html="<cms:inheritroute '$PAGE->tpl_inherit' />";

            $parser = new KParser( $html, $node->line_num, 0, '', $node->ID );
            $dom = $parser->get_DOM();

            foreach( $dom->children as $child_node ){
                if( $child_node->type==K_NODE_TYPE_CODE ){
                $node->children[] = $child_node;
                }
            }
        }
    }

    $CR = new CustomRoutes();


Code: Select all
/cars.php

<?php require_once( 'couch/cms.php' ); ?>
<cms:template title='Cars' inherit="couch/data-templates/car.php">


</cms:template>



<cms:if k_is_page>
        is page
<cms:else/>
        <cms:if k_is_folder>
                folder
        <cms:else/>
                list
        </cms:if>
</cms:if>


<?php COUCH::invoke(K_IGNORE_CONTEXT); ?>

brunosa wrote: I like the idea of having models/data on the one hand, and views on the other.

Hi,

Could you, please, help me understand immediate benefits (in context of Couch, of course) of the above approach? I always imagined templates hold the data in backend and views are handled by snippets via cms:smart_embed - my sample 'users' template -

Code: Select all
<?php require_once( 'couch/cms.php' ); ?>
<cms:template title='Users' clonable='1' executable='1' order='0100' icon='people'>
    <cms:smart_embed 'template_editables' />
    <cms:smart_embed 'template_routes' />
</cms:template><cms:set my_debug='0' /><cms:ignore>

    // Users template
    // List users publicly

</cms:ignore>
<cms:smart_embed debug=my_debug 'html_afore' />
<!DOCTYPE html>
<html lang="<cms:show k_lang />">
    <cms:smart_embed debug=my_debug 'html_headers' />
<body>
    <cms:smart_embed debug=my_debug 'html_hero' />
    <cms:smart_embed debug=my_debug 'html_master' />
    <cms:smart_embed debug=my_debug 'html_trail' />
</body>
</html>
<?php COUCH::invoke();  ?>
<?php //COUCH::invoke( K_IGNORE_CONTEXT ); ?>


I modded smart-embed tag, so it supports language codes and the list of snippet names it looks for (possible views) for a page-view is like this -
Code: Select all
    en-users-page-admin
    en-users-page
    en-users-default
    en-users
    en-page-admin
    en-page
    en-default
    users-page-admin
    users-page
    users-default
    users
    page-admin
    page
    default


What you do is maybe useful (I would like to know more about it) but imagine a webapp with 50-60 templates - many will have data-duplicates then in your approach?

(!) I suspect you were initially trying to solve some other problem and eventually decided to split things in backend. Could you maybe share also what was the first desire that you couldn't see a solution to immediately?

P.S. Not to forget, there is another great approach for building an hierarchy of views - viewtopic.php?f=5&t=10984#p28250 - meet cms:block and cms:extends tags.
Originally the idea was to have two kind of templates; display data, store data.

These templates that store data are basically models.

couch/models/user.php
It's a non-executable clonable template with all the editables. It just stores data.

Then in the front-end you could have a template that displays the data of the model.

/users.php - inherits the couch/models/user.php data
It's a non clonable template. It has its own editables that, lets say, allows the admin to select how the user data is going to be displayed.

You could have another template called /members.php that works exactly like /users.php but it has another name. It's a cool a idea to have everything clean. Models on the one hand and templates on the other. Kind of like MVC (without controllers :lol:).

Anyway, I ended up not using this approach. Although it is a type of workflow that I like, it only makes things harder to accomplish in some cases, the end product it's just messy and I'm not sure it's even worth the effort.

Instead of using this approach to accomplish what I wanted I decided to go for the globals tag: listing each edit-globals page of each clonable template in the admin sidebar with an addon.

It's not the same but I'm happy with it.
brunosa wrote: allows the admin to select how the user data is going to be displayed

In practise, what does your admin selects?
6 posts Page 1 of 1