Andis
Forum Replies Created
-
Forum: Plugins
In reply to: [Polylang] [Plugin: Polylang] wp-login.php always in english?Could you explain why it is a problem ?
I create my custom post types in
init
action hook as suggested by the Codex examples of register_post_type, but textdomains are not loaded yet at that point. I could modify those labels later, but that duplicates code and doesn’t make much sense.I can register them after
wp
hook, but then CPT rewrite rules would not be modified by Polylang as that is done inwp_loaded
which comes beforewp
unless Polylang hooks ontoregistered_post_type
.
Another option for Polylang to get$qury_var['lang']
would be to hook ontoparse_request
but at that point$wp_query
is not yet populated and hence there is no$wp_query -> queried_object
.Forum: Plugins
In reply to: [Polylang] [Plugin: Polylang] excerpts too long when not in englishPlease clarify, so somebody can answer your question:
What is your other language?
Do you use automatic excerpts and how do you generate them?Forum: Plugins
In reply to: [Polylang] [Plugin: Polylang] wp-login.php always in english?You’re right, I just tested myself and it appears that Polylang is loading its front-end class
Polylang_Core
instead ofPolylang_Admin
becauseis_admin()
returnsfalse
before user has logged in.Correct locale was loaded when I disabled Polylang by commenting out last two lines in polylang.php (which is the fastest way to do it without logging in).
I suppose there should be another way to check if the back-end is loaded before user logs in.
Edit: maybe Polylang can check
$pagenow == 'wp-login.php'
besindesis_admin()
as it is WordPress global defined in wp-includes/vars.php and used in wp-settings.php.
Edit #2: I just checked and the switch works. If you really need it and are ready to modify code of Polylang, just make changes in polylang.php around line 81 to 86:// separate admin and frontend global $pagenow; if (is_admin() || $pagenow == 'wp-login.php') { require_once(PLL_INC.'/admin.php'); $polylang = new Polylang_Admin(); }
I’m actually having another problem because Polylang delays textdomain loading until
wp
action which is too late as I need my custom post type labels ininit
hook.Forum: Plugins
In reply to: [Polylang] [Plugin: Polylang] Identical page names in different languagesNOTE: If you create pages or posts with identical slugs and disable Polylang after that, only first matching post or page will be displayed in front-end. And this may not work for pages.
EDIT: Currently there are problems querying right posts in front-end when using this code. I’ll post more code as soon as I get it fixed.
It appears that Polylang is setting current language from current post or page in single view instead of getting it from query variable.
Forum: Plugins
In reply to: [Polylang] [Plugin: Polylang] Identical page names in different languagesThis is because WordPress does not filter posts and pages by language when checking if the slug is unique.
I had same problem and just finished code as a workaround for this. Until Chouby includes this in Polylang core you can use following code in your theme functions.php or create a plugin out of it:
global $polylang; // Check if Polylang_Base exists and if $polylang is the right object if(is_admin() && class_exists('Polylang_Base') && $polylang instanceof Polylang_Base){ // The wp_unique_post_slug filter is applied only after WordPress checks if the slug is unique and adds suffix otherwise // the function returns unique post slug within language add_filter('wp_unique_post_slug', 'unique_slug_in_language', 10, 5); function unique_slug_in_language($slug, $post_ID, $post_status, $post_type, $post_parent = 0){ global $polylang, $wpdb; // Get language of a post $lang = $polylang->get_post_language($post_ID); // return the slug if Polylang does not return post language if(empty($lang)) return $slug; // Remove suffix if it was added // this might remove any dash and number at the end of a slug $new_slug = isset($_POST['new_slug'])? sanitize_title($_POST['new_slug']) : preg_replace('@-\d$@', '', $slug); // Return slug if it was not changed if($new_slug == $slug) return $slug; // prepare statements to filter by language $join = $wpdb->prepare(" INNER JOIN $wpdb->term_relationships AS pll_tr ON pll_tr.object_id = ID"); $where_lang = $wpdb->prepare(" AND pll_tr.term_taxonomy_id = %d", $lang->term_id); $hierarchical_post_types = get_post_types( array('hierarchical' => true) ); // Polylang does not translate attachements - skip if it is one if ( 'attachment' == $post_type ) { return $slug; } elseif ( in_array( $post_type, $hierarchical_post_types ) ) { // Page slugs must be unique within their own trees. Pages are in a separate // namespace than posts so page slugs are allowed to overlap post slugs. $check_sql = "SELECT post_name FROM $wpdb->posts $join WHERE post_name = %s AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) AND ID != %d AND post_parent = %d $where_lang LIMIT 1"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $new_slug, $post_ID, $post_parent ) ); if(!$post_name_check) return $new_slug; } else { // Post slugs must be unique across all posts. $check_sql = "SELECT post_name FROM $wpdb->posts $join WHERE post_name = %s AND post_type = %s AND ID != %d $where_lang LIMIT 1"; $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $new_slug, $post_type, $post_ID ) ); if(!$post_name_check) return $new_slug; } return $slug; } }
It is smart enough not to just strip the suffix added by WordPress. It really checks if there are no duplicates in post/page language and under same parent. Code is partially taken from wp-includes/post.php
wp_unique_post_slug
function with some stuff from Polylang core.php.Not pretty, but it works and I don’t know any better way to do this right now. Additions or suggestion are welcome.
Forum: Plugins
In reply to: [Polylang] [Plugin: Polylang] wp-login.php always in english?That is because wp-admin language settings are saved for logged-in user, but the user data is not loaded until you log in.
However, if you have defined default language in wp-config.php, you should see your login screen in that language.Another thing is that textdomains of themes and plugins have to be loaded after init action hook (which is even after
after_setup_theme
hook) to be in language detected by Polylang.Forum: Plugins
In reply to: [Polylang] [Plugin: Polylang] Problems with custom post type archive titlesCPT archive titles now work correctly in Polylang 0.8.
Unfortunately there is another CPT related bug;
CPT archive links are incorrect if$cpt->has_archive
is string and differs from CPT name or slug.
Actually, you just need to get the slug from$cpt->has_archive
if it is a string;This makes things simpler in core.php @ 518:
$cpt = get_post_type_object($qvars['post_type']); // we don't need to check if there is $cpt->rewrite['slug'] because WP always sets it // see /wp-includes/post.php in register_post_type() on line 995 $cpt_slug = is_string($cpt->has_archive) ? $cpt->has_archive : $cpt->rewrite['slug']; $url = esc_url($base.$cpt_slug.'/');
And, I believe, there could be other underwater stones hiding in
$cpt->hierarchical
. Haven’t seen any tho.
I’m currently trying to create a structure of _different_ hierarchical post types and some CPT limitations can be seen already, but that’s mostly unrelated to Polylang.Forum: Plugins
In reply to: [Polylang] Development of Polylang version 0.8hide_empty
inget_terms
adds checking ofcount
field inwp_term_taxonomy
table and that is why Polylang was displaying thefill_languages
option in settings tab.I’ve updated to 0.8 and all seems OK.
…until I’ll find another edge case bug, which can be encountered only in very special conditions. ??Forum: Plugins
In reply to: [Polylang] Development of Polylang version 0.8I was moving code to production sandbox and tried to set default language for existing content in Polylang options screen.
Got this:WordPress database error: [Duplicate entry '41-5' for key 1] INSERT INTO wp_dev_term_relationships (object_id, term_taxonomy_id) VALUES (41, 5),(33, 5),(28, 5),(26, 5),(2, 5),(1, 5),(23, 5),(13, 5),(6, 5),(9, 5),(24, 5)
This is because
get_terms('language', array('fields'=>'ids'))
return an empty array every time. This in turn happens because, when you insert term relations manually,wp_term_taxonomy.count
is not incremented.
Theget_terms
query returns only non-empty terms:
SELECT t.term_id, tt.parent, tt.count FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ('language') AND tt.count > 0 ORDER BY t.name ASC
Solution would be to add the
hide_empty
option toget_terms
inPolylang_Admin::get_untranslated()
:get_terms('language', array('fields'=>'ids','hide_empty'=>0));
and term count should also be updated after inserting relations to prevent further problems with
get_terms
:$post_count = count($untranslated['posts']); //Note: get_untranslated returns array instead of false - read below if($post_count && $lang->term_taxonomy_id){ $values = array(); foreach ($untranslated['posts'] as $post_id) $values[] = $wpdb->prepare("(%d, %d)", $post_id, $lang->term_taxonomy_id); $wpdb->query("INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id) VALUES " . implode(',', $values)); $wpdb->update($wpdb->term_taxonomy, array('count'=>$post_count), array( 'term_taxonomy_id' => $lang->term_taxonomy_id )); }
Probably there is a better way to update term counts.
Polylang_Admin::get_untranslated()
should return an array of arrays instead of false:return empty($posts) && empty($terms) ? false : array('posts' => $posts, 'terms' => $terms);
better cast them as arrays:
return array('posts'=>(array)$posts, 'terms'=>(array)$terms);
that way it can be passed directly to
foreach
without warnings likeInvalid argument supplied for foreach() in ...
.EDIT: I made this change and realized that there should be more advanced check in admin-form.php so maybe in this case it is easier to check return values in admin.php.
Forum: Plugins
In reply to: [Polylang] Development of Polylang version 0.8Downloaded 0.8dev7 and going over diff.
In core.php on line 330, instead ofunset($query->queried_object)
it should be
$query->queried_object = false
because
unset()
will delete the property and create notice when accessed in WP core and maybe create even more issues.
I’ll correct it in local copy, but you should also change it in your code.EDIT: Oh, excuse me. I was actually wrong about that
unset()
. Inget_queried_object
it actually checks it withisset
.I have also partially translated Polylang to Latvian and as soon as I get to complete it, I’ll send you the .mo file.
Forum: Plugins
In reply to: [Polylang] Development of Polylang version 0.8Those two notices I mentioned above are coming from filter hook
option_page_for_posts
.
I think,Polylang_Core->translate_page()
should return passed value if it equals zero because there is no post with ID 0. That is also the way filter functions work in WP.I highly recommend adding Xdebug to your development toolset, because oftentimes it can help to solve some obscure issues. To get better idea of what’s going on configure it to show function params in stack traces. That would be
xdebug.collect_params = 4
.I am ‘self made PHP developper’ so glad to learn more…
Me too. I have a graphics design education and PHP is only part of my skill set. Nevertheless I have more than eight years of experience in web development and programming in general.
I agree that
before
andafter
options are not needed.I’ve implemented post content and title duplication on translation creation. I did it on
default_content
anddefault_title
filter hooks just for my event CPT and only if$_GET['from_post']
is set.
here’s the code:// copy post content and title when translating events with Polylang add_filter('default_content','copy_post_translation', 100, 2); add_filter('default_title','copy_post_translation', 100, 2); function copy_post_translation($content, $post){ $from_post = isset($_GET['from_post'])? (int)$_GET['from_post'] : false; if($from_post && 'ily_event' == $post->post_type && $content == ''){ $from_post = get_post($from_post); if($from_post) switch(current_filter()){ case 'default_content': $content = $from_post->post_content; break; case 'default_title': $content = $from_post->post_title; break; default: break; } } return $content; }
Note:
ily_event
is my CPT and it copies content if it is not set already, as other plugins or theme could have set default content or title.Forum: Plugins
In reply to: [Polylang] Development of Polylang version 0.8The permastruct is
/%year%/%monthnum%/%postname%/
optionshow_on_front => 'posts'
polylang options when I get redirect loops:[browser] => 0 [rewrite] => 1 [hide_default] => 0 [force_lang] => 0 [default_lang] => lv [redirect_lang] => 1
polylang options when it works as expected:
[browser] => 0 [rewrite] => 1 [hide_default] => 1 [force_lang] => 0 [default_lang] => lv [redirect_lang] => 1
It seems that
hide_default
andforce_lang
are somehow exclusive because if both arefalse
I get redirect loops on front page.browser
andredirect_lang
is irrelevant here because changing those didn’t fix redirect problem.
All redirects are to site root/
and with status 302 if that is of any help.And I’m also getting PHP notices when opening non found pages/posts
Trying to get property of non-object in [...]wp-includes/category-template.php on line 1082 Trying to get property of non-object in [...]wp-content/plugins/polylang/include/base.php on line 121
which must be because option
page_for_posts
is'0'
. maybe you should check for such cases inPolylang_Core::translate_page()
orget_post()
.Regarding your coding style – maybe you should not return
false
ornull
where object is expected or either check return values before using them. I know that it is easier and takes less code to do it like:$this->get_post_language($post_id)->term_id
but it is harder to debug and maintain. And thatreturn '';
inget_post
is not nice. I is ok until you turn onWP_DEBUG
and have error reporting set toE_ALL
(which I always have on development sites).
No flame intended – just trying to help. ??a bit off-topic:
When I was starting my current project I thought I could go with WPML, as that is what the blog is using now. Then I discovered that WPML is not free anymore, so I looked for alternatives and found Polylang. It was looking promising until I encountered that bug with CPT and the other one with quick edit, but I decided to help out and maybe make it better. After all, that’s what opensource is about – making stuff better.Forum: Plugins
In reply to: [Polylang] Development of Polylang version 0.8@chouby Have you considered using WordPress plugin trac for bug reports? It’s a bit cluttered in reports section as there are many other devs using it, but it would be easier to track reports.
I have updated to 0.8dev4.
As for the CPT archive title issue: I still can’t get it to show up withwp_title()
becauseget_queried_object()
inpost_type_archive_title()
returns language taxonomy object instead of CPT object. I’ve been reading code of polylang and still can’t track down this bug.Another issue is redirect loop when opening home page without language slug. This doesn’t happen with language slug in url.
After some testing and changing options I found out this happens only ifhide_default ==0
andrewrite == 0
.Forum: Plugins
In reply to: [Polylang] Development of Polylang version 0.8Strangely enough those notices in
post_type_archive_title()
are still coming in 0.8dev3.