Web Development Category

Widget to Translate Blog Link Categories with WPML

I’ve been using the WPML plugin on a few sites recently to turn Wordpress into a very powerful multilingual CMS, with great success. I really have to applaud these guys for building a very useful plugin. On the to-do list is integrating their plug-in with Wordpress’ built-in widgets. A few people have mentioned getting stuck when trying to use the Links feature of Wordpress, which does not currently work with WPML.

To fix this issue, I’ve thrown together a quick widget that acts as a wrapper for Wordpress’ built-in widget, but lets you set a different link category for each language you have setup using WPML. I hope you find this useful.

To install, copy and paste this into your theme’s function.php file or insert code into a file in the plugins directory.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
add_action('widgets_init',  array('LinkTranslationWidget','register_widget'));
 
class LinkTranslationWidget extends WP_Widget
{	
 
	function LinkTranslationWidget() {
 
		/* Widget settings. */
		$widget_ops = array( 'classname' => 'LinkTranslationWidget', 'description' => __('This widget allows you to set different link categories to display based on a language setting.', $this->plugin_name) );
 
		/* Widget control settings. */
 
		/* Create the widget. */
		$this->WP_Widget( 'LinkTranslationWidget', __('WPML Links'), $widget_ops );
 
	}
 
	function register_widget()
	{
		register_widget('LinkTranslationWidget');
	}
 
	function widget( $args, $instance ) {
 
		global $sitepress;
 
		if(class_exists('WP_Widget_Links')) {
 
			$link_widget = new WP_Widget_Links();			
 
			if(isset($sitepress))
			{
 
				$lang = $sitepress->get_current_language();
				$instance['category'] = $instance[$lang.'_category'];					
				$link_widget->widget($args, $instance);
 
			}
 
 
 
		}
 
	}
 
	function update($new_instance, $old_instance) {
 
		$new_instance = (array) $new_instance;
		$instance = array( 'images' => 0, 'name' => 0, 'description' => 0, 'rating' => 0);
		foreach ( $instance as $field => $val ) {
			if ( isset($new_instance[$field]) )
				$instance[$field] = 1;
		}
 
		$langs = $this->GetLangs();
		foreach($langs as $lang=>$lang_id)
		{
			$instance[$lang.'_category'] = intval($new_instance[$lang.'_category']);
		}
 
		return $instance;
 
	}
 
	function form($instance) {
 
 
 
		$settings = $this->GetSettings();
		$langs = $this->GetLangs();
 
		$instance = wp_parse_args( (array) $instance, $settings );
 
		$link_cats = get_terms( 'link_category');
 
		foreach($langs as $lang=>$lang_id)
		{
			echo '<p><label for="'. $this->get_field_id($lang.'_category').'">'. __('Select Link Category') . ' (' .$lang.'): </label>';
			echo '<select id="'. $this->get_field_id($lang.'_category').'" name="'. $this->get_field_name($lang.'_category').'">';
			foreach ( $link_cats as $link_cat ) {
 
				echo '<option value="' . intval($link_cat->term_id) . '"'
				. ( $link_cat->term_id == $instance[$lang.'_category'] ? ' selected="selected"' : '' )
				. '>' . $link_cat->name . "</option>\n";
			}
			echo '</select></p>';
 
		}
		?>
		<p>
		<input class="checkbox" type="checkbox" <?php checked($instance['images'], true) ?> id="<?php echo $this->get_field_id('images'); ?>" name="<?php echo $this->get_field_name('images'); ?>" />
		<label for="<?php echo $this->get_field_id('images'); ?>"><?php _e('Show Link Image'); ?></label><br />
		<input class="checkbox" type="checkbox" <?php checked($instance['name'], true) ?> id="<?php echo $this->get_field_id('name'); ?>" name="<?php echo $this->get_field_name('name'); ?>" />
		<label for="<?php echo $this->get_field_id('name'); ?>"><?php _e('Show Link Name'); ?></label><br />
		<input class="checkbox" type="checkbox" <?php checked($instance['description'], true) ?> id="<?php echo $this->get_field_id('description'); ?>" name="<?php echo $this->get_field_name('description'); ?>" />
		<label for="<?php echo $this->get_field_id('description'); ?>"><?php _e('Show Link Description'); ?></label><br />
		<input class="checkbox" type="checkbox" <?php checked($instance['rating'], true) ?> id="<?php echo $this->get_field_id('rating'); ?>" name="<?php echo $this->get_field_name('rating'); ?>" />
		<label for="<?php echo $this->get_field_id('rating'); ?>"><?php _e('Show Link Rating'); ?></label>
		</p>
 
		<?php
 
	}
 
	function GetLangs()
	{
		global $sitepress_settings;
		$langs = $sitepress_settings['default_categories'];
		return $langs;
	}
 
	function GetSettings()
	{
		$settings = array();
 
		$settings['images'] = true;
		$settings['name'] = true;
		$settings['description'] = false;
		$settings['rating'] = false;
		$langs = $this->GetLangs();
		foreach($langs as $lang=>$lang_id)
		{
			$settings[$lang.'_category'] = '';
		}
		return $settings;
	}
 
}

Use TinyMCE in your Wordpress 2.8 Plugin

Okay, so when you try to include the tinyMCE code using wordpress’ built in wp_enqueue_script() function, it does absolutely nothing. If you try to manually include the script, you’ll end up with all sorts of javascript errors, and missing language translations. However, if you simply call wp_tiny_mce(); in the template_redirect or wp_head function, all the javascript for tiny_mce is loaded properly. Then all you need to do, is run your tinymce.init script to setup your text editor. For example:



Solution: Wordpress Pagination Stays On Same Page

This was a big head banger.

If you are are using query_posts multiple times on a page, and are trying to paginate the second loop on the page, the following

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

will always return 1, Unless you place wp_reset_query() below the previous loop.


rewind_posts();

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

query_posts(
array(
'cat'=>‘5′,
‘orderby’=>’date’,
‘order’=>’DESC’
)
);

if(have_posts())
{
?>
// Post template goes here.
}
wp_reset_query();
?>

Pagination should now work for the next loop.

Template for Writing Your First Wordpress Plug-in

It seems like only yesterday, I set out to build my first ever Wordpress Plug-in. Bright eyed and bushy tailed, I poured over the Wordpress Codex, putting together the pieces of the process until I finally got the big picture. The Wordpress Codex is an amazing resource for anyone looking to get into Wordpress development; I strongly recommend any new developer read through the “Writing a Plugin” section.

While learning, I had a difficult time finding a straightforward template I could use as a base for my plug-ins. I wanted something that was clean and well-organized but also provided examples of more complex behaviours, such as: Internationalization, Widgets and Front and Back-End Ajax. I wanted to ensure my plug-in functionality was encapsulated inside a class structure so my functions and variables wouldn’t conflict with the Wordpress Core, or other plug-ins.

I’ve finally gotten around to writing this template plug-in, and I thought I would share it with the community to get your feedback and improvements, and hopefully save new developers some time. If you are interested in learning how to build a plug-in, and have a strong programming background, you can look through my sample code, read the comments and pretty much piece together how everything works. If you want a more thorough description of what is going on, read through this article.

You can download the plug-in from the Wordpress Plugin directory.

Getting Familiar With the Brolly Template Plug-in

  1. Download the template plug-in.
  2. Place the files in the plug-ins directory of your development installation of Wordpress.
  3. Come up with a unique name for your plug-in, such as MyPlugin. Check the Wordpress Plug-in directory to ensure this name hasn’t been used.
  4. Rename the plug-in folder from B2Template to your plug-in name (i.e. MyPlugin). Do not use spaces or special characters.
  5. Rename the file B2Template.php to MyPlugin.php
  6. Rename the file B2Template.class.php to MyPlugin.class.php
  7. Rename the class inside MyPlugin.class.php from B2Template to MyPlugin
  8. Rename the constructor function inside MyPlugin.class.php from B2Template() to MyPlugin()
  9. Activate the plugin from the Wordpress Plugin Administration Panel
  10. Add the Template widget to your sidebar from the Wordpress Appearance Administration Panel
  11. View your site, and interact with the widget to observe it’s behaviour
  12. From the Wordpress Administration page, click on Settings, and select MyPlugin.
  13. Interact with the plugin from this page, to view its behaviour.

How to Write a Plugin Using the Brolly Template Plug-in

Note: Substitute B2Template in the instructions below, to whatever you named your plugin (i.e. MyPlugin).

There are two main files in the Brolly Wordpress Plug-in Template. The first, B2Template.php, is used to initialize the plugin and route various Wordpress actions and filters to class methods in the second file, B2Template.class.php. Keeping all our plug-in functions inside a class gives us greater flexibility to reuse the code we write for the plugin. It also prevents naming conflicts from occuring when multiple plug-ins use the same function or variable names.

Continue reading.. ›

Mayfair Theatre Case Study: Holy APIs Batman!

We’ve just rolled out a new project, here at Brolly. Our client is, the Mayfair Theatre, a local independently run movie theatre in Ottawa, Ontario. The theatre recently closed down for renovations and is now under new ownership. Their web site was in serious need of an update, so we took the opportunity to do some really new and exciting things. We have been very excited about this project – it gave us great freedom to further develop our experience in social media and focus on providing meaningful interaction between our client and their customers.

Mayfair Theatre Case Study

Like many of our other projects, the website is built upon the WordPress platform. We built a custom plugin for them to manage their upcoming movie listings. This plugin has some great features:

IMDB Integration

The Wordpress plugin allows the Mayfair Theatre to manage their upcoming movies and showtimes. Instead of forcing the administrator to enter in details for each movie that’s playing, we interfaced with a very neat movie database api, called The Movie Database, to allow them to import upcoming movie information, YouTube trailers and high quality artwork. This feature will saves huge amounts of time.

Twitter Integration

We set up the theatre with a twitter account, @mayfairtheatre, and used the Twitter API to automatically broadcast what movies are playing on a daily basis. We are encouraging users to follow the theatre’s Twitter account with a series of giveaways including: movie passes, free concession coupons and movie posters. We believe that keeping people informed of show times on a daily basis will greatly improve attendance.

Google Calendar

Another way we are keeping users up-to-date on the movie schedule is by integrating show times with Google Calendar using the Google API. This calendar stays synchronized with the online schedule and allows users to add the calendar to their computer and mobile devices.

By leveraging existing APIs we were able to build a lot of great functionality into the site, within a limited budget and short development cycle. It seems like every day we are finding new and exciting ways to expand WordPress to accommodate the diversity of our clients. Look for more exciting plugins and services coming soon!

Aurora Importing Case Study: Wordpress Plug-ins for Business Applications

In response to the current state of the American economy many companies are looking for innovative methods of reducing costs. A business looking to develop or overhaul their corporate web presence should consider shedding their expensive content management system for a lower cost alternative. Companies have heard a great deal in the last few years about the benefits of open-source. The recent culture of belt-tightening that has spread through all major industries provides companies with an excellent opportunity to explore these technologies.

Here at Brolly, we have just launched a new corporate website for Aurora Importing and Distributing, a medium sized Canadian food importing business, built entirely on the WordPress platform.

Auroa Importing

Continue reading.. ›

Q/A: How do I add multiple WordPress widget sidebars?

I’m putting together my first WordPress theme which requires three dynamic sidebars (don’t ask!!). For some reason I can’t figure out how to add the other two dynamic sidebars.. Could you help me please?

Adding in multiple sidebars is fairly straightforward and you can create as many as you need.

Locate your functions.php file in your theme and add the following code:

1
2
3
4
5
6
7
8
9
10
<?php
     if(function_exists('register_sidebar'))
          register_sidebar(array(
          'name' => 'Sidebar One', // The sidebar name to register
          'before_widget' => '<div class="widget">',
          'after_widget' => '</div>',
          'before_title' => '<h3>',
          'after_title' => '</h3>',
     ));
?>

Continue reading.. ›

Quick Fix: Javascript Loaded into DOM From AJAX doesn’t Execute?

So I’ve been beating my head around this problem for the last couple of days. For a project I’m working on, I have a series of modal windows that pop up using the amazing Shadowbox library. I’m using a custom ajax player for shadowbox that uses prototype to load in a new page into the DOM and display it as a shadowbox. Everything was going great until, I started trying to run javascript from inside my modal window.

See, javascript that gets added to the DOM after a page is loaded does not get run. You don’t even seem to be able to reference functions that are loaded after the initial document load. So I needed a solution so that my AJAX calls from within the modal windows would function. After two days of thinking this out, I came up with a very simple low tech solution:

1
2
3
4
5
6
7
8
9
10
11
function parse_new () {
     var shadowbox = document.getElementById('shadowbox');
     var scripts = new Array();
     scripts = shadowbox.getElementsByTagName('script');
 
     for(i=0; i < scripts.length; i++) {
          if(scripts[i].getAttribute('type') == 'text/javascript') {
          eval(scripts[i].innerHTML);
          }
     }
}

Basically whats going on here, is that after I load my shadbowbox, I get a reference to that element, search for all the script tags inside it with type = text/javascript, and evaluate it. Hope this helps someone out!

CakePHP + ACL concepts from a (former) noob

While there are plenty of tutorials out there covering how to use CakePHP’s ACL Component, and getting it to jive with CakePHP’s Auth Component, most of the tutorials out there take different approaches towards implementing this technology. If this is your first time using ACL, you might be feeling a little confused about exactly how ACL works, and if you’re like me, diving through all of these conflicting tutorials (some which use deprecated functions based on prior versions of cake) only serves to further confuse.

So now that I’ve spent a good couple of days wrapping my head around this concept, I thought I’d share what I’ve learned with you, so hopefully you can get this up and running much quicker than I did. To do this you’re going to need to understand some basic concepts of ACL, reading up on this in depth will only help you. I’ll try and point out some of the major pitfalls I ran into, so you don’t make the same mistakes. I’m not going to give you code, since this will just further confuse you. You’re going to have to write a fair bit of code on your own to get this working for your application. But I will provide a link to my source code for my project and an sql dump of my ARO tables so you can see what they should look like at the end of the tutorial.

Step One, What You Need to Learn

ACL basically defines what actions each person or group (AROs) can do to each item (ACOs). The important thing to remember is that an ARO and an ACO are really exactly the same. In a web application, everything is a row in a table. Each user or group or post or comment is just a row in the User, Group, Post or Comment table. So what we are doing is saying, when someone is logged in as a certain row in the User table, which rows in the Post table are they able to access? Groups are used so that users can inherit permissions. This saves us effort and results in fewer rows in our ACL tables because we don’t have to redefine permissions for each user, they simply inherit the permissions of the group they are in. A user can have a combination of any of the following permissions on an item: create, read, update and delete.

Setup the ACL tables by following the ACL section of the CakePHP manual. Once you have it setup, open up phpmyadmin or cocoa and have a look at the tables that were created, they should be acos, aros, and aros_acos. Lets look at the fields in these tables to understand what is going on. If it helps, whenever you see ARO think User, and whenever you see ACO think Post.

Continue reading.. ›

line