Topic: Running Wordpress functions in MODx  (Read 772 times)

Pages: [1]   Go Down

#1: 21-Jan-2010, 06:24 PM

mconsidine
Posts: 261

Tthis was way easier than I thought it would be.  First, I created a snippet in MODx and called it wp_bridge.  In it, I put the following code, which is basically everything that gets loaded up until "wp" gets called.  So the snippet looks like this :

Code:
<?php
//This code pieced together by Matt Considine from files
//in a Wordpress install, January 2010
/*
* Tells WordPress to load the WordPress theme and output it.
*/
define('WP_USE_THEMES'false);

/* Loads the WordPress Environment and Template */
if ( !isset($wp_did_header) )
{
   
$wp_did_header true;
   
//In this case it is assumed that the Wordpress install is
   //located in a folder called 'wordpress', which lives alongside
   //the assets and manager folders of a default MODx installation
   
require_once( 'wordpress' '/wp-load.php' );
}
?>



At the start of a MODx template, e.g. "Minimal Template", I put this

Code:
[!wp_bridge!]

Now, I created another snippet, called wp_function.  This looks like this :
Code:
<?php
$output 
'';
$output .= 'Blog name : '.get_bloginfo('name');
return 
$output;
?>


Creating a new document that uses this new template, I place the following call in it's content area :
Code:
[!wp_function!]
... which displays the name of the blog.

A bigger example of the info available is here :
Code:
<?php
$output 
'';
$output .= get_bloginfo('admin_email').'<br />';
$output .= get_bloginfo('atom_url').'<br />';
$output .= get_bloginfo('charset').'<br />';
$output .= get_bloginfo('comments_atom_url').'<br />';
$output .= get_bloginfo('comments_rss2_url').'<br />';
$output .= get_bloginfo('description').'<br />';
$output .= get_bloginfo('url').'<br />';
$output .= get_bloginfo('html_typen').'<br />';
$output .= get_bloginfo('language').'<br />';
$output .= get_bloginfo('name').'<br />';
$output .= get_bloginfo('pingback_url').'<br />';
$output .= get_bloginfo('rdf_url').'<br />';
$output .= get_bloginfo('rss2_url').'<br />';
$output .= get_bloginfo('rss_url').'<br />';
$output .= get_bloginfo('siteurl').'<br />';
$output .= get_bloginfo('stylesheet_directory').'<br />';
$output .= get_bloginfo('stylesheet_url').'<br />';
$output .= get_bloginfo('template_directory').'<br />';
$output .= get_bloginfo('template_url').'<br />';
$output .= get_bloginfo('text_direction').'<br />';
$output .= get_bloginfo('version').'<br />';
$output .= get_bloginfo('twpurl').'<br />';

$variable wp_list_categories('echo=0&show_count=1&title_li=<h2>Categories</h2>');
$variable str_replace(array('(',')'), ''$variable);
$output .= $variable;

$output .= wp_list_pages('echo=0');

return 
$output;

?>


Finally, I was also able to pull in the header, footer, etc. files via the "get" functions
in WP.  But there was a conflict with the existing style sheet that I was using, so I haven't
got the kinks worked out yet.  But I've begun to wonder if it's possible to have one set of
cleverly written templates that work in both MODx and WP.

As much as anything else, this was an effort to see if the same general approach could
be used in making Wordpress functions available in MODx as is used in making MODx resources
available in Wordpress.  Dunno yet where this will lead, but I thought I'd point this approach
out.

Matt

#2: 21-Jan-2010, 06:56 PM


einsteinsboi
Posts: 313

WWW
Thanks for sharing this! This is pretty interesting and neat, I'm going to have to play with it some Smiley

#3: 22-Jan-2010, 08:15 AM

mconsidine
Posts: 261

Well, for just for you-know-what-and giggles, I was able to pull up an essentially-unaltered Wordpress template from within MODx.  The layout wasn't perfect because I didn't try to use all the WP code in MODx, but it was close.

In MODX, I created the following snippet, called wp_bridge :
Code:
<?php
if (!defined('MODX_WP'))
{
     
define('MODX_WP','MODX'); //MattC
     /*
      * Tells WordPress to load the WordPress theme and output it.
      */
     
define('WP_USE_THEMES'false);

     
/* Loads the WordPress Environment and Template */
     
if ( !isset($wp_did_header) )
     {
$wp_did_header true;
require_once( 'wordpress' '/wp-load.php' );
     }
}
?>

This allows us to not load the MODX bridge routine that will be set up in Wordpress.  And vice versa (see below)

Next I created a new document template, the contents of which are
Code:
[!wp_bridge!]
[!wp_call!]

A snippet called wp_call is created and it looks like this :
Code:
<?php
get_header
();
get_sidebar();
get_search_form();
get_footer();
?>

This snippet is invoking the basic Wordpress functions to get and process various templates.  Just to see what would happen Smiley

In Wordpress, I have a file called modx_bridge.php which lives in whatever theme I am using.  It is based on Tim Spencer's work found here
http://timspencerweb.co.uk/blog/?p=3
There is another, similar, routine which can be found in the MODx archives which would probably work as well.  But I haven't tried it.

In any case, my version of that routine looks like this :
Code:
<?php
if (!defined('MODX_WP'))
{
// MODx integration
// -------------------------------------------------------------------------------
define('MODX_WP','WP');//MattC
// ----- CONFIG -----
define('MODX_SITE_BASE_URL''http://localhost/testsite/');
define('MODX_MANAGER_PATH''c:/xampp/htdocs/testsite/manager');
define('MODX_DOCUMENT_IDENTIFIER'206); // The MODx document we are going to pretend to be

// ------------------
// Some defines used by the modx API
define('MODX_API_MODE'true); // Tells MODx index.php to not run $modx->executeParser
define('MODX_SITE_URL', (!isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) == 'off' 'http://' 'https://').$_SERVER['SERVER_NAME'].MODX_SITE_BASE_URL); 

// Run the MODx config and get site settings
//$GLOBALS['database_type']='mysql';
require(MODX_MANAGER_PATH.'/../index.php');
$modx->getSettings();

//  Set the docid (most sensibly to the MODx weblink to here) and get the MODx document object
$modx->documentObject $modx->getDocumentObject('id'MODX_DOCUMENT_IDENTIFIER);
$modx->documentIdentifier MODX_DOCUMENT_IDENTIFIER;

// Set the base URL for any MODx snippets
$modx->config['base_url'] = MODX_SITE_BASE_URL;

// Get AND parse a modx chunk. Cannot cope with nested snippets within the chunk. 
function modx_chunk($chunk_name)
{
global $modx;
return $modx->rewriteURLs(str_replace('[~'MODX_SITE_URL.'[~'// Ensure that the link goes to the MODx site and not e.g. /blog/pagename       
$modx->parseDocumentSource(str_replace('[!''[['str_replace('!]'']]'$modx->getChunk($chunk_name))))));

}
?>

And it is included at the top of each Wordpress theme .PHP file like this
Code:
<?php require_once('modx_bridge.php'); ?>

With the variable "MODX_WP" available in both locations and MODx and WP functions available to the other app, I think it might be possible to have one set of layout and stylesheets for both apps.  Not being intimately familiar with the innards of either MODx or WP, I wouldn't be surprised if there is a ton of overhead that gets created, or that it is incredibly inefficient to do this.  And there may be a lot of good reasons not to do this.  But for the moment, ignorance is bliss.  Or at least entertaining ...

UPDATE : I got two WP widgets to run in MODx...

Matt
« Last Edit: 22-Jan-2010, 09:40 AM by mconsidine »

#4: 22-Jan-2010, 09:45 AM

mconsidine
Posts: 261

There's a bit more flexibility to be had if, instead of one snippet like wp_call (above), there are separate calls to the WP "get" functions.  So the template looks like :

Code:
[!wp_bridge!]
[!wp_get_header!]
<div id="content">
[*content*]
<div><!-- content -->
[!wp_get_sidebar!]
[!wp_get_footer!]

where each snippet has a form similar to this one (wp_get_header) :
Code:
<?php
get_header
();
?>


I've still got the sidebar ending up on the left as opposed to the right (using the "Scruffy" WP template I've been playing with), so there's still some tweaking to be done.

MattC

#5: 22-Jan-2010, 10:57 AM

mconsidine
Posts: 261

Of course, the fun couldn't last for long...

I'm trying to implement this in an online environment and getting this error
  Fatal error: Call to undefined method stdClass::set_prefix() in [...]/wp-settings.php on line 287
when trying to get the wp_bridge snippet to load in MODx.  ([...] is just the path on the testinstall I'm trying)

I suspect there's some include file that is not getting loaded, but not sure why that would be the case.  The versions of WP are the same (2.9.1).

Loading the modx_bridge works - I'm able to load a chunk and have it's contents displayed on the WP blog.  But I'm there must be some permissions or .htaccess or ... something that's different enough from the local install I was initially playing with to mess things up.  I'll report back if I ever get it figured out ...
MattC

#6: 22-Jan-2010, 05:34 PM

mconsidine
Posts: 261

This is a bit puzzling.  I had MODx and WP talking to each other on a local install, with MODx being v 1.0.0 and WP being and v 2.8.4 upgraded to 2.9.1

So I went to try the same trick on an online setup, using a clean MODx install (1.0.2) and WP install (2.9.1).  And promptly ran into the above problem.  Which seems to be related to the use of global variables, in part, by WP.  This type of error has been noted by others trying to pull info out of WP, at least according to Google.  (It seems that the 2.9.1 update has busted things for other people as well).

Still, I thought I should try things locally again with a clean Evo and WP install.  Same versions as the ones online, just local.  Pulling info from MODx into WP works, but when I tried my already-tested routine to get the blog name displayed in MODx, I get this error
Quote
« MODx Parse Error »
MODx encountered the following error while attempting to parse the requested resource:
« PHP Parse Error »
 
PHP error debug
  Error:    Assigning the return value of new by reference is deprecated   
  Error type/ Nr.:    - 8192   
  File:    C:\xampp\htdocs\wpmodx\blog\wp-settings.php   
  Line:    601   
  Line 601 source:    $wp_the_query =& new WP_Query();

So I'm guessing something changed between v1.0.0 of Evo and v1.0.2 of Evo to cause this.

Does anyone know of a flag that can be thrown which will treat this sort of thing as a warning rather than an error?  Is it possible to do that "on the fly" rather than having to mess with the default install options of MODx?

Or is this error a red herring, meaning the real issue lies elsewhere?  I'd note that I don't see any errors when running WP - which is why I'm puzzled about what is causing this.

Any perspective would be helpful.
MattC

#7: 22-Jan-2010, 06:54 PM

mconsidine
Posts: 261

Okay.  It would have helped if I had remembered that index.php in the MODx install needs to have this as the first line :
Code:
require('/blog/wp-blog-header.php');
where "blog" is the subfolder name where Wordpress lives.  (I suppose this could also be require_once ...)

Also, it appears that the recent install of WP did not have this
Code:
error_reporting(0);
on the first line of wp-config.php

I haven't run a complete check, but this seems to take care of the problem.

MattC

#8: 23-Jan-2010, 12:22 PM


einsteinsboi
Posts: 313

WWW
Just saying thanks again for this thread and for sharing your process Smiley

#9: 23-Jan-2010, 03:44 PM


Frank
Posts: 518

WWW
Hi,

thanks for sharing. Do you think you could work this out, with a doc so even I could understand it.
I have been trying to do the same, but I lack PHP skills, so keep up the good work,

frank

#10: 23-Jan-2010, 05:25 PM

mconsidine
Posts: 261

I'll try to write this up.  In the meantime, here's a live example of running WP widgets in MODx, with a link to the Wordpress blog, which itself pulls the MODx "Minimal" theme elements and uses that in place of it's default.  In this instance, I editted the Wordpress "classic" theme to pull the elements of the MODx theme it needed.  This did require chopping up the "Minimal" theme so that it was more Wordpress-ready, in a sense.

I'm not sure the databases was all that happy with this work.  Maybe my host was having a glitch, but at one point I got a database error and needed to revisit the site.  Didn't need to reload anything - it was more of a hiccup than a problem.  But one thing that had been working - using a snippet to return the title of a document in the "Title" field of the document settings - no longer works.  Dunno why.

In any event, here's the site
  http://www.considine.net/testinstall
You'll see the snowflakes, cartoon-of-the-day and quotes widgets that are installed in Wordpress as soon as you load the MODx page.  If you hit the blog, you'll see how the style is carried over.  Not completely gracefully, but I'm shooting for proof of concept.

Also, I've set up a demo user : username = demo pwd = modxwp.  If you log in you should be able to explore the template, chunks and snippets and see what I've been trying to do.

Finally, the Wordpress theme files that I editted are zipped up and available here
  http://www.considine.net/testinstall/wpmodx.zip

I can't reiterate enough that this is an experiment-in-progress and messing with this stuff might well screw something up.  So - caveat emptor!  But I hope it helps someone better than me come up with some clever routines.

MattC

#11: 25-Jan-2010, 01:20 PM

mconsidine
Posts: 261

Just testing something out and it appears that the "wp_bridge" snippet doesn't need to be called at the start of a template, if there is the include statement (noted above) in the "index.php" file.

And on the WP side, it looks like the "modx_bridge" code can be included in the functions.php file.  This then means that the "require_once" statement doesn't need to be included in the various templates.

...which simplifies things a bit.  I might find out that I've overlooked something, but if anyone is trying this out, it might be worth just testing those two changes first.

MattC

#12: 4-Mar-2010, 10:55 PM


hotdiggity
Posts: 248

Mostly harmless.

WWW
Quote
require('/blog/wp-blog-header.php');


should be just
Code:
require('blog/wp-blog-header.php');

(on Linux, at least)
Pages: [1]   Go Up
0 Members and 1 Guest are viewing this topic.