Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When exporting a WP site that uses Divi/WPML, only the English posts are exported #156

Closed
dirkhh opened this issue Jan 3, 2017 · 13 comments

Comments

@dirkhh
Copy link

dirkhh commented Jan 3, 2017

One of the things that would be extremely nice is to be able to use Github in order for the translators to collaborate... I push changes to the English posts and pages to Github, the translators can then add pull requests for the updated translations.
But it seems that wpgs only syncs the original English posts :-(

@dirkhh
Copy link
Author

dirkhh commented Jan 3, 2017

Reading through the code I believe I understand why this is happening... github_filename() assembles the correct path plus get_name() (for pages) or get_the_time().get_name() (for posts). And for translated posts and pages the post_name in the wp_posts database is identical, but the guid is different (for example
mysql> SELECT ID,post_date,post_title,post_name,guid,post_status,post_type FROM wp_posts WHERE post_name = 'about' AND wp_posts.post_type = 'page' AND (wp_posts.post_status = 'publish') ORDER BY wp_posts.post_date DESC;
+------+---------------------+------------+-----------+--------------------------------------------------+-------------+-----------+
| ID | post_date | post_title | post_name | guid | post_status | post_type |
+------+---------------------+------------+-----------+--------------------------------------------------+-------------+-----------+
| 7 | 2011-10-06 02:48:17 | Subsurface | about | <siteURL>/?page_id=7 | publish | page |
| 1686 | 2011-10-06 02:48:17 | Subsurface | about | <siteURL>/about/?lang=fr | publish | page |
| 1687 | 2011-10-06 02:48:17 | Subsurface | about | <siteURL>/about/?lang=de | publish | page |
| 1688 | 2011-10-06 02:48:17 | Subsurface | about | <siteURL>/about/?lang=it | publish | page |
| 1689 | 2011-10-06 02:48:17 | Subsurface | about | <siteURL>/about/?lang=es | publish | page |
| 1690 | 2011-10-06 02:48:17 | Subsurface | about | <siteURL>/about/?lang=pl | publish | page |
| 1691 | 2011-10-06 02:48:17 | Subsurface | about | <siteURL>/about/?lang=pt-pt | publish | page |
| 2195 | 2011-10-06 02:48:17 | Subsurface | about | <siteURL>/fi/about/ | publish | page |
+------+---------------------+------------+-----------+--------------------------------------------------+-------------+-----------+
As you can see, all the translated pages have the same post_title (that's coincidence, but it means this can't be used to distinguish the pages) and post_name, but the guid is different. Unfortunately the guid is slightly inconsistent, in some instances it's '../language/post_name', in some it's '../post_name/?lang=language'... but it should be possible to extract the language from the guid and create about.md, about-fr.md, about-de.md, etc.

@mAAdhaTTah
Copy link
Owner

You can customize the exported file with the wpghs_filename filter. You can use it to give each filename a custom extension (e.g. -de.md or what have you) based on the post.

The filename collisions are the only problem you're having, correct?

@dirkhh
Copy link
Author

dirkhh commented Jan 3, 2017

Thanks for the quick response!
So far the filename collision seem like the most likely source of my problem - I'll see if there's anything else once I address this.
I do have one questions in this context (and this is just a sign that I'm not very comfortable with PHP/WP programming): how would I go about using wpghs_filename to make the filename unique? I.e., would I modify the source of the plugin that I use? Create another plugin? Is there a way to do this from the WP UI?

@dirkhh
Copy link
Author

dirkhh commented Jan 4, 2017

Hmm, did some more googling and wrote a tiny plugin to add a filter - I think I did this right as it does get called:

function makeunique_github_sync_names( $post_name, $post_object ) {

  file_put_contents('php://stderr', print_r("makeunique_github_sync_names: " . $post_name . " -- " . get_permalink( $post_object->post ) . "\n", TRUE));
  return $post_name;
}

add_filter ( 'wpghs_filename', 'makeunique_github_sync_names', 10, 2 )

but unfortunately it only gets called once per post_name - so it looks like the wpghs logic already gives up on creating multiple files before this filter gets called :-(

@dirkhh
Copy link
Author

dirkhh commented Jan 4, 2017

Continuing to talk to myself here :-)

So it turns out that WPML filters the responses to WP_Query to only show the active language. So this does require a tiny change to wpghs:

        public function fetch_all_supported() {
                $args  = array(
                        'post_type'   => $this->get_whitelisted_post_types(),
                        'post_status' => $this->get_whitelisted_post_statuses(),
                        'nopaging'    => true,
                        'fields'      => 'ids',
                        'suppress_filters' => true,
                );

                $query = new WP_Query( apply_filters( 'wpghs_pre_fetch_all_supported', $args ) );

Note the 'suppress_filters' => true

Then a quick plugin that gives you reasonable document names for your export could be this:

function makeunique_github_sync_names( $post_name, $post_object ) {

  $my_post_language_details = apply_filters( 'wpml_post_language_details', NULL, $post_object->id ) ;

  global $sitepress;

  $current_main_id = icl_object_id( $post_object->id, $post_object->post->post_type, true, $sitepress->get_default_language() );
  $current_slug = get_post( $current_main_id );
  $slug = $current_slug->post_name;

  return $slug . "." . $my_post_language_details["language_code"];
}

add_filter ( 'wpghs_filename', 'makeunique_github_sync_names', 10, 2 )

and this seems to work fine for me. The slightly cumbersome way to get the $slug here uses the WPML api to get to the untranslated matching post and then uses its name - this way all the names are consistent.

about.en
about.de
about.fr
...

Next I need to see if the opposite direction works as well.

Not sure if / how this could be made generic so I don't need to patch wpghs - could you add an option to suppress the filters?

@dirkhh
Copy link
Author

dirkhh commented Jan 4, 2017

OK, I guess I have a solution here - I'd love to see the "suppress_filters" argument somehow be enabled as an option, though.

@dirkhh dirkhh closed this as completed Jan 4, 2017
@mAAdhaTTah
Copy link
Owner

So just so we're on the same page, this line:

$query = new WP_Query( apply_filters( 'wpghs_pre_fetch_all_supported', $args ) );

would need to be added/modified so you can filter the arguments passed to the WP_Query?

@dirkhh
Copy link
Author

dirkhh commented Jan 4, 2017

If you look at my snippet above, I added one element to $args: 'suppress_filters' => true
So, staring at the code some more, I guess I can do that by writing another filter that adds this element via wpghs_pre_fetch_all_supported, correct?
I'll get the hang of WP/PHP hacking, eventually :-)

@mAAdhaTTah
Copy link
Owner

Correct. You generally want to avoid modifying plugin files directly, as those changes will get overwritten when you upgrade the plugin. So you should use the wpghs_pre_fetch_all_supported filter to add the suppress_filters to the args before they get passed into the WP_Query.

If you're new to WordPress, check out the Codex, which has a lot of info about the Plugin API.

@dirkhh
Copy link
Author

dirkhh commented Jan 4, 2017

The funny thing is - I've used WordPress since 2003; I remember when 'Miles' became the first named release. And I have done a bit of work on themes in the early days. But I have never really become a PHP developer - I have been a C (and lately C++) developer for 30 years, though :-)

Anyway, to prove my point that I'm not all that competent, I updated the plugin, but somehow managed to get my WP installation confused. It now tells me

Fatal error: Class 'WordPress_GitHub_Sync_Admin' not found in /data/www/subsurface/wp-content/plugins/wp-github-sync/wp-github-sync.php on line 141

when I try to activate the updated plugin. Any idea what I messed up?

@mAAdhaTTah
Copy link
Owner

How did you update the plugin? Through the UI?

@dirkhh
Copy link
Author

dirkhh commented Jan 4, 2017

No, I figured it would be easier to checkout the git repository, so I deleted the folder and then did a git clone (I run my own wordpress site on a dedicated server). I now deleted the plugin from the UI and installed it again from the UI and that seems to have worked. I just fail to understand why I ran into this problem in the first place...

The added filter seems to have worked, but I do have some odd changes in my git repo that I want to track down (two new files were added without language designation and one file with language designation was deleted) - something is odd there, but it's possible that it's in my plugin that adds the filters.

@mAAdhaTTah
Copy link
Owner

The git repo depends on composer, PHP's package manager, which installs an autoloader to load our dependencies. On .org and GitHub's releases, I ensure composer install is run to create said autoloader to bundle with the plugin. Since you just cloned the repo, you would need to run composer install after to get the autoloader. Which is why you saw the "class not found" error: no autoloader, class isn't loaded, therefore, not found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants