Better URL formatting with Custom Post Types and Taxonomies - .htaccess

I'm using Toolset Types and wondering how easy it is to set up the URL's how I want.
I have a custom post type of venues and I have a custom category taxonomy of location.
Currently the urls are coming out like
http://domain.com/venue/location/manchester/
http://domain.com/venue/manchester/the-venue-name/
But I want the URL's to be structured like
http://domain.com/manchester/
http://domain.com/manchester/the-venue-name/
Where do I need to look to make these changes?
Is this all .htaccess work or can something be done within the permalinks section?
Thanks in advance

If i understand right, this hack must work in your template.
First of all we have to remove the Post type name from url Slug.
function ft_remove_postType_slug_fromUrl( $post_link, $post, $leavename ) {
if ( 'venue' != $post->post_type || 'publish' != $post->post_status ) {
return $post_link;
}
$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
return $post_link;
}
add_filter( 'post_type_link', 'ft_remove_postType_slug_fromUrl', 10, 3 );
But this is not gonna work by itself. If u pate this code in your functions.php u should get 404 Error.Bbecause WordPress only expects posts and pages to behave this way.
So, you have to add this action also.
function ft_change_parsingRequest( $query ) {
if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
return;
}
if ( ! empty( $query->query['name'] ) ) {
$query->set( 'post_type', array( 'post', 'venue', 'page' ) );
}
}
add_action( 'pre_get_posts', 'ft_change_parsingRequest' );
After this, you renew / refresh yours post type / permalink tree (It calls flush_rewrites i guess.), It means, re-update your permalink settings on your admin panel area.
Or if you want to see or do some magic, you can check it out from source url.
https://core.trac.wordpress.org/browser/tags/4.3/src/wp-includes/post.php#L1454
This Line says;
add_permastruct( $post_type, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args );
Happy Coding.

Related

How to show primary menu of main site throughout multi-site network

I have managed to switch the primiary navigation menu of my subsites to show the main site primary navigation.
However, it renders above the site-header instead of in the menu location dictated in the code.
Here is the code I currently have:
function wp_multisite_nav_menu() {
global $blog_id;
}
if ( ! is_multisite() || 2 == $blog_id ) {
switch_to_blog( 1 );
wp_nav_menu( array(
'menu' => 2,
'fallback_cb' => false,
'menu_class' => 'genesis-nav-menu',
'theme_location' => 'Primary Navigation Menu',
));
restore_current_blog();
}
I was expecting the menu to be placed in the 'Primary Navigation Menu' location.
What have I missed?
Any clarity is appreciated.
UPDATE
I managed to figure it out for my primary and secondary menus however how do get the site title to change to the main site title and hyperlink?
Here is the code I currently have minus the site title switch
//*Multisite global menus
//*Primary global menu
add_action('genesis_after_header', 'primary_menu_switch');
function primary_menu_switch() {
global $blog_id;
if ( ! is_multisite() || 2 == $blog_id ) {
switch_to_blog( 1 );
wp_nav_menu( array(
'menu' => 2,
'fallback_cb' => false,
'menu_class' => 'genesis-nav-menu',
'theme_location' => 'primary'
) );
restore_current_blog();
}
}
//*Secondary global menu
add_action('genesis_header_right', 'secondary_menu_switch');
function secondary_menu_switch() {
global $blog_id;
if ( ! is_multisite() || 2 == $blog_id ) {
switch_to_blog( 1 );
wp_nav_menu( array(
'menu' => 17,
'fallback_cb' => false,
'menu_class' => 'genesis-nav-menu menu-primary responsive-menu',
'theme_location' => 'primary'
));
restore_current_blog();
}
}
//*Use main site title
function site_title_switch() {
global $blog_id;
if ( ! is_multisite() || 2 == $blog_id ) {
switch_to_blog( 1 );
restore_current_blog();
}
}
I am a complete novice so please excuse the hack job.
Your insights are appreciated.
This is an answer to the updated question, not the one in the title.
This should do the trick, if you put it in a network activated plugin. Read the comments to see what it does exactly. It might not work depending on how your theme is made. I made it for the Twenty Eleven theme.
Keep in mind that it will change the home URL everywhere where it is called with a path '/', not only in the header.
add_filter( 'option_blogname', 'function_to_filter_the_blogname' );
// Changes the blog name of all sites that are not the main one to the name of the main one, only outside of the admin panel
function function_to_filter_the_blogname( $name ) {
$main_site_id = get_main_site_id();
if ( get_current_blog_id() != $main_site_id && ! is_admin() ) {
return get_blog_option( $main_site_id, 'blogname' );
}
return $name;
}
add_filter( 'home_url', 'function_to_filter_the_home_url', 10, 4 );
// Changes the home URL of all sites that are not the main one to the home URL of the main one, only outside of the admin panel and only when the path is '/'
function function_to_filter_the_home_url( $url, $path, $orig_scheme, $blog_id ) {
$main_site_id = get_main_site_id();
if ( $blog_id != $main_site_id && ! is_admin() && '/' == $path ) {
return get_blog_option( $main_site_id, 'home' );
}
return $url;
}

Show only authors post except a single post ID

I am working with Wordpress, and I have a post type using ACF fields.
The fact is that I used a function in function.php to show only author's posts but I completely forgot that It wont show the ACFgroupfields
Here is my function
function posts_for_current_author($query) {
global $user_level;
if($query->is_admin && $user_level < 5) {
global $user_ID;
$query->set('author', $user_ID);
unset($user_ID);
}
unset($user_level);
return $query;
}
add_filter('pre_get_posts', 'posts_for_current_author');
How to make an exception for an ID for a post ?
Thank you very much !
Might be a bit late to respond to this. But what you could try is something like this.
add_action( 'pre_get_posts', 'pre_check', 10, 2);
function pre_check($query) {
global $user_ID;
if ( !current_user_can( 'edit_others_posts' ) && $query->query['post_type'] != 'acf-field-group' && $query->query['post_type'] != 'acf-field') {
$query->set('author', $user_ID);
}
return $query;
}
This way it will not list posts/pages other than what belongs to the author. And still display the ACF fields on the posts/pages itself.

How to insert text on post link Wordpress?

only post link current: http://mydomain/post-name
I want change only post link : http://mydomain/blog/post-name
In the permalink page (Settings > Permalinks), select the last option to enter a custom permalink structure and enter this :
/blog/%postname%/
It will prepend all your post urls with /blog/.
UPDATE
To prefix posts only, use the following function in your functions.php :
function add_rewrite_rules( $wp_rewrite )
{
$new_rules = array(
'blog/(.+?)/?$' => 'index.php?post_type=post&name='. $wp_rewrite->preg_index(1),
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules');
function change_blog_links($post_link, $id=0)
{
$post = get_post($id);
if( is_object($post) && $post->post_type == 'post'){
return home_url('/blog/'. $post->post_name.'/');
}
return $post_link;
}
add_filter('post_link', 'change_blog_links', 1, 3);

Show latest posts from each custom post type with pre_get_posts

What I have
On my front page I have managed to alter the main query on the front page to show my custom post types with "pre_get_posts" like this:
function custom_post_types_in_home_loop( $query ) {
if ( ! is_admin() && is_home() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'member', 'press', 'calendar_event' ) );
}
return $query;
}
add_filter( 'pre_get_posts', 'custom_post_types_in_home_loop' );
What I want
The problem is that some post types have way more posts than others, so I want to show only 3 posts per post type to get a little variation in the loop.
What I've tried
With some help from this and this answer ive managed to do this but nothing's happening, what am I doing wrong?
function custom_post_types_in_home_loop( $query ) {
if ( ! is_admin() && is_home() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'member', 'press', 'calendar_event' ) );
if ( $query->get( 'post_type' ) == 'member' ) {
$query->set('posts_per_page', 3);
}
/* And the same 'if' statement for 'press' and 'calendar_event' */
}
return $query;
}
add_filter( 'pre_get_posts', 'custom_post_types_in_home_loop' );
You are setting post_type on the main query to an array. And then comparing it against a string. None of these conditionals are true and hence aren't executing.
If you simply want to limit the number of queries and pick a random order you can do so with,
$query->set('posts_per_page', 9);
$query->set('orderby', 'rand);
This will give you 9 posts, 3 each, randomly choosen between the different Custom Post Types.
To keep the different types together, you'll need to build a more complex and resource intensive groupby query. If you need this, I'd suggest building 3 different Custom Loops for each post_type instead.

Magento: Browser detection to load right language

How do I implement a browser detection into Magento to load the right language.
Example:
If a US User is surfing to my Magento shop, Magento should load the path: ..myshop../usa/
usa=storecode
If a japanese User is surfing to my Magento shop, Magento should load the path: ..myshop../jp/
jp=storecode
and so on
I guess I have to adapt the .htaccess with rewrite Urls, but I never did that before. How do I have to do it?
How does the code of browser detection look like and where do I have to put it? In the header.phtml?
thank you very very much in advance!
Edit:
index.php in CE 1.7.0.2 looks like this
/**
* Error reporting
*/
error_reporting(E_ALL | E_STRICT);
/**
* Compilation includes configuration file
*/
define('MAGENTO_ROOT', getcwd());
$compilerConfig = MAGENTO_ROOT . '/includes/config.php';
if (file_exists($compilerConfig)) {
include $compilerConfig;
}
$mageFilename = MAGENTO_ROOT . '/app/Mage.php';
$maintenanceFile = 'maintenance.flag';
if (!file_exists($mageFilename)) {
if (is_dir('downloader')) {
header("Location: downloader");
} else {
echo $mageFilename." was not found";
}
exit;
}
if (file_exists($maintenanceFile)) {
include_once dirname(__FILE__) . '/errors/503.php';
exit;
}
require_once $mageFilename;
#Varien_Profiler::enable();
if (isset($_SERVER['MAGE_IS_DEVELOPER_MODE'])) {
Mage::setIsDeveloperMode(true);
}
#ini_set('display_errors', 1);
umask(0);
/* Store or website code */
$mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
/* Run store or run website */
$mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
Mage::run($mageRunCode, $mageRunType);
But this Link describes the follwing code which you cannot simply replace:
require_once 'app/Mage.php';
/* Determine correct language store based on browser */
function getStoreForLanguage()
{
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
foreach (explode(",", strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])) as $accept) {
if (preg_match("!([a-z-]+)(;q=([0-9.]+))?!", trim($accept), $found)) {
$langs[] = $found[1];
$quality[] = (isset($found[3]) ? (float) $found[3] : 1.0);
}
}
// Order the codes by quality
array_multisort($quality, SORT_NUMERIC, SORT_DESC, $langs);
// get list of stores and use the store code for the key
$stores = Mage::app()->getStores(false, true);
// iterate through languages found in the accept-language header
foreach ($langs as $lang) {
$lang = substr($lang,0,2);
if (isset($stores[$lang]) && $stores[$lang]->getIsActive()) return $stores[$lang];
}
}
return Mage::app()->getStore();
}
/* Auto redirect to language store view if request is for root */
if ($_SERVER['REQUEST_URI'] === '/') {
header('Location: '.getStoreForLanguage()->getBaseUrl());
exit;
}
#Varien_Profiler::enable();
#Mage::setIsDeveloperMode(true);
#ini_set('display_errors', 1);
umask(0);
Mage::run();
Can anybody help me to find out where to put it or where to adapt the index.php
Thank you again!
The request the browser sends has a field called "Accept-Language" header. It's formatting isn't so intuitive and if you wanted to do it correctly, is beyond the ability of the htaccess file and mod_rewrite to parse properly. Here's a typical "Accept-Language" request header:
Accept-Language: da, en-gb;q=0.8, en;q=0.7
Which means: "I prefer Danish, but will accept British English and other types of English"
So you can't simply look for the first two letters of the field. If you don't have Danish, then you've got to continue parsing to find the right language. Magento probably has some ways of dealing with this, for example: http://www.magentocommerce.com/wiki/multi-store_set_up/how_to_automatically_redirect_to_a_store_view_based_on_the_browser_language
Just paste the following code after require_once $mageFilename; in your CE 1.7.0.2 index.php:
/* Determine correct language store based on browser */
function getStoreForLanguage()
{
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
foreach (explode(",", strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])) as $accept) {
if (preg_match("!([a-z-]+)(;q=([0-9.]+))?!", trim($accept), $found)) {
$langs[] = $found[1];
$quality[] = (isset($found[3]) ? (float) $found[3] : 1.0);
}
}
// Order the codes by quality
array_multisort($quality, SORT_NUMERIC, SORT_DESC, $langs);
// get list of stores and use the store code for the key
$stores = Mage::app()->getStores(false, true);
// iterate through languages found in the accept-language header
foreach ($langs as $lang) {
$lang = substr($lang,0,2);
if (isset($stores[$lang]) && $stores[$lang]->getIsActive()) return $stores[$lang];
}
}
return Mage::app()->getStore();
}
/* Auto redirect to language store view if request is for root */
if ($_SERVER['REQUEST_URI'] === '/') {
header('Location: '.getStoreForLanguage()->getBaseUrl());
exit;
}
Make sure you don't delete or overwrite any code in your index.php file and you should be fine!

Resources