Close

John Morris

I'm a Developer at WishList products, creators of WishList Member, instructor for the WishList Member Certified Developers program, and creator of numerous WordPress plugins and PHP applications.

How Wealthy Developers REALLY Succeed

You know, I’ve spent a lot of time teaching coders technical skills. How to upload files using PHP, how to create website templates, how to hack, twist and mold WordPress to your will, and so on.

In fact, the entire site over at LearnPHP.co is about exactly this when it comes to PHP. I have an entire category on this site called Code Snippets where I do exactly that. All of my YouTube videos do the exact same thing.

But, to be honest, I’ve never really talked much about what it REALLY takes to be successful as a developer. Because, while all that technical mumbo-jumbo is cool… none of it REALLY matters.

Yes, you need to know how to do those things… but those things aren’t what MATTER most when it comes to determining the successful from the unsuccessful. Any monkey can learn to code.

And, there’s 1000s of coders out there who can do all those “cool” things who struggle to get by day after day. People “who can code” are a dime a dozen.

What’s rare is a “Coder”. An artist. Someone who has a point of view about what/how/why they code. Someone who’s so passionate about what they do they’ll not just tell you no but “hell no” when you ask them to do something that they feel violates their art.

So…

You WANT to be one of these coders. Because you’ll make more money. Because you’ll be more appreciated. Because you’ll be happier.

What do you need to do to get there? Here’s some things I’ve picked up from the successful coders (and artists in general) I’ve been around… things I try to integrate into my work:

Be a Picky Bitch

This is my slang way of saying “have a point of view”. I see so many coders who don’t really care about the code they write. Their standard for their code is “it works”. They’ll bend to the will of any client no matter how asinine the request is.

The successful coders I know don’t do this. Meeting them… you might even think, “Man, that guy/girl is a whiny picky bitch”.

Yep. They have a point of view and own it. But, most good artists do.

My guess is if you happen to be around when Michelangelo was painting the Sistine Chapel and told him to use red instead of blue… you’d have been thrown out in a fiery rage.

Why? Because he, and only he, knew what his art was. He knew what his perspective was and he was going to express it his way regardless of what you might think of it.

All the successful coders I know are this way. Hell, all the successful anybodys I know are this way.

My boss, Stu McLaren, is this way. I don’t know how many times I’ve been working on a project with him and at some point told my wife, “Man, he’s a picky bitch”. 🙂

But, you know what… he’s almost always right. And, the stuff he does works. Because, he has a point of view based on years of practical experience and he’s willing to stand up for it.

And, in the long run… I appreciate it. I wouldn’t want to work with anyone else.

So, don’t be afraid of being a picky bitch. Be proud of it. Own it. Because, it’s based on your point of view… your art. And, in the long run, people will appreciate you for it.

Be a Megamind

For coders specifically, I believe the single most important skill you can ever develop is the ability to mentally abstract. I believe that how well you can mentally abstract is inextricably linked to how good your applications will be.

For your applications to get better, you have to get better at abstraction.

If you think about, ultimately that’s what coding is. You’re taking a specific instance of something and abstracting it out into functional code that will work across instances. The bigger your application becomes (i.e. the more it “does”) the more abstraction is required.

All the successful coders I know are wizards at this. They have this uncanny ability to simultaneously hold the full scope of their applications in their mind and focus on the fine details of any individual part.

The best example I have of what it’s like is a mind-map. If you’ve ever done any mind-mapping, you’ll know the power of it is in the ability to get a large-scope view of an entire idea while simultaneously having the fine details of any particular part available at a moment’s notice.

This is what good coders can do.

Of course, the big question is “how do you get better at it”. The answer is you code. You try building bigger and bigger applications and have the ability to keep going when you look back on old code and want to puke.

You’ll never really be completely happy with your code… ever. Especially old code. But, to others, it will seem elegant. It’s kind of like an artist who’s never fully satisfied with a particular painting (that’s why he/she keeps painting)… but to others, the painting is gorgeous.

You just have to keep coding and pushing yourself… and you’ll necessarily get better at abstracting.

Be Like a Dog on a Bone

That is, be tenacious. As a coder, you have to have a dogged persistence with details. You have to care about every last minute detail. For you, “good enough” can never be good enough.

All the successful coders I know are bloodhounds when it comes to details. They iterate over and over and over their code. They labor to make sure every character is where they think it should be at that time.

That’s not to say that they’re perfectionists that never ship. On the contrary. Good coders ship early and often… before they’re ready. But, they’re never done. You’ll find them up late at night working through a 10-line block of code to make sure it’s perfect.

And, once it is… they’ll move onto the next 10 lines.

Of course, a lot of that passion comes from having a point of view. When you have a point of view, you know exactly how you want something to look and function… and you won’t rest until it looks and functions how you want.

And, once it does…  you’ll find ways to make it better.

This is the kind of tenacious attitude all good coders I know have.

You just can’t be afraid to be a little OCD. Don’t worry. You’re not weird. We’re all that way. If you can’t sleep in the middle of the night, because a certain piece of code you want to fix is driving you nuts… you’re on the right track.

At the end of the day, this is the kind of tenacity and passion your clients will appreciate.

What Else?

These are a few of the biggest pieces of the puzzle I’ve identified… but by no means is this list exhaustive. I plan to add to it as I see fit. But, what characteristics have you seen in successful coders? How are they different from the coders you see struggle? How have you tried to implement those skills in your coding?

Share your thoughts in the comments below.

(photo by Ludovic Toinel)

April 4, 2013

How NOT to Hire a Freelance Developer

I’ve seen a rash of really bad job postings on Elance lately and I thought I’d step in to offer a little (ahem) constructive criticism.

Here’s the thing. Bad job postings are bad for everybody, because they lead to unclear expectations. Developers hate it because we have no idea how to bid these kinds of jobs… and the job posters hate it because they always end up paying more and getting less.

Now, certainly there’s something to be said for how a developer should submit their proposal back; however, 1) I can’t see how other developers do it, so I have no case studies and 2) it’s hard to critique the proposal if the job posting itself is jacked.

So, here’s a list of things NOT to do:

1. DON’T Be Ultra-Concise

I’ve literally seen listings like this:

I need a custom WordPress theme.

Then, the job will be listed as a fixed price job and the budget will be “not sure”.

As the developer, there’s almost nothing I can do with this. Yes, I can submit a proposal without a price and ask all those questions, but here’s the rub for you the business owner:

A good developer won’t.

Good developers (the kind you want) aren’t desperate. They have plenty of work and generally only look through job postings every couple weeks or so when other projects are finishing up.

And, they’re picky. They won’t take just any client. And, they’ve been around the block enough to have developed a sort of “radar” about what projects to avoid.

And, this is the kind of project they’ll pass right over.

What this kind of job posting does is attract more desperate developers… developers who will take just about any job. Developers who haven’t worked on enough projects to know when to walk away.

In a nutshell, NOT the kind of developer you want.

Instead, take a few minutes (or hours) and really think through your project. Flesh out the details. Know what you want. If you can, develop mock-ups of exactly how you want it to look and function.

You’ll attract better developers and you’ll get better proposals and you’ll know right away which developers paid attention and which ones didn’t. And, your chances of landing a quality developer are much better.

2. DON’T Be Incomplete

Here’s a perfect example of how to be incomplete:

This is a high level description and does note reflect the final description. Some more features will be added. Your bid should reflect the total price for the entire project considering these requirements represent 70% of the total requirements.

The big problem with this is it was posted as fixed price job. If it was a posting for an hourly job, it’d make more sense, because the details could be fleshed out and they’d be billed at the hourly rate.

But, for a fixed price job?

I’m not sure how you can expect someone to bid your job accurately when you’ve only given them a vague description… and it’s not even the WHOLE description. Details matter when bidding a job like this.

It’s hard enough for a developer to estimate how long a job will take them… even with a full, detailed description. A proposal like this will typically get two types of proposals:

  1. Overbids. Developers who at least recognize that the scope of this project will most likely increase pretty dramatically and they will bid accordingly so as to not be accused of “jacking up their prices” later.
  2. Underbids. Desperate developers who just want the job and who will bid it low to win. But, once it comes time to actually build out the project and they see how much they have to do and how little they’re getting… are very likely to abandon the project.

Neither is accurate and both will lead to turmoil down the road.

Instead do one of two things:

  1. Either, flesh out the details of the project before-hand and post a full description including mock-ups, if possible.
  2. Or, post it as a hourly rate job and be willing to pay the developer for non-development time… that is, time helping you flesh out the details.

Personally, I specifically avoid fixed price jobs with incomplete descriptions because it’s the perfect breeding ground for massive scope creep… and generally it’s the developer that takes the heat when timelines and budgets get blown.

So, to attract good developers… be complete.

3. DON’T Be a Douche

I see postings all the time with some sort of harsh language in them like:

Note: Don’t be lazy and actually read this posting before submitting a proposal.

Or something along those lines.

Here’s a hint for you…

The people who don’t read the postings… don’t read the postings. Whether because they’re using some sort of software to auto-submit or they’re copying and pasting their proposals… whatever the method… they’re NOT reading them.

Which means they’re NOT reading your note about not reading the posting.

On the other hand, the developers who DO actually read the job descriptions see that note and are immediately turned off. Again, good developers have developed a kind of “radar” about these things and they’re constantly looking for cues as to what type of person they’d be working with.

And, this is a major red flag. It screams snarky and good developers will move on.

Again, you’ll end up with desperate developers who need the money… and who are more likely to abandon you later.

Instead, just do what you’re doing anyway without actually feeling the need to state it. That is, immediately ignore the proposals that obviously did not read your job posting. It’ll be pretty easy to spot. Just ignore them and move on.

Because, you’re GOING to get them whether you put that note there or not. Sad but true.

And, that way you don’t send any red flags to the really good developers… the ones you want.

Don’t Try to Buy Steak From McDonalds

Another important point to consider here is the quality of the network in which you’re searching for freelance developers.

You wouldn’t expect to get a high quality New York Strip from McDonalds’ dollar menu… so why do you think you can find a high quality developer on a price-oriented network for $5/hour?

You can’t.

The standard approach is to visit an “open” freelance network like Elance, oDesk or Freelancer.com… post your job and watch as 800 Tom, Dick and Harry’s harass you about how great they are.

With these open networks, it doesn’t take much to get approved as a freelancer… and the onus is on YOU to separate the wheat from the chaffe.

Even worse, all you have to go on is a written service description, a limited portfolio, and some ratings.

If you’ve spent any time on these sites, you know most of the freelancers all tend to blur together after awhile and it’s difficult to know who is really great.

But, a new breed of freelance site is emerging.

These new sites are much more aggressively curated. Sites like Crew and Ziptask (among others) curate the freelancers for you by making them go through a rigorous application process.

This means only the best, most committed developers get through.

Probably the most unique of these I’ve seen is Ziptask.

When you land on the home page you see a live video feed of an actual project manager waiting to answer any questions you have and work with you to build a team for your project.

You click “Get Started” and you can be chatting with an expert in seconds… and that expert will work with the necessary developers for you to get your project complete.

It’s immediate and managed. And, it’s impressive. I have yet to see anything else where you can be talking to someone so quickly.

But, regardless of what network you go with… you need to understand what you’re getting into. If you go with a site like Elance or oDesk, it’ll be on you to curate and manage your developer.

With a curated site like Ziptask or Crew… they handle those things for you.

So, don’t try to buy steaks from McDonalds. Recognize if you’re set on going to McDonalds… you’ll probably have to settle for a cheeseburger.

Who’s Advice Should You Take?

Finally, I want to talk a little bit about this whole business of giving advice on how to submit job postings and hire developers on freelance sites.

I see a lot of marketers offering advice on how to submit your postings on sites like Elance and oDesk.

That’s cool. I’m sure it’s valuable to see how they do it.

But, BE careful. A lot of the advice I see… from the developer’s perspective… is… well let’s just say “not quite accurate”.

Here’s my favorite I see a lot of marketers teaching:

This job should be easy for someone who knows what they’re doing.

I see marketers teaching that you should put this at the bottom of every job posting.

Look, I get what you’re trying to do… but we’re not dumb. A good developer sees right through this. Insulting my talent to try and get a lower price won’t work. I’m going to bid the job what I think it deserves regardless of how easy you happen to think it is.

Because, frankly, I know you don’t actually have a clue how easy something is or is not. If you did, you’d just write it up yourself.

More probably, a good developer will just move on… because we’re picky. And, you can choose from all the leftover, desperate and  unseasoned developers who are probably going to make your life miserable.

Have fun with that.

But, at the end of the day… we really do want to help you. We love watching your project come to life, seeing how excited you get, and watching as you launch and start bringing in those first dollars, and so on.

It’s a great experience that we get to re-live project after project.

It’s just those first few encounters. They set the tone for the entire relationship… and, if you heed the advice above when crafting your job postings, you’re much more likely to attract quality developers who will actually bring your project to fruition.

And, that’s good for everybody.

April 2, 2013

How to Monetize Your Content in 2014

What will the future of content monetization look like? Are we forever stuck with an ad-based, privacy-encroaching business model (ala Facebook)? Does the failure of NewsCorp’s “The Daily” mean fee-based content is dead? What is the trend and how can you profit? These are the questions I want to answer in this article.

I’ve been thinking about content monetization a LOT lately. Not because I’m weird, but because that’s what the company I work for (WishList Products) does… at least in my eyes.

Right now, we call ourselves a membership site plugin, but let’s be real… our software does a lot more than pure membership site functionality.

To me, a “pure” membership site is one with a recurring fee that publishes ongoing content. WishList Insider is a membership site.

And, this is what WishList Member was originally built around… and something it does VERY well. But, it’s not all it does.

For example, WishList Member lets you set up products that can be purchased with a one-time fee… e.g. I charge a one-time fee of $19.99 for lifetime access to my PHP5 Decoded Program at LearnPHP.co.

Nothing about that says “membership site”… not in “pure” terms.

Or, how about the Pay-Per-Post functionality in WishList Member? Paying a one-time fee for access to a single post. Again, nothing about that says “membership site” to me.

What it DOES say (read: scream) to me is: “Content Monetization”.

All of these things, including a pure membership site, are ways of monetizing content.

But, who cares? It’s just semantics, right?

I don’t think so. You see, the web is in a state of trying to figure out content monetization right now. The traditional media models that worked in print, radio, TV, etc… don’t work as well online. And, frankly, I think the current model is broken.

Think I’m kidding? Consider that News Corp spent 10s of millions of dollars testing a new method of Content Monetization (news, in this case).

They created the first iPad only subscription-based news service called “The Daily”.

And, after a couple years of losing 30M annually, they finally shut it down.

Now, why would such a large news and content company spend that much money testing a new model if the current ones were working great?

Remember, NewsCorp is the company that owns massive news and entertainment companies like HarperCollins, the New York Post, the Wall Street Journal, GQ, Vogue, all the FOX variations, and more. And, they are the world’s second largest “media” group in terms of revenue.

So, again, why would they risk millions of dollars testing a new content monetization model?

I think it’s because they see the writing on the wall. As I said before, I think the most popular content monetization model is broken and unsustainable over the long-term.

What is that model and why is it broken?

It’s the advertising model. You get a bunch of people to visit the pages on your website and advertisers pay you to run their ads on those pages.

Most big websites charge per impression (pageview) not per click… so, the more people you get to visitor your site the more money you make.

Seems perfect in theory.

You can focus on writing high quality content on a regular basis which your readers love… and you continually build your traffic over time and allow advertisers to gain exposure with your audience which they love… and you make a steady income without having to “sell” anything… which you love.

Win-win-win. Everybody’s happy.

Except it never works that way in reality. Instead what happens is you become beholden to your “sponsors” (people paying you to advertise on your site)… and all they care about is exposure. They want pageviews.

You want to keep your sponsors happy and keep the money coming in so you start to focus more on how to generate pageviews… and you quickly realize it doesn’t matter if people actually read your content… only that they VIEW it.

You get paid for the impression whether someone actually reads your article (views your video) or not. And, this has dire consequences.

You end up spending more time writing the headline for your article than you do the article itself.

You could care less about the accuracy of your article as long as it is something that will generate controversy… and thus pageviews.

In the end… instead of peddling wholesome fruits and veggies to your readers… you sell them crack… and could care less how the rest of the world is affected as long as you get yours.

You don’t need to look far to see this actually happening. Look at any of the major news sources out there and you’ll see it’s all about drama.

You’ll see cleverly crafted headlines designed to generate the most dramatic response… coupled with articles that have little to no substance or, in many cases, completely refute the article’s headline.

It’s a “click-culture” designed to get clicks… not inform readers. And, it’s driven by the business model that’s used to monetize that content.

But again, who cares?

There’s a moral argument to be made here, but that’s not MY argument. Mine isn’t that you should care because it’s wrong and we need to do something about it (although, we DO)… my argument is that it’s NOT sustainable. It’s going to fall apart.

Why?

To use our analogy… if you feed an addict enough crack, they’ll eventually die or clean themselves up.

People will (and already have) figure out what’s going on and there will be backlash. Need proof?

Easy. Just ask the next 10 people you meet what their opinion of the news media in the U.S. is. Unless you’re at some sort of conference for journalists, you’re going to get negative reviews from the majority of those 10. In many cases, “passionately” negative.

As it stands now, most people don’t read the news from a particular news site (CNN, HuffPo, Washington Post, Wall Street Journal, FOX, etc) because they LOVE that news source and believe it’s honest, informative journalism… they do it because the headline is so enticing they can’t resist clicking through.

This is going to change.

We’ve already seen the rise of alternative media on the web… media that focuses more on real journalism and honest reporting.

This is part of the backlash that’s happening. And, it’s going to continue. And, it’s going to mean big trouble for the big media conglomerates that don’t adapt.

And, THAT is why NewsCorp spent so much time and money testing a new business model. Because, they see the writing on the wall.

Now, you might say… “But, The Daily failed. Doesn’t that give credence to the idea that the current model is the only workable one?”

In a word… NO!

Just because someone executes poorly on an idea doesn’t make the idea bad. It means the way it was implemented is bad.

While The Daily was losing millions of dollars/month… there were thousands (probably hundreds of thousands) of smaller publishers making tens of thousands (in some cases hundreds of thousands) of dollars per month… those same months.

And, for me, this is where things start to get more difficult.

Because, I see WishList Member and technology like it as a potential solution to a much broader problem.

The web, as a whole, is trying to figure out content monetization… meanwhile, we have tens of thousands of customers who already have it figured out and are making money hand over fist SERVING their members.

And, they’re doing it with more than just the traditional “membership site” model of content monetization.

Yet, I agree with people like Gary Vaynerchuk who believe content is more and more becoming a commodity… meaning the days of selling $2,000 online courses are coming to an end.

So, on one hand, we have big media corporations “selling” garbage content for pennies/click… and, on the other, we have smaller, well-known individuals and companies selling higher quality content for 1000s of dollars.

I think we end up somewhere in the middle.

And, it’s where I think software like WishList Member has a tremendous opportunity for growth. I think, right now, we see ourselves as “membership site” software and our feature-set reflects that. The way we make decisions reflects that.

We’re doing what we’ve been taught to do. Focusing on a specific niche and serving THAT niche. Not trying to be everything to everybody.

Yet, our customers tend to push us outside of that specific role (which is why we even have one-time fee and pay-per-post capabilities)… because our customers aren’t just building membership sites… they’re monetizing content… and they need the tools to do it.

So, what does a company like ours do?

There’s a Grand Canyon-size difference between seeing yourself as a “Membership Site Plugin” and a “Content Monetization” platform… a lot of which I talked about in an earlier post about platforms vs plugins.

And, the thing is… we’ve seen this before.

This is exactly the kind of disruption we saw in the music industry when Napster hit the scene.

And, it completely revolutionized how consumers saw themselves consuming music. Apple with iTunes was the first to really capitalize on this change and we saw how well that worked for them.

Who will be the first to really capitalize on the change happening with informational content? I don’t know, but I hope it’s us.

(photo by bookgrl)

March 27, 2013

How to Add a Login/Logout Link to WordPress Menus

In my last post, I talked about how to add a custom meta box with a custom link to WordPress navigation menus. Several times, I mentioned how I needed to add a specific class to that link for WishList Login 2.0, so that I could find that link later and do stuff with it.

This is the part where we “do stuff” with that link. Specifically, we’re going to hook into the navigation menu before it displays, find our link and change its display based on the current user’s login status. Here’s what it looks like:

Adding a Login/Logout Link

So, if they’re logged in, we’re going to change it to a logout link. If they’re not logged, then we’ll leave it alone. Here’s the code to do that:

if ( !class_exists( 'HijackMe' ) ) {
class HijackMe {
public function hijack_menu($objects) {
/**
* If user isn't logged in, we return the link as normal
*/
if ( !is_user_logged_in() ) {
return $objects;
}
/**
* If they are logged in, we search through the objects for items with the
* class wl-login-pop and we change the text and url into a logout link
*/
foreach ( $objects as $k=>$object ) {
if ( in_array( 'wl-login-pop', $object->classes ) ) {
$objects[$k]->title = 'Logout';
$objects[$k]->url = wp_logout_url();
$remove_key = array_search( 'wl-login-pop', $object->classes );
unset($objects[$k]->classes[$remove_key]);
}
}

return $objects;
}
}
}

$hijackme = new HijackMe;

add_filter('wp_nav_menu_objects', array($hijackme, 'hijack_menu'), 10, 2);

Here’s a run-down of what’s happening:

  1. We’re hooking in using the wp_nav_menu_objects filter.
  2. If the user is logged out, we just return the link as it is since by default it’s a login link.
  3. If the user is logged in, we then loop through the items and search the “classes” array element for our class.
  4. If the class exists in an item object, then we alter the “title” and “url” of that link and we unset our target class from the object.
  5. Then, we simply return the new objects array.

There’s definitely some customization and abstraction you could do with this:

1. Edit only the menu for a certain theme location. You’ll notice in the hook, I have 2 arguments being sent to the callback function, but I’m only actually using the first one. That’s to show you that there are actually 2 arguments available. The second one is the $args array which will contain information about that menu… including the theme location.

You would simply run a check on that array to see if the current theme location is the one you want to edit. This is especially important if you don’t want to touch widget menus at all… since, the Custom Menu widget uses the same back-end functionality as regular menus.

In our case, we wanted to hijack every instance of a link that contained our special class… even in a widget… so, we didn’t run any such check.

2. Abstract the target class. In our function, the target class we search for is hard-coded. In this instance, it’s fine because there’s no reason to have an option to change that class. You may have a scenario where it does make sense to allow users to change that class. In this case, you’d want to abstract that out by creating an admin option. You could then use get_option() to retrieve the target class and alter your menu accordingly.

So, that’s it. It’s a pretty straight-forward way to hook in and alter navigation menus how you’d like. And, IMHO, a hell of a lot easier than dealing with wp_nav_menu_items() and futzing with parsing HTML, and so on.

March 26, 2013

How to Add a Fully Functional Custom Meta Box to WordPress Navigation Menus

When I created WishList Login 2.0, I wanted to an easy way for users to add a dynamic login/logout link to their navigation menus. As simple as it sounds, it’s not something you can do natively in WordPress and we can requests for this kind of thing all the time.

In WishList Login 1.0, I had added an entire admin interface in the plugin settings that had all the necessary options for creating the link, editing its text, setting its position, and so on.

Of course, this was before WordPress added menus, so I didn’t have much choice… but, now WITH WordPress’ menus, it seemed silly to create a redundant interface… especially when the WordPress menus handled all the things need to added a menu link in a much clear way than my original interface did.

All that led me to figure out how to add my own meta box to the WordPress navigation menu interface with (important) the ability to add a custom link that contained certain parameters I needed in order to hijack the link’s display on the front-end.

Here’s what it looks like in the admin:

WordPress Custom Meta Box

Notice the CSS class. This was really the most important part because it’s what allows me to identify this link later and change it to a login link if the user is logged out and a logout link if the user is logged in.

Here’s a look at the code to make this happen:

if ( !class_exists('JMO_Custom_Nav')) {
class JMO_Custom_Nav {
public function add_nav_menu_meta_boxes() {
add_meta_box(
'wl_login_nav_link',
__('WishList Login'),
array( $this, 'nav_menu_link'),
'nav-menus',
'side',
'low'
);
}

public function nav_menu_link() {?>
<div id="posttype-wl-login" class="posttypediv">
<div id="tabs-panel-wishlist-login" class="tabs-panel tabs-panel-active">
<ul id ="wishlist-login-checklist" class="categorychecklist form-no-clear">
<li>
<label class="menu-item-title">
<input type="checkbox" class="menu-item-checkbox" name="menu-item[-1][menu-item-object-id]" value="-1"> Login/Logout Link
</label>
<input type="hidden" class="menu-item-type" name="menu-item[-1][menu-item-type]" value="custom">
<input type="hidden" class="menu-item-title" name="menu-item[-1][menu-item-title]" value="Login">
<input type="hidden" class="menu-item-url" name="menu-item[-1][menu-item-url]" value="<?php bloginfo('wpurl'); ?>/wp-login.php">
<input type="hidden" class="menu-item-classes" name="menu-item[-1][menu-item-classes]" value="wl-login-pop">
</li>
</ul>
</div>
<p class="button-controls">
<span class="list-controls">
<a href="/wordpress/wp-admin/nav-menus.php?page-tab=all&amp;selectall=1#posttype-page" class="select-all">Select All</a>
</span>
<span class="add-to-menu">
<input type="submit" class="button-secondary submit-add-to-menu right" value="Add to Menu" name="add-post-type-menu-item" id="submit-posttype-wl-login">
<span class="spinner"></span>
</span>
</p>
</div>
<?php }
}
}

$custom_nav = new JMO_Custom_Nav;

add_action('admin_init', array($custom_nav, 'add_nav_menu_meta_boxes'));

Most of this is pretty straight-forward.

  1. You hook into WordPress using the “add_nav_menu_meta_boxes” hook.
  2. You call add_meta_box() in your callback function setting “nav-menus” as the $post_type parameter.
  3. Finally, in your callback function for add_meta_box() you lay out your meta box HTML.

It’s that last part that can get tricky in order to make the adding of your custom link item to the nav menu… so, we’ll look at this more in-depth.

1. First, you need to make sure your HTML is set up correctly. The JavaScript that actually processes the adding of the link to the menu selects your link item in a specific way… so altering the HTML can break it. The above works. I’d recommend copying it and then just altering the small bits you need to.

Or, you can do what I did which is to copy the Category meta box native in WordPress and change what I needed.

2. Next, you need to adjust the main container div ID and the submit button ID so they match. This is part of how the jQuery works. You need to change these so they are unique and you need to make them match.

In the example code, you’ll notice the name of the container div ID is “posttype-wl-login” and the name of the submit button ID is “submit-posttype-wl-login”. This is the kind of relationship these two items need to have.

3. Finally, you’ll edit the inputs in the un-ordered list. These are the bare minimum I needed for everything to work. You can alter the values of these to what you’d like to display be default. You can also check other native meta boxes to see what inputs are available. The important one in our case was the “menu-item-classes”. This sets the CSS classes the link item will have by default and is what I used to hijack the menu later on.

And, that’s it. Once you have that all set up. Your users will be able to add your custom link item from your custom meta box to any of their menus and it’ll have the information pre-loaded in it that you may need later on when displaying menus.

Later, I’ll write up a tutorial on how to hijack menu items when you display the menus, so you can alter your custom link as you need.

March 22, 2013

Think Small

What if I could tell you the secret making a major breakthrough in your work… in 2 words? How to stop spinning your wheels 1,000 miles an hour but getting nowhere? How to stop being overwhelmed with “everything you’ve gotta do” and start working on only the things that matter?

(more…)

March 1, 2013

How to Create a Custom Loop in WordPress Using WP_Query

In this tutorial, I’ll show you how to create a custom loop in WordPress using WP_Query. Plus, I’ll explain why you want to use this instead of query_posts when creating custom loops like these.

<?php
/*** Custom Loop ***/
function demo_loop() {
$args = array(
'cat' => 3,
'posts_per_page' => 1
);

$demo_posts = new WP_Query($args);

if ( $demo_posts->have_posts() ) {
while( $demo_posts->have_posts() ) {
$demo_posts->the_post();

$output .= '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
}
}

return $output;
}

add_shortcode( 'demo_custom_loop', 'demo_loop' );

February 11, 2013

How to Create an ics Import File Using PHP

In this video, you’ll learn how to create an .ics import file using PHP. This allows you to dynamically generate the .ics file based on stored event data. Users can then download the file and import the event information in their calendar of choice… Outlook, Thunderbird(Lightning), Apple Calendar, etc.

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
/**
* Get the event ID
*/
$event_id = @$_GET['event_id'];
/**
* If no event ID or event_id is not an integer, do nothing
*/
if ( !$event_id || !is_numeric( $event_id ) ) {
die();
}
/**
* Event information
*/
//$event = get_event($event_id);
$event = array(
'event_name' => 'Test Event',
'event_description' => 'This is a test event. This is the description.',
'event_start' => time(),
'event_end' => time() + 60*60*2,
'event_venue' => array(
'venue_name' => 'Test Venue',
'venue_address' => '123 Test Drive',
'venue_address_two' => 'Suite 555',
'venue_city' => 'Some City',
'venue_state' => 'Iowa',
'venue_postal_code' => '12345'
)
);
$name = $event['event_name'];
$venue = $event['event_venue'];
$location = $venue['venue_name'] . ', ' . $venue['venue_address'] . ', ' . $venue['venue_address_two'] . ', ' . $venue['venue_city'] . ', ' . $venue['venue_state'] . ' ' . $venue['venue_postal_code'];
$start = date('Ymd', $event['event_start']+18000) . 'T' . date('His', $event['event_start']+18000) . 'Z';
$end = date('Ymd', $event['event_end']+18000) . 'T' . date('His', $event['event_end']+18000) . 'Z';
$description = $event['event_description'];
$slug = strtolower(str_replace(array(' ', "'", '.'), array('_', '', ''), $name));
header("Content-Type: text/Calendar; charset=utf-8");
header("Content-Disposition: inline; filename={$slug}.ics");
echo "BEGIN:VCALENDAR\n";
echo "VERSION:2.0\n";
echo "PRODID:-//LearnPHP.co//NONSGML {$name}//EN\n";
echo "METHOD:REQUEST\n"; // requied by Outlook
echo "BEGIN:VEVENT\n";
echo "UID:".date('Ymd').'T'.date('His')."-".rand()."-learnphp.co\n"; // required by Outlok
echo "DTSTAMP:".date('Ymd').'T'.date('His')."\n"; // required by Outlook
echo "DTSTART:{$start}\n";
echo "DTEND:{$end}\n";
echo "LOCATION:{$location}\n";
echo "SUMMARY:{$name}\n";
echo "DESCRIPTION: {$description}\n";
echo "END:VEVENT\n";
echo "END:VCALENDAR\n";

October 22, 2012

Plugins, Platforms, and My Plan for World Domination

I’ve been thinking a lot lately about WishList Member and its future. Specifically, how the web as a whole is evolving and what role WLM will play in that web. Looking into my magic “crystal ball”, I’m seeing some exciting things ahead if we take the right approach and develop the right mindset for the changes that are occurring with the greater internet.

Of course, none of this makes sense unless you know my Secret Plan for World Domination (add in ominous tone). I don’t mind sharing it, because while it’s simple to understand… it’s pretty damn difficult to implement. So, knowing it is like 1/100 of the battle.

However, I’ve personally never seen this put together in one grand strategy before… and, if you’ve never seen it, it can be quite enlightening (if I do say so myself). So, here it is…

(more…)

August 9, 2012

How to Destroy Your Business Legacy… And Why You Shouldn’t

Ethics in business today suck. Entrepreneurs are too focused on profit as the ultimate goal.

Profit is NOT the ultimate goal.

Business Is a Game

In baseball, a power hitter is often measured by how many homeruns he hits. As fans, we idolize and adore good hitters.

But, hitting homeruns isn’t his ultimate goal.

It’s a means to an end. The end is winning games… and winning enough games to be called a champion.

Often times, his legacy depends on whether or not he won a championship… regardless of how many homeruns he hits.

And, if he cheats to win, his legacy will be forever taintedregardless of how many homeruns he hits.

(more…)

June 28, 2012

7 Reasons Why You Should Start Using the Official Facebook for WordPress Plugin (and 3 Reasons Why You Shouldn’t)

Facebook just launched its official WordPress plugin which allows you to “easily” integrate Facebook features into your WordPress website.

I’ve spent the last day or so playing around with it and here’s my initial thoughts.

Why You Should Install Facebook for WordPress

1. Easy connection to your Facebook account. If you’ve ever setup one of the many Facebook plugins for WordPress, you’ll know that you typically have to create a new application in Facebook, grab the API Key and API Secret from your app, and paste them into your plugin.

This plugin is no different, except you only need to do it once and it gives you access to several of Facebook’s social plugins. Having an integrated Facebook plugin like this keeps you from having to create multiple Facebook applications for a bunch of different plugins or a bunch of PHP coding… which is very handy.

(more…)

June 13, 2012

This Is MY Blog!

If you’ve been following this site for a bit, you’ll know it’s been primarily about coding and contained all my various coding tutorials and such. Well, that’s changed.

I’ve officially moved all my coding tutorials over to http://www.learnphp.co and I’m taking this blog back as my personal blog. If you want the coding tutorials, head over there.

Here, I’ll be posting about pretty much whatever I want. You can follow me here if you’d like to keep in touch with me personally.

(photo by a2gemma)

June 13, 2012

How to Sort Multidimensional Arrays Using PHP

In this video, you’ll learn how to sort multidimensional arrays in PHP. You’ll not only learn basic sorting using array_multisort(), but you’ll also see a more advanced custom function for sorting multidimensional arrays by a specific key.

Multidimensional arrays can be one of the more confusing parts about learning PHP, but this video will help you get your head around it and give you some tools for sorting your multidimensional arrays that are simple and straight-forward.

<?php
$arr = array(
array('name' => 'John', 'age' => 30, 'website' => 'http://learnphp.co'),
array('name' => 'Joe', 'age' => 28, 'website' => 'https://johnmorrisonline.com'),
array('name' => 'Amy', 'age' => 32, 'website' => 'http://amy.com'),
array('name' => 'Alex', 'age' => 22, 'website' => 'http://thealex.com'),
array('name' => 'Pat', 'age' => 40, 'website' => 'http://patsjourney.com'),
);

?>

<pre><?php print_r($arr); ?></pre>

<?php
array_multisort($arr);
?>

<pre><?php print_r($arr); ?></pre>

<?php
function val_sort($array,$key) {

//Loop through and get the values of our specified key
foreach($array as $k=>$v) {
$b[] = strtolower($v[$key]);
}

print_r($b);

asort($b);

echo '<br />';
print_r($b);

foreach($b as $k=>$v) {
$c[] = $array[$k];
}

return $c;
}

$sorted = val_sort($arr, 'website');
?>

<pre><?php print_r($sorted); ?></pre>

December 29, 2011

How to Create an HTML Select Box From a MySQL Results Array Using PHP

This is a question I get quite a bit, so I figured I’d write a post on it:

How do I create an HTML select box with options from data in my database?

Here’s how:

The Query

First, let’s look at our query. Yours might look something like this:

<?php
$sql = "SELECT * FROM queried_table";
$query = mysql_query($sql);
while ( $results[] = mysql_fetch_object ( $query ) );
array_pop ( $results );
?>

That will select everything in our table and loop it into an array of objects containing the results. Now, we can take that array and create a HTML select box with it.

The HTML Select Box

Now, that we have our array of objects from our database we can use it to populate an HTML select box dynamically with PHP. Here’s how that might look:

<select name="the_name">
<?php foreach ( $results as $option ) : ?>
<option value="<?php echo $option->desired_value; ?>"><?php echo $option->desired_label; ?></option>
<?php endforeach; ?>
</select>

That’s it. The code above will loop through the array creating a new option for each element in the array… and populating each option with the desired values from your database. Of course, this is just sample code, you’ll need to work with your database structure and code to make it work for you… but, that should give you the framework for getting this kind of thing done.

Here’s a video walk-through of this, as well:

If you enjoyed this tutorial and want to keep learning, check out my free tutorial site here: https://johnsfreetuts.com

August 10, 2011