Basically my Idea was to do routes like.../directory
-> display a list of all countries that are assigned to a user (data is available)/directory/{country}/
-> display a list of all users within that country/directory/{country}/{city}
-> display a list of all users within that city
in my DirectoryController I wanted to have one view with different outputs dependent on the country or city
Hi @jennifer.eberlei_gitlab ,
What Calvin said is right - there are 3 main groups of routes that are supported in WP Emerge - Web (front end if you will), Admin (under /wp-admin/) and AJAX (handled via WordPress' AJAX hooks).
For your use case (and most) web.php is the file to use so you'd want to place \Racom::route()->get()->url( '/verzeichnis/{country?}/{city?}' )->handle( 'DirectoryController@index' );
in that file but above the \Racom::route()->all();
line as the comment warns.
Ok how do I check that country is actually a country and city is actually a city
This type of validation you can do inside your controller method, so something like this is what I imagine you'd need:
// Note that URL parameters are automatically passed to your controller method as extra arguments.
// You can check out the docs which mention this here: https://docs.wpemerge.com/#/framework/routing/conditions?id=url
public function index( $request, $view, $country, $city ) {
// Assuming you have an is_city_valid() function:
if ( ! empty( $city ) && ! is_city_valid( $city ) ) {
return \Racom::error( 404 );
}
// Assuming you have an is_country_valid() function:
if ( ! empty( $country ) && ! is_country_valid( $country ) ) {
return \Racom::error( 404 );
}
// Assuming you'll need both $country and $city in your view:
return \Racom::view( 'templates/directory/index.php' )
->with( [
'country' => $country,
'city' => $city,
] );
}
So I created a folder templates
in the root folder of the theme and a subfolder called directory
and then in my route I want to do this like suggested:
return \Racom::view( 'templates/directory/index.php' )
->with( [
'country' => $country,
'city' => $city,
] );
but when I var_dump
$view in my route it still gives me the 404 template.
class DirectoryController {
public function index( $request, $view, $country, $city ) {
var_dump($view);
var_dump($country);
if (!empty($country) && !is_country_valid($country)) {
return \Racom::error(404);
}
return \Racom::view( 'templates/directory/index.php' )->with(['country' => $country, 'city' => $city]);
}
}
@atanas-dev Could you explain a use case for an admin route? I always thought what happens is that you could override the callback function defined in add_menu_page for a specific admin page. However, after studying the code this it seems like this is not the case but instead we send headers from the request and the body from or view (if there is any view loaded ) straight to the client. When I tried some routes it seems like nothing is happening at all. (Might be because WordPress still loads the default admin view. )
Maybe I'm not getting the admin routes quite right. Hope you can share some insights.
Admin routes check for the registered page slug. The request is then split - headers are sent during do_action( "load-{$hook_suffix}" )
and the view is output during do_action( $hook_suffix )
where $hook_suffix is a hook name that WordPress generates based on your admin page slug.
The above means that headers will be sent correctly before any output and your view will be embedded inside the default admin page (where the usual add_menu_page callback runs).
An important note: Admin routes are currently only meant to be used with custom admin pages i.e. ones registered using add_menu_page and add_submenu_page, not core admin pages.
Ah ok got it, so the do_action( $hook_suffix )
takes care of the placing the content in the correct place I assume.
Btw, is there any reason that im missing for why admin/ajax handlers do need to get passed a $view variable. Its always empty since only the "web function" inside the kernel passes the view as an optional argument to the handle method.
got it. I'll strip it out in the container implementation since every controller, middleware, etc gets resolved automatically.
Another thing, is there a way we could allow for the extension of the error handler in a custom service provider?
So far there are only CsrfException and NotFoundException that we can catch when we push something through the HTTP-Kernal process
protected function toResponse( $exception ) {
// @codeCoverageIgnoreStart
if ( $exception instanceof InvalidCsrfTokenException ) {
wp_nonce_ays( '' );
}
// @codeCoverageIgnoreEnd
if ( $exception instanceof NotFoundException ) {
return $this->response_service->error( 404 );
}
return false;
}
Hey there, if I wanted to add acf to wpemerge, would i do that with its own service provider? would that make sense?
I was thinking that widgets, and sidebars, and menus and such are provided via a service provider so I was wondering if it would make sense to do the same for registering custom fields with acf
Hi, I tried to add woocommerce styles to the theme seperately from admin|frontend|login
and edited the config.json
and the AssetsServiceProvider.php
like this:
config.json
"bundles": [
"frontend",
"admin",
"login",
"editor",
"woocommerce"
],
AssetsServiceProvider.php:
/**
* Enqueue woocommerce assets.
*
* @return void
*/
public function enqueueWoocommerceAssets() {
// Enqueue scripts.
\Racom::core()->assets()->enqueueScript(
'theme-woocommerce-js-bundle',
\Racom::core()->assets()->getBundleUrl( 'woocommerce', '.js' ),
[ 'jquery' ],
true
);
// Enqueue styles.
$style = \Racom::core()->assets()->getBundleUrl( 'woocommerce', '.css' );
if ( $style ) {
\Racom::core()->assets()->enqueueStyle(
'theme-woocommerce-css-bundle',
$style
);
}
// Enqueue theme's style.css file to allow overrides for the bundled styles.
\Racom::core()->assets()->enqueueStyle( 'theme-woocommerce-styles', get_template_directory_uri() . '/woocommerce.css' );
}
ressources/styles/woocommerce/index.scss
@atanas-dev Great work and thanks a lot for the framework. Looking forward to use it on my projects. Can somebody help me with why I am getting "Unknown named parameter $post_id" when post_id has been matched in web.php? Same for post_slug, post_status...
Error thrown with message "Unknown named parameter $post_id"
#20 Error in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:177
#19 call_user_func_array in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:177
#18 WPEmerge\Kernels\HttpKernel:executeHandler in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:205
#17 WPEmerge\Kernels\HttpKernel:WPEmerge\Kernels\{closure} in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:40
#16 WPEmerge\Kernels\HttpKernel:executeMiddleware in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:44
#15 WPEmerge\Kernels\HttpKernel:WPEmerge\Middleware\{closure} in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Input/OldInputMiddleware.php:44
#14 WPEmerge\Input\OldInputMiddleware:handle in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:53
#13 call_user_func_array in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:53
#12 WPEmerge\Kernels\HttpKernel:executeMiddleware in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:44
#11 WPEmerge\Kernels\HttpKernel:WPEmerge\Middleware\{closure} in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Flash/FlashMiddleware.php:40
#10 WPEmerge\Flash\FlashMiddleware:handle in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:53
#9 call_user_func_array in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:53
#8 WPEmerge\Kernels\HttpKernel:executeMiddleware in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:206
#7 WPEmerge\Kernels\HttpKernel:run in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:237
#6 WPEmerge\Kernels\HttpKernel:handle in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:332
#5 WPEmerge\Kernels\HttpKernel:filterTemplateInclude in /Users/banestojanovic/Code/Manastiri/podmaine/wp-includes/class-wp-hook.php:292
#4 WP_Hook:apply_filters in /Users/banestojanovic/Code/Manastiri/podmaine/wp-includes/plugin.php:212
#3 apply_filters in /Users/banestojanovic/Code/Manastiri/podmaine/wp-includes/template-loader.php:104
#2 require_once in /Users/banestojanovic/Code/Manastiri/podmaine/wp-blog-header.php:19
#1 require in /Users/banestojanovic/Code/Manastiri/podmaine/index.php:17
#0 require in /Users/banestojanovic/.composer/vendor/laravel/valet/server.php:219
@atanas-dev Hello Atanas, I can't get JSON responses to work for web request. The header is always empty. I debugged the entire HTTP Kernel.
For example:
App::json(['foo' => 'bar'])
renders correctly in the browser. But the header is empty. Ie content type is not set to application/json altought the kernel supposedly called `sentHeaders()``
add_menu_page
// This will not work
add_menu_page( 'test', 'test' , 'manage_options', 'test' );
// Forth parameter is optional in Wordpress but its needed to work correctly
add_menu_page( 'test', 'test' , 'manage_options','test', function () {
// Nothing.
});