Brain-WP / Cortex

Routing system for WordPress
MIT License
348 stars 20 forks source link

Preserving variables? #20

Closed jonathanstegall closed 7 years ago

jonathanstegall commented 7 years ago

I'm trying to find out if it's possible to preserve some variables for reuse and automation. My goal is to allow a certain type of widget to create a route for each instance, using that widget's settings.

Example:

$widget_instances = get_option( 'widget_mywidgetname', false );

foreach ( $widget_instances as $instance ) {
    $title = sanitize_title( $instance['title'] ); // use widget slug as url
    $routes->addRoute( new QueryRoute(
        $title,
        function( array $matches ) {
            $instances = array_values($widget_instances);

            $value = $instance['title']; // use widget title as a way to find the query
            $key = array_search( $value, array_column( $instances, 'title' ), true );
            $match = $instances[$key];

            $query = array(
                'post_type' => 'post',
                'tax_query' => array(
                    'relation' => 'OR',
                    array(
                        'taxonomy' => 'category',
                        'field' => 'term_id',
                        'terms' => $match['widget_categories'],
                    ),
                    array(
                        'taxonomy' => 'post_tag',
                        'field' => 'name',
                        'terms' => explode( ',', $match['widget_terms'] ),
                    ),
                )
            );

            return $query;
        },
        ['template' => 'template.php']
    ));
}

This currently doesn't work because the $value is unknown inside the function(array $matches ) { line. Having a bit of trouble thinking of a way to preserve it from the foreach.

I'm also interested in whether that $value url could be passed to the template.php file itself, so that template could be used for all the routes being created, and display the correct title from the widget.

I realize this might be a weird use case, but I'm curious about its feasibility.

jonathanstegall commented 7 years ago

I think I've found a decent fix for this.

$widget_instances = get_option( 'widget_mywidgetname', false );
$instances = array_values( $widget_instances );

foreach ( $widget_instances as $instance ) {

    $title = sanitize_title( $instance['title'] );
    add_filter( 'get_the_archive_title', array( $this, 'set_wp_title' ) );
    add_filter( 'pre_get_document_title', array( $this, 'set_wp_title' ) );

    $key = array_search( $instance['title'], array_column( $instances, 'title' ), true );
    $match = $instances[$key];
    $query = array(
        'post_type' => 'post',
        'tax_query' => array(
            'relation' => 'OR',
        )
    );
    if ( ! empty( $match['widget_categories'] ) ) {
        $query['tax_query'][] = array(
            'taxonomy' => 'category',
            'field' => 'term_id',
            'terms' => $match['widget_categories'],
        );
    }
    if ( ! empty( $match['widget_terms'] ) ) {
        if ( ! is_array ( $match['widget_terms'] ) ) {
            $widget_terms = explode( ',', $match['widget_terms'] );
        } else {
            $widget_terms = $match['widget_terms'];
        }
        $query['tax_query'][] = array(
            'taxonomy' => 'post_tag',
            'field' => 'name',
            'terms' => $widget_terms
        );
    }
    $routes->addRoute( new QueryRoute(
        $title,
        $query,
        ['template' => 'template.php']
    ));
}