This is the technical support forum for WPML - the multilingual WordPress plugin.
Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
- | - | 9:00 – 18:00 | 9:00 – 18:00 | 9:00 – 18:00 | 9:00 – 18:00 | 9:00 – 18:00 |
- | - | - | - | - | - | - |
Supporter timezone: America/Lima (GMT-05:00)
Tagged: Custom Work
This topic contains 19 replies, has 2 voices.
Last updated by Andreas W. 4 months, 2 weeks ago.
Assisted by: Andreas W..
Author | Posts |
---|---|
February 7, 2025 at 11:14 am #16679232 | |
lorenzP |
Please stop sending my AI generated answers. This does not help at all. The answers are just wrong... |
February 7, 2025 at 4:47 pm #16680669 | |
Andreas W. WPML Supporter since 12/2018 Languages: English (English ) Spanish (Español ) German (Deutsch ) Timezone: America/Lima (GMT-05:00) |
We ran a quick test and could not confirm an issue in a minimal setup: Your code works as expected here without any workaround. --- Now, I saw you reported this issue earlier, and we have a couple of open tickets on development about this issue, which are still not solved and this is why I tried to provide a possible workaround. My previous answer truly was not AI-generated and I have today verified the provided workaround with one of our compatibility developers, who suggested a slight change: // Use the wpml_current_language hook to get the current language $current_language = apply_filters( 'wpml_current_language', NULL ); // Get the permalink for a specific post in default language (replace with your post ID) $default_language = apply_filters( 'wpml_default_language', NULL ); do_action( 'wpml_switch_language', $default_language ); $post_permalink = get_permalink( $post_id ); // Get the post ID from the URL (this works for the default language, based on permalink) $post_id_in_default_language = url_to_post_id( $post_permalink ); // Use WPML's filter to get the translated post ID in the current language do_action( 'wpml_switch_language', $current_language ); $translated_post_id = apply_filters( 'wpml_object_id', $post_id_in_default_language ); // $translated_post_id now contains the post ID for the current language echo $translated_post_id; --- If it works on the production site and not on the staging then this would mean both sites are not identical. Revise installed theme and plugins and their versions. Make sure that staging and production use the same custom code. If you would like me to take a look at the staging, let me know. --- Also, I would like to invite you to, please log into the following test site and recreate the issue, so that we can take a closer look at your code and try to find a solution: One-Click-Login: |
February 10, 2025 at 3:31 pm #16688427 | |
lorenzP |
The code you provided assumes we know the post ID already (calls get_permalink()) but we don’t know the post ID that’s why we are using the url_to_postid() WordPress API to convert a URL to a post ID. Last week I debugged the WPML plugin’s source code for more than 4 hours to understand what’s going wrong. The WPML hook handles language switching, URL parameter stripping and lots of other things. I found the following code was failing and a failsafe code gets executed which returns the 0 result: In classes/query-filtering/class-wpml-get-page-by-path.php the WPML_Get_Page_By_Path::get() method uses get_page_by_path() internally and returns no WP_Post value in our case. This method gets called with $post_name as parameter but does not get the full path of the page which is in our case a child page. In our production environment we get the correct post ID but in our staging environment this failed to work about three weeks ago. In order to be able to launch our new website ASAP, we added a workaround which uses get_page_by_path() in cases where url_to_postid() returns 0. This works fine for now without having a fix yet for the root cause. We also extended the test page to show the APIs we call: hidden link To further analyze this issue we can get you access to our staging environment or duplicate it on one of your servers as we have done before. I guess this issue is related to the database and therefore not easy to reproduce on a fresh WordPress instance. |
February 11, 2025 at 8:12 am #16690218 | |
Andreas W. WPML Supporter since 12/2018 Languages: English (English ) Spanish (Español ) German (Deutsch ) Timezone: America/Lima (GMT-05:00) |
To report a bug in WPML and for further escalation I would like to invite you to, please log into the following test site and recreate the issue, so that we can take a closer look at your code and take further steps: One-Click-Login: |
February 14, 2025 at 4:43 pm #16707520 | |
lorenzP |
I have a Duplicator backup I can upload to a server. It is important we upload the full database to showcase this error. We cloned our WordPress instance before for other WPML tickets. Can we do this again? |
February 14, 2025 at 8:23 pm #16708015 | |
Andreas W. WPML Supporter since 12/2018 Languages: English (English ) Spanish (Español ) German (Deutsch ) Timezone: America/Lima (GMT-05:00) |
Hello, I would like to offer to take a closer look and request temporary access (wp-admin and FTP) to the site to investigate the issue further. The required fields are below the comment section when you log in to leave the next reply. The information you provide is private, meaning only you and I can see and access it. IMPORTANT If you can't see the "wp-admin / FTP" fields, your post and site login details will be set to "PUBLIC". DO NOT publish the data unless you see the required wp-admin / FTP fields. I may need to install a plugin called "All In One WP Migration" here to create a copy of the site that I can use to investigate the issue further. However, I would also be very grateful if you could provide a staging site or copy of the website from your server for this purpose. If you have any questions about creating such a staging site, you can consult your hosting provider. Please note that WPML must also be registered on this staging site at https://wpml.org/de/account/websites/. If you are not able to provide such a copy of the website for testing, please let me know on this ticket. The private reply form looks like this: The next time you reply, click on "I still need assistance". Video: Please note that we are obliged to request this information individually on each ticket. We are not allowed to access any credentials that were not specifically submitted on this ticket in the private response form. Best regards |
February 21, 2025 at 6:15 pm #16734920 | |
Andreas W. WPML Supporter since 12/2018 Languages: English (English ) Spanish (Español ) German (Deutsch ) Timezone: America/Lima (GMT-05:00) |
My apologies, but I asked you to simply recreate the issue on a test site which I provided. You are using custom code, which is something that generally is not something that we support. We can guide you on using custom code but we do not debug such code. Our support team is not obligated to do this and I am assisting you on this matter on a voluntary base. Further, you are asking me to take a local copy of a site that already is a staging site. Besides, according to what I see here, this is currently working as expected with the exception of page_by_path: This function will be default always get the path in the site's default language. To get page_by_path you will need to use WPML's dedicated hook to switch the language, after getting the current language and check for all active languages. Example: if (ap_starts_with($permalink, $base_url)) { $path = substr($permalink, strlen($base_url)); $pos = strpos($path, '?'); // Clean up path by removing query string if ($pos !== false) { $path = substr($path, 0, $pos); } // Get the current language and all active languages $current_language = apply_filters('wpml_current_language', NULL); $languages = apply_filters('wpml_active_languages', NULL, 'orderby=id&order=asc'); // Fetch all active languages // Check if there is a second language available $second_language = ''; foreach ($languages as $lang) { if ($lang['code'] !== $current_language) { $second_language = $lang['code']; // Set second language break; // Break after finding the second language } } if ($second_language) { // Switch to the second language do_action('wpml_switch_language', $second_language); // Fetch the page in the second language $page = get_page_by_path($path); // Switch back to the original language do_action('wpml_switch_language', $current_language); // Debug output echo '<p>'; echo '<div>Path: ' . esc_html($path) . '</div>'; echo '<div>get_page_by_path(\'' . esc_html($path) . '\'): ' . (empty($page) ? '0':$page->ID) . '</div>'; echo '</p>'; } else { echo '<p>Second language not found.</p>'; } } |
February 25, 2025 at 4:03 pm #16746894 | |
lorenzP |
The facts are: - our code was working for 4 years (production and staging) Because we made no WPML update at that time we think this is a problem with one of the WPML database tables. A failing test case is available here: hidden link I suggest we close this ticket as unsolved because no one is willing to look into this and we have a workaround in place. |
February 25, 2025 at 6:55 pm #16747515 | |
Andreas W. WPML Supporter since 12/2018 Languages: English (English ) Spanish (Español ) German (Deutsch ) Timezone: America/Lima (GMT-05:00) |
Indeed, thank you for the feedback! My first goal was to first provide you with a workaround. The next step would be to consult our development team about which behavior would be expected and if we might have a bug in WPML. It might be that WPML earlier used to apply its own logic once the function was used and this was changed. I will try to recreate the issue with a simple example, then escalate accordingly and keep you updated. |
February 25, 2025 at 9:29 pm #16748222 | |
Andreas W. WPML Supporter since 12/2018 Languages: English (English ) Spanish (Español ) German (Deutsch ) Timezone: America/Lima (GMT-05:00) |
I was able to recreate the issue and it only occurs when the site URL format "Language name added as a parameter" is used. This format is usually only for development purposes and should not be used on a live site. It can even have a negative impact on your SEO rating and indexing of the site. I suggest you switch the language URL format to "Different languages in directories" which solves the issue on my test. |
February 26, 2025 at 5:47 pm #16752594 | |
lorenzP |
We use the language parameter on this site for many years without any issues. Because of static URLs we cannot easily switch to another URL format. Is the SEO impact you mention documented somewhere? I could not find any references in the WPML documentation about this: https://wpml.org/documentation/getting-started-guide/language-setup/language-url-options/. |
February 26, 2025 at 6:01 pm #16752743 | |
Andreas W. WPML Supporter since 12/2018 Languages: English (English ) Spanish (Español ) German (Deutsch ) Timezone: America/Lima (GMT-05:00) |
The topic is covered here: Google doesn't give a direct example of language parameters here, but the documentation clearly states that using too many parameters can cause problems. Example: example.com/shop/?lang=de&s=Handschuhe&color=blau&size=m This URL is difficult to understand and not as user-friendly for users as one organized by a clearer structure like a directory or subdomain. A contribution from Chat GPT on the topic: --- If you insist, I can report the problem internally, although it is possible that our developers will come to the same conclusion. |
February 26, 2025 at 6:33 pm #16752906 | |
Andreas W. WPML Supporter since 12/2018 Languages: English (English ) Spanish (Español ) German (Deutsch ) Timezone: America/Lima (GMT-05:00) |
Reason for the issue: The native WordPress function url_to_postid() does check for parameters inside the URL, like like p=N, page_id=N, or attachment_id=N, but it does not check for lang: if ( preg_match( '#[?&](p|page_id|attachment_id)=(\d+)#', $url, $values ) ) { $id = absint( $values[2] ); if ( $id ) { return $id; } } The following filter hook might be able to solve such an issue if you add it to functions.php file of a Child Theme, use a Code Snippet Plugins or create a small custom plugin: function custom_url_to_postid_lang_filter( $url ) { // Check if the URL has a 'lang' parameter if ( preg_match( '#[?&]lang=([^&]+)#', $url, $matches ) ) { // Do something with the 'lang' parameter, e.g., store it, change the URL, etc. $lang = $matches[1]; // You can perform further logic here, like loading language-specific content } return $url; // Return the potentially modified URL } add_filter( 'url_to_postid', 'custom_url_to_postid_lang_filter', 10, 1 ); |
The topic ‘[Closed] url_to_postid() in secondary language always returns 0 for valid URL’ is closed to new replies.