I am developing a theme which has a different method of adding in content and so, the default install of WordPress won’t show any content because of this. I was wondering if it is possible to automatically import an XML file via means of an internal function and or hooks after the theme has been activated?
User installs theme > User activates theme > Code behind the scenes
loads up an XML file and performs a silent import of its contents
Currently to import an XML file you have to install the WordPress importer plugin for WordPress and then manually import the file, select a user for associating the imported content with and deciding if you want to import media attachments. I find this step for the types of clients I am targeting too confusing and would like to effectively eliminate the need for this step.
I did some digging into the WordPress importer script and there are a lot of function calls, what would I have to do to strip out the parts where user input is required and import a file using the class and its methods directory? I’m not sure where to begin really.
My clients are tradesmen, so even something as simple as importing an XML file stumps them and they don’t have the time to do it so there is room for error especially if they try and import more than once causing duplicate pages.
Thank you in advance.
Edit/Clarification
There seems to be a lot of confusion here. I am not asking how to check if a theme has been activated, I’ve got that part sorted. I am asking how I would go about parsing an XML import file and automatically importing it without user effort. I essentially want to automate the WordPress import plugin which you can already use to manually import the XML file, choose author, choose to download and import attachments within my functions.php.
Instead of needing a plugin or requiring my clients with lack of computer knowledge nor the want to learn how to do it using the plugin.
Your question is a bit specific if you “only” want to automatically import some posts/pages. There are other ways to do this then using a XML export file.
If you have text-only posts, then you should use LOAD DATA INFILE. At first you have to export your posts.
This will create a directory in your theme folder (be sure it is writeable!) and export the posts and comments (with it’s meta) into dump files. Use the array
export
to define what you want to export. I grouped the most things more or less logical (if you want to export the posts, than you should also export postsmeta and so on).The benefit of this solution is, with the
SELECT
statement you can define particular stuff (e.g. only posts from a special category or only pages or only trashed posts).Now you want to import this stuff in a new blog
This solution is good if the posts did not contain any attachments like images. Another problem is, no users and no categories will be imported. Be sure both are created befor the import starts (or include users and categories in your export). It is a very rough method to import things, it will override existing stuff!
If you want to export the attachments also, you have to do a bit more work.
(Sidenote: Please read the complete answer and the Very Last Words at the end! This topic is not for beginners and I do not write a warning at every risky line of code)
The WordPress Importer Plugin seems to be a good way to import the whole stuff and automatically import/download the attachments. So let’s have a look what this plugin will do.
At first the plugin ask for a XML file to upload. Then it parse the XML file and ask for an author mapping and if the attachments should be downloaded or not.
For an automatically run of the plugin we need to change some things. At first we have to skip the upload process. Thats quite easy because you can bundle the XML file with the theme and you know where the XML file is. Then we have to skip the questions that appears after uploading the XML file. We can predefine our own values and pass them to the import process.
Start with a copy of the plugin. Create a directory in your theme like
autoimport
and copy the fileswordpress-importer.php
andparsers.php
to it. It is a good idea to rename the filewordpress-importer.php
to something likeautoimporter.php
. In your theme function add a function call to trigger the automated impoprtAt first we setup some arguments. The first thing is the complete path to the XML file. The second one is the ID of an existing user. We need this user for author mapping, this is the user where all posts will be mapped to when no new authors should be created.
Now we have to understand how the plugin works. Open your renamed plugin file and scroll down to the end. There is a function
wordpress_importer_init()
and an action call. Remove both, it’s not longer needed. Now go to the top of the file and remove the plugin header (the comment at the beginning of the file). After that, rename the classWP_Importer
to something likeAuto_Importer
, do not forget to adjust thefunction_exists
statement and the first methodWP_Importer
(this is the constructor in PHP4 style).Later we will pass the XML file direct to the class constructor, modify the first method to this
Now we have a to remove and modify some methods inside the class. The first method is the
dispatch()
method. This method tells you how the class works. It do three steps. At first upload the XML file, then process it and at last import the data.Case zero is the first step, it is the greeting. This is the part that you see if you call the import at the first time. It will ask for a file to upload. Case two handles the upload and display a form for the import options. Case three finally do the import. In other words: the first two steps only ask for data we can provide ourself. We only need step 3 (case 2) and have to provide the data asked in step one and two.
In step two you see a function call to
wp_import_handle_upload()
. This function setup some informations about the xml file. We cannot use this function anymore because we haven’t uploaded a file. So we have to copy and modify the function. Create a new method within the classAnd replace the function call
$file = wp_import_handle_upload();
in the methodhandle_upload()
with our new method$file = $this->import_handle_upload();
We replaced now the upload process with our own file (that should already exists). Go on and remove more unneeded methods. The methods
gereet()
,header()
andfooter()
are not longer needed (header and footer only print some text) and can be removed from the class. In thedispatch()
method remove the calls to this methods ($this->header()
and$this->footer()
).The first step is done, now we have to care about the second step, the import options. The import options ask if it should be allowed to download the attachments and mapping the authors.
The first part is easy. Set to true if the attachments should be downloaded or false if not. The author mapping is a bit more complicated. If it is allowed to create new users (the authors from the import file), create them. If not, assign the postss to an existing user. This is been done in the method
get_author_mapping()
. We have to replace the$_POST
data with existing data. Here we need a simple solution, so we simply map all new authors to an existing one if it is not allowed to create new users. Or simply create all new users. In the second case, be sure all new users are dummy users. If not, everytime you import them, they get an email with login and password to the new blog!! I do not explain every line of code, here is the complete rewritten methodThere is some work left to do. Adding a function
auto_import()
firstPlace this function after the class. This function miss some error handling and checking (e.g. for an empty file argument).
If you now run the class, you got a lot of error messages. The first one is, that the class is missing. This is because there is a
if
statement at the beginning.We have to remove it, otherwise the file would not be parsed completely. Than there are some functions that are not loaded at this point. We have to include some files.
Basically thats all. I test this on a local installation with the test data XML from WordPress. It work for me but it is not a perfect solution for production!
And some last words on setting up some options. There are two options that can be modified by a filter:
I think I do not have to explain it. Put this filters in your functions.php and setup true or false (first one is PHP5.3 style, second is WP style).
Very Last Words
I put alltogether in this gist. Use it at your own risk! I’m not responsible for anything!. Please have a look at the files in the gist, I did not explain every little step here.
Thinks I haven’t done: Set a value e.g. in the (theme) options after importing. Else the import starts every time the theme will be activated.
Maybe I will work on it in the future, clean up some things and run more tests on it.
Allow me to re-introduce 2 things here:
(a) “I am not asking how to… I’ve got that part sorted…”
»» I’ve learnt over time to be OK with the fact that the approach to issues/fixes doesn’t necessarily require some ‘visible association’ with the issue at hand.
(b) “…would I have to do to strip out the parts…”
“…clients are tradesmen, so even something as simple as…”
»» Why make it easier for the client at the cost of making it difficult for yourself? I certainly could offer ‘services’ after the deliverables and establish a remote connection to do it for them [chargeable], instead of “…hacking the import plugin…”. I mean, ask yourself if its really worth it in your current scheme of things.
However IF you’re willing to put in the effort then give a shot at the code below.
If you can, then:
I concur with both chrisguitarguy and amolv above.
As chris pointed out the number of ways to achieve an output is many. This is just one. Though it has the potential to get laboriously lengthy, do refer to the last couple of lines before anything else.
NOTE
If you’ve been with WP for a while its needless to mention BACK UP YOUR DB FIRST.
phpMyAdmin has raw power and makes it quite easy to carefully screw things up.
Though the effort required could seem daunting initially, if done right you could make it function like clockwork Ñ …
Finally
How to push 2000 lines of data in 20 sec into those last 2 lines within those 2 braces?
phpMyAdmin » Select DB on left »» Select All TABLES on right »» Export â¼
From the next screen I could copy the ‘STRUCTURE’ part into the $sql = “….” for
your_tables()
and the ‘DATA’ portion into$sql
foryour_data()
For the rest of WP defaults I use
update_option(...)
&update_post_meta(...)
There is no theme equivalent of
register_activation_hook
for plugins — there are a few hacks. Why? Because a theme is a skin. Only functionality specifically related to the display of content should go in a theme, not content itself.As far as how: use the example above to run a callback function one time. WordPress importer works on XML files there are many different ways to parse XML in PHP. Take your pick, parse the file, do what you want with it.
in functions.php condition can be checked
As soon as your theme activated this will automatically import data.