main.php

<?php
/** template originally developed on jan 20, 2022
 * @param \Phad $phad an object that handles the callback methods in the template. Can be any type, if you wish to change it from `\Phad`
 */


/* @@if1.start.route_info */
//these two blocks for route & sitemap are not actually used 
// ugh ... i am manually inserting the code instead ...
// idk why, it's just what i did
if ($phad_block==\Phad\Blocks::ROUTE_META){
    return @$$route_info; # route info gets passed into the template
}
/* @@end.route_info */

/* @@if1.start.sitemap_info */
//this code is literally never included (feb 1, 2022) ... see note on route_info above
if ($phad_block==\Phad\Blocks::SITEMAP_META){
    return @$$sitemap_info;
}
/* @@end.sitemap_info */

## becomes $BlogInfo
@$$ItemInfo = new \Phad\ItemInfo(
    name: '/* @@item_name */', //becomes Blog
    mode:$phad_block,
    apis: @$$apis, //rawdata generally json. could be sql or csv though
    type:'/* @@item_type */', //just view or form at this point
    args:$args, 
    data_index:false,
    data_nodes: @$$DataNodes, // each contains access="role:admin" & sql="Select * ...", etc
    response_code: false, // could start as 500?
    rows:[], // could start null/false?
    errors:[], // just gets appended to by whatever when there's a problem
    submit_errors:[],
    /* @@candelete */
    /* @@diddelete */
    /* @@cansubmit */
    /* @@FormTarget */
);

/* @@start.form_properties */
@$$ItemInfo->properties = 
    @$$form_properties_array;

/* @@end.form_properties */

$phad->access->item_initialized(@$$ItemInfo);


/* @@start.form_is_candelete */
if ($phad_block == \Phad\Blocks::FORM_DELETE){
    if ($phad->can_delete(@$$ItemInfo)){
        /* @@form_will_delete */
        $did_delete = $phad->delete(@$$ItemInfo);
        if ($did_delete){
            /* @@form_did_delete */
            $phad->did_delete(@$$ItemInfo);
            return;
        }
    }
}
/* @@end.form_is_candelete */


if ($phad_block==\Phad\Blocks::ITEM_META){
    return @$$ItemInfo;
}

foreach (@$$ItemInfo->data_nodes as $_next_index=>&$_next_node){

    unset($_node);

    if (isset($args[':data'])
        &&  (!isset($_next_node['name'])
                ||$args[':data'] !== $_next_node['name']
            )
    ){
        $_next_node['was_processed'] = false;
        continue;
    }

    if (isset($_next_node['if'])){
        $eval_code = 'return ('.$_next_node['if'].');';
        $result = eval($eval_code);
        if ($result !== true){
            $_next_node['was_processed'] = false;
            continue;
        }
    }

    $_index = $_next_index;
    $_node = &$_next_node;
    unset($_next_node);

    $_node['was_processed'] = true;

    if (!$phad->can_read_data($_node, @$$ItemInfo)){
        @$$ItemInfo->response_code = 403;
        $_node['response_code'] = 403;
        continue;
    }
    // may include getting $args['Blog'] or $args['BlogList'] instead of using a query
    @$$ItemInfo->rows = $phad->read_data($_node, @$$ItemInfo);
    if (count(@$$ItemInfo->rows)==0){
        @$$ItemInfo->response_code = 404;
        $_node['response_code'] = 404;
        continue;
    }
    @$$ItemInfo->response_code = 200;
    $_node['response_code'] = 200;
    @$$ItemInfo->data_index = $_index;
    break;
}

if ($phad_block == \Phad\Blocks::ITEM_DATA){
    // does not handle nested items. I'm okay with that, for now ... i can always make separate item views
    return $phad->get_rows(@$$ItemInfo);
}


/* @@start.status_codes */
if (@$$ItemInfo->response_code == 200){
    /* @@code_for_response_200 */
} else if (@$$ItemInfo->response_code !== false){

    $_statuses_processed = [];
    foreach (@$$ItemInfo->data_nodes as $_index=>$_node){
        if (!isset($_node['was_processed'])
            ||$_node['was_processed']==false){
            continue;
        }
        /* @@if2.start.response_code_403 */
        if ($_node['response_code'] == 403){
            /* @@code_for_response_403 */
        }
        /* @@end.response_code_403 */
        /* @@if2.start.response_code_404 */
        if ($_node['response_code'] == 404){
            /* @@code_for_response_404 */
        }
        /* @@end.response_code_404 */
        /* @@if2.start.response_code_500 */
        if ($_node['response_code'] == 500 ){
            /* @@code_for_response_500 */
        }
        /* @@end.response_code_500 */


        $_statuses_processed[$_node['response_code']] = true;
    }
}
/* @@end.status_codes */

if (count(@$$ItemInfo->rows)===0){
    $phad->no_rows_loaded(@$$ItemInfo);
}

foreach (@$$ItemInfo->rows as $RowIndex_/* @@ItemForeach */ ): 
    /* @@start.not_a_form */
        @$$ItemName = $phad->object_from_row(@$$Item_Row, @$$ItemInfo);
    /* @@end.not_a_form */
    /* @@start.form_submit */
        if (@$$ItemInfo->mode == \Phad\Blocks::FORM_SUBMIT){
            $this->enable_filtering = false;
            // data originates from POST
            @$$ItemName = $phad->object_from_submission(@$$Item_Row, @$$ItemInfo);
            // <onwillsubmit> code goes here. Set `@$$ItemInfo->mode = null` to stop submission & display the form.
            /* @@form_on_submit */
            $phad->onSubmit(@$$ItemInfo, @$$Item_Row);
            if ($phad->can_submit(@$$ItemInfo, @$$Item_Row)
                &&$phad->is_submission_valid(@$$ItemInfo, @$$Item_Row)
                &&$phad->submit(@$$ItemInfo, @$$Item_Row)
            ){
                // <ondidsubmit> goes here
                /* @@form_did_submit */
                $phad->redirect(@$$ItemInfo,@$$Item_Row);
                return;
            } else {
                // <onfailsubmit> code goes here
                /* @@form_fail_submit */
            }
            $args['@$$ItemInfoSubmitErrorsList'] = @$$ItemInfo->submit_errors;

        } else {
            $this->enable_filtering = true;
            // data was loaded from data nodes, because this request is not a submission
            @$$ItemName = $phad->object_from_row(@$$Item_Row, @$$ItemInfo);
        }
    /* @@end.form_submit */
    ?>/* @@html_code */<?php
endforeach;

?>