Acquia Lift's content syndication capabilities allow you to have a central repository, a Content Hub, for your content and syndicate it out to various connected sites. All the connected sites are able to send content to the Content Hub for use on any other connected site.
In an ideal world, all the connected sites would have matching content type and field machine names. However, in our reality, we had two existing sites where this was not true. We mainly wanted to send blog, event and webinar nodes from www.acquia.com (AC) to dev.acquia.com (DAC). What I will share with you here is how we got Acquia Lift's content syndication set up and syncing nodes between these two sites. Note that this is for Drupal 7.
When syncing entities using Acquia Lift's content syndication, if the machine name of the entity does not match, it gets ignored. For example, we have a field called field_webinar_start on AC, but the field is called field_event_date on DAC. So when I imported a webinar node into DAC, this field was ignored. Even if field machine names matched, the actual widget or settings of the field have to match too. That field_webinar_start field is a Date field. However, on AC it used the Date module timezone setting, but DAC had no timezone set. So even if the machine names matched, it still wouldn't sync. Even once that was fixed, I found that the actual timezone was not getting synced because the content syndication didn't manage that data. As of this writing, they are working on getting the timezone issue fixed, but until then, we have to manually set the timezone after syncing. There were quite a few fields where the machine names didn't match up, so that was one major obstacle for us.
Another obstacle we encountered was that content type names didn't match: event nodes were named event on AC and events on DAC. These would not import at all. And just to make things extra fun, if you have a taxonomy term reference field, the machine names for the vocabularies on the two sites have to match too. The term names can be found if the text matches, but if vocabulary machine names don't match, the reference field is ignored.
OK, so how did I go about fixing machine names for fields and content types? Luckily, some other clever people have hit the same issues for other reasons (not related to Acquia Lift) and have created some very useful modules to help with this. The Field Rename module works really well to rename fields. As an added bonus it also renames the fields if they're used inside of Views. Note that it doesn't do this for the field name if it's used inside a rewrite field. But at least you know which Views to look into for those and you can go and manually change those.
The last thing that I needed to do was create some custom code using hook_node_presave() so that I could finesse come of the incoming data.
Let's go into more detail on exactly what I did using the 3 approaches above. I'll start with converting Events into Event nodes, as it's the quickest explanation. Using Bundle Copy, I exported the Events content type from DAC. You get a bunch of text that you can copy and paste into a text editor. I then replaced the word "Events" with "Event", making sure I maintained the case of the letters. I left all the field names as they were to make this step simpler. Using Bundle Copy's import option, I pasted in the modified export and that created the Event content type. So now I had Events AND Event content types.
All the content was still using the Events node type, so using Node Convert, I created template that copied every field from Events to Event node fields. I created a Views page that listed all the Events node titles along with a Views Bulk Operation field, and selected Node Convert in the list of allowed bulk operations. Looking at the page itself, I had a list of Events titles, with checkboxes in front of each one. I ticked them all off, selected the Node Convert operation, chose the template and set it running.
Now I had all those nodes as Event nodes. Before you get too excited, just remember that anything that referenced the Events node type now has to be changed to reference Event nodes e.g. Views, Panels, node reference fields and custom code (preprocess functions, for example). So I manually tracked all those places down and switched things to the right content type. Once all that was done, I could delete the Events content type.
Field renaming & creation
Now that the easy part was done, I had a whole bunch of fields to rename. I quickly realized that some fields were used in multiple content types, and on AC, the fields had different names in different content types. So in a few cases I had to not only rename the field, but create a new field so that field names would match between the different content types we wanted to sync.
Let me explain that better with an example. On DAC we had a field_products taxonomy term reference field that was used in blog and webinar nodes. On AC, though, blog nodes used field_blog_product_ref and webinar nodes used field_acquia_product (so much for consistency). So if I renamed field_products to say, field_blog_product_ref, the field would sync for blog nodes, but not for webinars. So for webinar nodes, I created a new field_acquia_product field. Using Views Bulk Operations and the option to Execute Custom PHP, I could copy the existing data from field_products to field_acquia_product using the following code:
$entity->field_acquia_product = $entity->products;
Luckily I only had to do the creation bit for two fields: field_webinar_start was the other one. In that case it was because of the timezone setting. After creating the field to match AC, I used VBO to copy existing dates to the new field. Once the data was in the new field, I had to go find all the places that field was being used - the same places I had to look for Event nodes.
Actually renaming fields was quick and easy in comparison to the creating of new fields, because the Field Rename module tells you which Views the field is used in. Don't forget, I had to still double-check every rewrite field manually, but the haystack was a lot smaller this time. The only other place that I had to manually check was our custom code (modules and theme). Once I had all those nailed down, DAC looked like it did before I started messing with it :)
Custom coding (optional)
On DAC event nodes, we have a field that stores the event year in it. We don't have a matching field on AC, so using hook_node_presave(), I added some code that checked the event date field, and then sets the year to match. I believe this function can be used to do much more tweaking of incoming values. In particular I'm thinking about vocabulary machine names. Currently we have to manually tick off taxonomy terms because vocabulary names don't match, so the data doesn't sync. I'm hoping that I can use the presave function to change the vocabulary name to match and then have terms set automatically. It would required a hard-coded array, so it's not ideal, and I haven't tested this yet, either. If it works, I'll update this blog post.
Content Syndication at Work
So I finally had matching fields where I needed them (we ignored some that were specific to AC or DAC) and I was ready to actually enable Acquia Lift's content syndication suite of modules on both AC and DAC. I added the various settings to allow blog, event and webinar nodes to be synced, and I was ready to go. I edited a blog node on AC, and saved it so that the content syndication would see it. I switched over to DAC and saw the blog node in the content syndication content list. I selected it and imported it. One final snag quickly became apparent: a custom text format we had on AC didn't match the one we had created on DAC, so I had to edit the node and select the right text format. Once that was done, the node appeared correctly and the things were good again in the world. Now, any blog, event or webinar that is saved on either AC or DAC will appear in Acquia Lift's content syndication content list and can be imported to the other site.
There are a few caveats with retrofitting Acquia Lift's content syndication to two somewhat unrelated sites:
- If user ids don't match (they don't on our sites), the node author will be the user that imported the node. You have to manually change this if you need a specific author on the node. This will apply to a user reference field too, by the way.
- The published date gets set to the date you imported the node.
- Node reference fields won't sync unless node ids match between the sites.
Acquia Lift's content syndication capabilities allow you to have a central repository, a Content Hub, for your content and syndicate it out to various connected sites. All the connected sites are able to send content to the Content Hub for use on any other connected site.Acquia Developer Center October 20, 2016 November 1, 2016