Skip to content

Instantly share code, notes, and snippets.

@stevygee
Last active May 10, 2022 10:04
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save stevygee/ed18db68a247c2cd4fb7680d39d41502 to your computer and use it in GitHub Desktop.
Add WPML translations to WP2Static v7
<?php
function sg_get_translated_posts_urls() {
$default_lang = apply_filters( 'wpml_default_language', NULL );
$ids = get_posts( array(
'fields' => 'ids',
'post_type' => array( 'post', 'page' ),
'numberposts' => -1,
'suppress_filters' => true, // Get posts in all languages
) );
$permalinks = array();
foreach ( $ids as $id ) {
$lang = apply_filters( 'wpml_post_language_details', NULL, $id );
// We only need translations; skip posts in default language
if ( $lang['language_code'] === $default_lang ) {
continue;
}
$permalink = get_permalink( $id );
$wpml_permalink = apply_filters( 'wpml_permalink', $permalink, $lang['language_code'] );
// Strip home URL (domain) from permalink
$wpml_permalink = str_replace( trailingslashit( home_url() ), '/', $wpml_permalink );
$permalinks[] = $wpml_permalink;
}
return $permalinks;
}
function sg_add_additional_urls( $url_queue ) {
/* Add WPML translations */
$translation_urls = sg_get_translated_posts_urls();
$url_queue = array_merge(
$url_queue,
$translation_urls
);
return $url_queue;
}
add_filter( 'wp2static_modify_initial_crawl_list', 'sg_add_additional_urls' );
@tareco
Copy link

tareco commented Apr 10, 2020

Hi, I would like to try this out; how do I patch V7 with this file?

@stevygee
Copy link
Author

No need to edit wp2static, just create a plugin file with this code and activate the plugin!

@tareco
Copy link

tareco commented Apr 10, 2020

Thanks! Testing..

@thegulshankumar
Copy link

Hi, Thanks for sharing. This snippet was little helpful in crawling. The index.html from three other languages and some pages are still missing.

@stevygee
Copy link
Author

stevygee commented May 4, 2020

@thegulshankumar You'll have to check during which step the crawling fails. Check if the pages you are missing show up in the lists here: WP2Static > Caches > Show URLs/Paths. They should definitely be included in the Crawl Queue log if the snippet is active and working correctly.

@thegulshankumar
Copy link

thegulshankumar commented May 5, 2020

I checked and found crawl doesn't include some pages, I think it's WPML bug and nothing else.

Before using above snippet, I have experienced a fact if I keep WordPress settings > Your homepage displays > Your latest posts it doesn't add hreflang. In fact, I had to add manually in the past.

Right now to resolve above issues, there is a solution but It doesn't fit my choice because I prefer Blog archive style.

Solution
WordPress settings > Your homepage displays > A static page (select below) > My beautiful Homepage for the sake of WPML
This way I run crawling, all works fine.

@jeffceriello
Copy link

Hi,

Thanks for this snippet. I managed to get all pages crawled but when I deploy on the S3 bucket I get a Forbidden error on the translated page.

http://m86zur9g.s3-website-eu-west-1.amazonaws.com/en-US/contact-us/

The rest of the website works well. What could it be?

Thanks

@stevygee
Copy link
Author

stevygee commented May 5, 2020

Hi @jeffceriello, is there an index.html in your /en-US/contact-us/ output directory?

@jeffceriello
Copy link

Hi @stevygee, thanks for the quick reply. Yes, there is an index.html in that folder.

@maciejmokrzycki
Copy link

Hi, @stevygee I implemented your solution, unfortunately it doesn't work for me. In one of the comments you wrote "just create a plugin file with this code and activate the plugin!" Just create a simple wp plugin in the wp-content / plugins directory and activate it? Below I attach some of the code as it is written in my project:

` <?php
/**
* @Wordpress-Plugin
* Plugin Name: Static S3 WPML
* Plugin URI: https://www.xxx.com/
* Description: Additional crawler for wp2static plugin. Crawling pages & subpages translated via WMPL
* Version: 0.0.2
* Author: xxx.com
* Author URI: https://xxx.com/
* Text Domain: static-s3-wpml
*/

function sg_get_translated_posts_urls()
{
    $default_lang = apply_filters('wpml_default_language', null);
    
    $posts = get_posts(array(
        'post_type'        => array('post', 'page'),
        'numberposts'      => -1,
        'suppress_filters' => true,
    ));
    
    $ids = wp_list_pluck($posts, 'ID');
    
    $permalinks = array();
    foreach ($ids as $id) {
        $lang = apply_filters('wpml_post_language_details', null, $id);
        
        if ($lang['language_code'] === $default_lang) {
            continue;
        }
        
        $permalink      = get_permalink($id);
        $wpml_permalink = apply_filters('wpml_permalink', $permalink, $lang['language_code']);
        $wpml_permalink = str_replace(trailingslashit(home_url()), '/', $wpml_permalink);
        $permalinks[]   = $wpml_permalink;
    }
    
    return $permalinks;
}

function sg_add_additional_urls($url_queue)
{
    $translation_urls = sg_get_translated_posts_urls();
    $url_queue        = array_merge($url_queue, $translation_urls);
    
    return $url_queue;
}

add_filter('wp2static_modify_initial_crawl_list', 'sg_add_additional_urls');

`
I will be grateful for a hint as to what I am doing wrong.
Greetings, Maciek

@stevygee
Copy link
Author

@jeffceriello So in that case, this gist seems to work, because WP2Static has received the URL and crawled it. Please check the WP2Static output files, open that index.html locally in your browser and check if it contains the contents you expect. If it does, I think you are experiencing an issue with your hosting, unrelated to this gist. If you are getting an error, it means the page has been crawled, but something went wrong during crawling and the error your webserver (running WP) has been saved into the file, in which case it is probably an issue with your webserver config or WP2Static itself.

@jeffceriello
Copy link

Ok, I will check that, thanks @stevygee.

@stevygee
Copy link
Author

@maciejmokrzycki Yes that looks good, should work this way. I just tested again with WP2Static v7.alpha-004 and a snapshot from May 8th and both worked. Please check if you translations show up in the WP2Static logs: WP2Static > Caches > Show URLs/Paths.

@thegulshankumar
Copy link

thegulshankumar commented May 15, 2020

Hi, @stevygee

I have noticed some issues

Suppose, I have Contact Page in English and Spanish with Different languages in directories settings in WPML.

Typically, my homepage looks like example.com/ and example.com/es/

Case 1. It works perfectly if I maintain same permalink for all languages.

example.com/contact/ returns 200
example.com/es/contact/ returns 200

All good.

Case 2. Doesn't work with Translated permalinks

example.com/contact/ returns 200
example.com/es/contacto/ returns 404

Issues

  1. Crawled logs shows 404 for /es/contact/ which should not be because I have already translated permalink (Ref: case 2)
  2. I do not see /es/contacto/ in the crawl logs.
  3. However, the actual content of /es/contacto/ appears at /es/contact/ permalink.

This problem presist for Post and Pages.

Expected: I wish to make content appear at translated URL /es/contacto/ which is for Spanish version of Contact page.

Thanks

@stevygee
Copy link
Author

@thegulshankumar Two things come to mind:

  1. Apologize if this is too obvious, but are your translated permalinks working in the WP frontend? So are you getting 200 for /es/contacto/ when accessing WordPress directly? If not, try to get the permalinks working first.
  2. Clear your WP2Static Cache before deploying. I found that WP2Static v7 often refuses to crawl a page (even if a change has been made), if it was already cached during a previous deployment process.

@fertek
Copy link

fertek commented Jun 19, 2020

Expected: I wish to make content appear at translated URL /es/contacto/ which is for Spanish version of Contact page.

Hi @thegulshankumar

I think this issue can be solved by:
$wpml_permalink = apply_filters( 'wpml_permalink', $permalink, $lang['language_code'] );

$wpml_permalink = apply_filters( 'wpml_permalink', $permalink, $lang['language_code'], true );

See $full_resolution parameter at https://wpml.org/wpml-hook/wpml_permalink/.

@stevygee thanks for sharing! I have an idea for improvement.

	$posts = get_posts( array(
		'post_type'        => array( 'post', 'page' ),
		'numberposts'      => -1,
		'suppress_filters' => true, // Get posts in all languages
	) );

	$ids = wp_list_pluck( $posts, 'ID' );

	$ids = get_posts( array(
		'fields'           => 'ids',
		'post_type'        => array( 'post', 'page' ),
		'numberposts'      => -1,
		'suppress_filters' => true, // Get posts in all languages
	) );

@stevygee
Copy link
Author

@fertek You are right, thanks for the simplification!

@bkno
Copy link

bkno commented May 6, 2022

Edited: After all I was able to get it working using fertek's suggestion above using the true parameter after all. For this to work reliably, you need to go to WPML > Languages > and disable "Adjust IDs for multilingual functionality". Otherwise, the IDs get converted and you will be missing some pages during the crawl.

Thank you for sharing these solutions.

@stevygee
Copy link
Author

@bkno Glad to hear that it works for you now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment