Skip to content

Removing “Author” from RSS WordPress Feed

I wanted to remove the “author” tag from my RSS feed from WordPress lately and couldn’t find an appropriate plugin. The reason for this was that I am co-writing for a blog but we don’t want to show individual authors.

When reading a feed in e.g. Google Reader, you either get to see the title, the blog name and the other when in “all items” view or just the title and the author:

All Items View: Blog with Author

All Items View: Blog and Author

Single Blog View: Only Author

Single Blog View: Only Author

The end result I was looking for should only always contain the name of the blog and never of the author:

Any View without an Author

Any View without an Author

As I said, there may be a plugin that does the job but I haven’t found it (let me know if you did). That said, there is an easy manual way to get rid of the author:

1) Connect to your blog via FTP – You will need to edit a couple of files that are WordPress specific and are unrelated to the theme you are using. So there is no direct way to do this (Again, there might be a plugin that let’s you do exactly this).

2) Download (or edit remotely): feed-atom.php, feed-rdf.php and feed-rss2.php – These three files contain all a call to the PHP function: php_the_author(). They are located in the folder wp-include (WordPress 3.2.1). Remove the bit: < ?php the_author()?> between the “name” tag in feed-atom.php and the “dc:creator” tag in feed-rdf.php and feed-rss2.php respectively.
As an example, the feed-rss2.php file should be changed from:

< ?php the_author() ?>

to:


3) Upload – If you did the change remotely, forget this step. Otherwise, upload the three files again.

Alternatively, you can download these files here and upload them to your server:

rss-feed-without-author

However, remember that the zipped files are WordPress 3.2.1 compatible and might not work with other versions.

UPDATE: The same works with the latest WordPress 3.3 Release. Simply copy paste the three files

Un-Shuffling – the missing feature!

Today I was driving home from the Alps. My iPod was playing random songs from its 60 GigaByte repertoire. Shuffling is a great feature when you are not really sure what you want to listen to… Of course I had to skip quite a few songs. When you carry 60 GigaBytes of mp3s around, obviously not every song is great.

But then it happened: My iPod played a song from a Pink Floyd album. One from an album like “The Wall” where the songs are all somehow connected to each other. I wish I had been able to easily leave the “shuffle mode”, to unshuffle so to speak, so that I can continue listening to the rest of the album…

So you guys who build the iPod and similar devices: Think about it! Shuffling did the job of finding me some great music I had previously forgotten about. But once I find something I like, let me stick to it with one click…

Please add the “Unshuffle Button”! I think it could be useful…

Tip of the Iceberg Problem: Throw code at your users!

Users tell you “this should be easy”, “you only have to do x”, “just another button here”? Give them the direct experience of their fallacy: **Throw the source code at them!**

Today, a colleague from the sales department, an internal user of one of our IT products, said he could not imagine that the app in question was *that* complex…

Users always only see the top of the software iceberg.

If you are an IT expert, you can plot a realistic picture of the size and complexity of an application once you know the dependencies to input data, other systems and workflows. For example, if an application needs to be kept in sync with another system or if even company boundaries are crossed, you quickly get an idea of the complexity these scenarios put on your code.

To the half knowledgeable user (the smart boys and girls), it often *just* looks like a case of “but you only have to send this XML file to them” or “call this webservice”.

I wanted to give this colleague a better understanding by making the facts more accessible in a direct, physical way. Turn the abstract concept into something real that you can experience directly. To give him an idea of “how deep the iceberg really is”…

I decided to print out the whole source code of the project, put it into a folder and throw it on his lap.

He would feel the weight of all that code we wrote during the last three years! He would look at a few of the pages and would not understand a word of what he reads, except some business realted words that he would recognize and therefore would conclude the whole thing was not a hoax.

He would understand why we, in the IT division, cannot always deliver his latest (by the way, *very good*) ideas within a day or two…

I did a quick search on Google if there was an app to turn our sourcecode into one single file for print but didn’t get lucky quickly.

I decided to spend half an hour and wrote this trivial piece of code:

public class Code2Book {

       private List<string> fileTypesToPrint;
       private int fileCount = 0;
       private BufferedWriter writer;

       public static void main(String[] args) throws IOException {
           Code2Book m = new Code2Book();
           File[] files = new File(args[0]).listFiles(); 
           m.createBook(files);
       }

       private void createBook(File[] files) throws IOException {
           fileTypesToPrint = new ArrayList<String>();
           fileTypesToPrint.add("java");
           fileTypesToPrint.add("groovy");
           fileTypesToPrint.add("scala");
           fileTypesToPrint.add("xhtml");
           fileTypesToPrint.add("css");
           fileTypesToPrint.add("js");
           fileTypesToPrint.add("xml");
           fileTypesToPrint.add("html");

           if (new File("outfile.txt").exists()) {
               new File("outfile.txt").delete();
           }
           writer = new BufferedWriter(new FileWriter("outfile.txt"));

           handleLevel(files);

           writer.close();

           System.out.println();
           System.out.println("Concatenated " + fileCount + " files.");
       }

       private void handleLevel(File[] files) throws IOException {
           for (File file : files) {
               if (file.isFile()) {
                   if (isFileToPrint(file.getName())) {
                       fileCount++;
                       System.out.println("file = " + file);
                       appendToFile(file);
                   }
               } else if (file.isDirectory() && !file.getName().startsWith(".") && !file.getName().equals("target")) {
                   handleLevel(file.listFiles());
               }
           }
       }

       private void appendToFile(File file) throws IOException {
           FileInputStream fis = new FileInputStream(file);
           DataInputStream dis = new DataInputStream(fis);
           BufferedReader br = new BufferedReader(new
           InputStreamReader(dis));
           String line;
           writer.write(file.getName() + " - " + file.getAbsolutePath());
           writer.newLine();
           writer.newLine();
           while ((line = br.readLine()) != null) {
               if (!line.trim().equals("")) {
                   System.out.println(line);
                   writer.write(line);
                   writer.newLine();
               }
           }
           writer.newLine();
           dis.close();
       }

       private boolean isFileToPrint(String name) {
           for (String s : fileTypesToPrint) {
               if (name.endsWith("." + s)) {
                   return true;
               }
           }
           return false;
       }
}

The code snippet above simply takes the root folder of a “JDK” project, recurses through all subdirectories and concatenates all source code it finds, into one single file. Blank lines are skipped while comments aren’t.

I run it on the project the sales colleague put into question and was surprised with the result:

– 2100+ files
– 170’000+ lines of code (including comments, which we don’t do a lot :-/)

Next I was going to print it… Turned out I would have had to print out 2600+ DIN A4 pages. Given I print them double sided, this is still 1300+ physical sheets. I checked how many pages there are in a standard printing paper packet, five hundred. The “book” would be aroud 20 centimeters or about 8 inches think! You can kill a person with this kind of brick!

However, I was gonna do it and print it, no matter what, I just wanted to throw it at him… The effect would have been massive!

Then my colleagues in the IT department talked me out of it, saying boring things like “think about the environment” and so on… One guy ([Jason](http://twitter.com/retronym)) recommended to produce a [Gource](http://code.google.com/p/gource/) source code evolution movie from the GIT commits. Great idea and environmentally friendly. Everybody happy!

It does’t give you a direct idea about the **physical weight of the project, when *someone actually throws it at you***…

…but it is a joy to watch the little code jedis lasering at the file tree…

Lets see if I it works out. I will let you know…

UPDATE:

I decided not to print it but instead take a pile of around 1300 pages of plain printer paper and hand it to him. He first didn’t know what I was about. When I told him he currently held the equivalent of the projects source code, he was quite impressed, to say the least :-)

A simple idea but it totally got the point across. It made an abstract concept accessible through physical experience.

I recommend it.

Maven Archtype Plugin

Sometimes it is the little things that make the biggest impact. So here is a quick solution to a common problem when using the maven archtype plugin.

If you want to run the plugin with

x:>mvn archtype:generate

and get the error that the plugin could not be found

The plugin ‘org.apache.maven.plugins:maven-archtype-plugin’ does not exist or no valid version could be found

try to force maven to recheck the remote repositories by deleting the org/apache/maven file tree in your local repository

/org/apache/maven

If this does not help, make sure you have the right mirrors in your maven settings (conf/settings.conf). This one worked for me:


ibiblio.net
http://www.ibiblio.net/pub/packages/maven2
central

Hope this helped.

Avoiding team erosion: why codebase growth and teamsize have to be aligned overtime

In this short post, I’m going to share my thoughts on why I think it is neccessary to align your software project portfolios growth with that of the development department headcount. This sounds logical enough but not actively managing this can lead to an unwanted team erosion that you will only discover when it is too late… This post will give you the arguments to defend it in front of managment.

Introduction

In any IT departement of any company there are different kind of tasks to do. A company inĀ  a more traditional sector, like mechanical eningeering needs an IT help desk to support the staff with daily problems like installing new software, setting up new user accounts and so on. Possibly there will also be a team that takes care of running the IT infrastructure, making sure that the network is up and running and secured from the outside, that email and ftp servers are up and healthy.

As soon as a company has the need for very specific IT systems that are tailored to its own needs, a development departement will be needed as well. If the company is producing software as a product for their clients, the development department moves out of the support line, into the production line of the business.

The development team will be responsible for creating new software systems, applications and websites that are used within the organisation or by the organisation’s clients. Within the lifecycle of these products, the initial creation of the first one or two versions is only a tiny step. When they get into production the realworld test starts. Is the program really doing what it is supposed to do? Does it help to reduce costs? Does it meet the expectations, the initial ideas set out?

If the software product is of any use, it will enter a phase where users will request new features. For the initial developers, this phase can be frustrating. An initial design might needs to be refactored to meet the new requirements. There may not be enough funding from the business to do the refactoring properly and soon little hacks have to be introduced to meet cost requirements.

Maintenance Lifecycle

Developers usually take pride in their work but when time and cost constraints force them to drop their quality standards, they easily get upset and soon look for other interesting projects that are at an earlier state of the product lifecycle.

Nevertheless the project has to be maintained by someone. This is usually where the manager will look for less experienced newbie developers to join the project. While the newbies get a chance to learn from what the initial project developers did, they also get a good feeling for “how it works in the real world”.

They are forced to make compromises between “technically outstanding code” and “getting things done”. If you staff right, these are the people who will keep your development department running in the long run. They will appreciate the learning they get from the more senior staff while also understanding the need to maintain code over time.

The rockstar developers, the divas who do not want to spend their time with maintenance, those whom you employed as a startup, to get things flying, will by now look for new challenges. For the manger, it is too late in their careers to teach them modesty. They can leave the company and find a job out there with ease and within minutes.

What are the options?

The managers only option is to give them more work that they find interesting enough to stay. For the top developers, it is a very simple cost/benefit analysis: “Given all other incentives, like compensation and so on are equal at any other company, is the benefit of doing project X bigger than the costs of a job transition, if yes, stay”. If the company doesn’t manage this phase right, their development department will get into crisis.

This crisis can be triggered from two sides: If the company fails to come up with interesting new projects. This is the obvious one and is not necessarily a problem when there are in fact no new development needs and the only job left is to maintain the current software project portfolio.

The other cause however is when there are in fact new projects in the pipeline but due to either an understaffing or resignations from “maintenance staff” happens. In either case the top developers will be forced to do more of the maintenance than they are willing to as they are the only ones left fit for the job. As it leaves them less time to work on challenging projects, their benefits in the equation above will diminish and they will eventually leave.

Conclusion

So sum it up, overtime more projects are added, the codebase naturally grows and so does the mainenance effort. If the headcount of the development team is not increased over time to match the project growth, new projects cannot be done anymore as maintenance of a live system is always more important than working on new ones that don’t yet payoff.

As a consequence the top shots will resign and you end up with a handful of maintenance coders who will now also not be happy anymore. All their colleagues who they could learn from are gone and no one is left to show them new tricks. As soon as they find a better offer, they too will leave.

So, it boils down to a very simple equation:

Codebase growth and teamsize have to be aligned overtime.

Sounds like a no-brainer but you now have the arguments to defend it in front of managment. And if you stick to this rule, you will not run into these kinds of problems.

If a company fails to consider this, reality will kick it in the… knee.

My Blog is finally back up again!

Hi All,

To those of you who are still here: A big welcome back! After 2.5 years, I finally got my blog back!

A WordPress security hole seemed to have deleted all my posts and I was just too depressed about that to even bother and decided to do nothing about it.

The other day I played around with the WayBackMachine and surprisingly found everything that I had thought had been gone to data Nirvana! I then added a subscription to this blog on Google Reader and it could even load the whole feed! Magic! I just checked in here ten minutes ago and after a database update, all my data was back!

I will write now more often. However, the posts will be a bit less crafted (takes ages) and much less politically correct and thus hopefully more fun!

Thanks!

Java Web Start’s silly Self Reference

Just coming from having to push a Java Application out to the clients machine via Java Web Start. Everything went pretty well, after signing all the Jar’s. This, so they could sneak outside the “security sandbox” that Java Web Start plugs around downloaded applications.

The (maybe) unusual thing in our setup was, that the jnlp file had to be rendered on the fly. So there was never going to be a “on-disk” version of the file during the whole request, response cycle.

So, following the old “monkey see/monkey do” rule, my generated file looked a bit like this one:

[...]
jnlp spec="1.0+"
codebase="http://192.168.0.1/"
xhref="myapp.jnlp" mce_href="myapp.jnlp" // ignore the mce...
[...]

When trying to run this generated “file” through a link in the browser, silly web start tried to locate the file “http://192.168.0.1/myapp.jnlp”… HELLO? YOU ARE THIS FILE! STOP COMPLAINING YOU CANNOT FIND YOURSELF!

A quick look in the Java Web Start Tutorial hinted me to try to omit the href argument in the jnlp tag. Apparently, it is not needed. It then worked the way as I expected it to. But really, what is it good for anyway?

In the “spec” mentioned above, it says about the href attribute:

“The href specifies the URL of the JNLP file itself.”

Oh, that’s cute :-)

Skype sitting on Port 80

Once again I went into the Skype Trap. Today, I decided to try out Elgg. Elgg is an open source version of a social network platform. The nice thing is, you can download it and host it on your own servers. This is particularly useful if you don’t want anybody else to mess with your network data. Some of my friends live in Russia and they told me, the KGB surveillance mentality of the state was still ongoing. Talking freely in a social network is crucial. However, in some countries, this would already mean committing a crime. And by all means, I just like open source software better.

But back to what I was saying about Skype. I downloaded the latest Apache Webserver and installed it on my machine. At the end of the installation process, it told me it could not bind to port 80. Have seen this before, I thought. Yeah, right, last time it took me hours to finally accept, that the Apache installation was probably intact and that there would have to be some other problem. I then did a portscan and what did I find sitting on my port 80? – Skype! That cheeky little bastard !

skype2.gif skype1.gif skype2.gif

I had to uncheck the setting “Use port 80 and 443 as alternatives for incoming connections” in the Connection Tab. Great Philosophy: “Let’s just hijack the http and the https port, then in most of the cases, our software should work”.

Anyway, now I can go back to Elgg and try to make PHP and Apache talk together. This used to be a problem a few years ago. I think this was the reason for the XAMPP Project.

Let me quote them: “Many people know from their own experience that it’s not easy to install an Apache web server and it gets harder if you want to add MySQL, PHP and Perl. XAMPP is an easy to install Apache distribution containing MySQL, PHP and Perl. XAMPP is really very easy to install and to use – just download, extract and start.”

Anyway, I will give it a go “by hand” now. Wish me luck :-)

Fixed intransparent Picture for the Diva: Microsoft Internet Explorer

I finally fixed the intransparent picture in the header of this blog. The picture of the “yellow marker”:

marker.jpg

This is a PNG. Only in Internet Explorer it looked like this. I changed it with Photoshop to a GIF:

marker.gif

Now the header looks the same, and good, everywhere.

I did not notice earlier, because I NEVER use IE, unless Microsoft forces me to, through some windows update process, that only IE can handle.

I suggest everybody to add JavaScript to all their pages with this functionality:

If IE is detected, the user is forwarded to some other page, telling it to download Opera, Firefox, Safari or whatever other Browser that conforms with the standards. Thus not allowing any browsing with Internet Explorer at all.

The next step is to add this functionality a step further up, into the webserver software. Then into the routers.

Think about it, otherwise we never get out of the browser hell :-)

Bug Fix for “Contributing to Eclipse”

It has been a long time since my last post. I was very busy. Sorry for that.

Here comes another technical article on a book: “Contributing to Eclipse: Principles, Patterns, and Plug-Ins”, published by Addison-Wesley. It is written by Erich Gamma (co-author of the “OO-Bible” Design Patterns, technical director of the IBM Research lab Zurich and developer of the Eclipse Platform) and Kent Beck (creator of Extreme Programming).

contributing_eclipse_2.jpg contributing_eclipse_3.gif contributing_eclipse_1.jpg

The book is obviously on how to extend the Eclipse platform with your own “contributions”, aka Plug-Ins. The book is very interesting as it comes from two authors who “come from the inside” of Eclipse. Thus they reveal all kinds of background information that a normal author could easily have missed.

However the book was written in 2003 and builds on a previous Eclipse release, prior version 3.0. When reading through the examples in the book, I eventually got to chapter 7, where Erich and Kent are developing the JUnit Plug-In. I think the one nowadays shipped with the standard Eclipse distribution.

There, page 62, they say: “For now, we can’t imagine how your understanding of Eclipse would be helped by seeing the details of starting a new virtual machine and communicating with it via sockets. See Appendix A for the details.”

Here they talk about how to properly run your test cases. That is “outside” the Eclipse JVM instance. To easily get above that bump, I downloaded their source code from here. In this archive, there are two classes that are senseless for the reader to implement himself, that is TestRunner and SocketTestRunner. So I imported them into my own Eclipse Project (Note: Circle_1!).

First I changed the obvious stuff, like in TestRunner.java, line 77 and 130:

JUnitPlugin plugin = JUnitPlugin.getPlugin();

to match my slightly different class names:

MyJUnitPlugin plugin = MyJUnitPlugin.getPlugin();

However, when I started my Plug-In Project (“run as Eclipse Application”) and selected an object type in a dummy project (“ADemoProject”) and then tried to start my own JUnit implementation (“Run MyTest”), nothing happened.

The Eclipse View “Error Log” gave the hint that there was a NullPointerException in TestRunner, line 78:

java.lang.NullPointerException
at org.eclipse.core.runtime.Plugin.getDescriptor(Plugin.java:268)
at org.theyellowmarker.gamma.TestRunner.computeClasspath(TestRunner.java:78)

But then looking at my Eclipse source of TestRunner, the deprecation warnings gave me the hint to do a bit of research, have a look at the screenshot below:

contributing_eclipse_4.jpg

Obviously, plugin.getDescriptor() was the reason for the NullPointerException. Used to the standard Java JDK philosophy, where deprecated methods usually still do their job somehow, it took my a bit of Eclipse API reading to figure out how to recode the whole section. Again, see the screenshot below:

contributing_eclipse_5.jpg

To get the plug-in path for our plug-in, we have to get “the Bundle” from the static method of

org.eclipse.core.runtime.Platform:

// has to be unique id of activation plugin.
Bundle bundle = Platform.getBundle("org.theyellowmarker.MyJUnit");

Note that the string “org.theyellowmarker.MyJUnit” is the unique id of my plug-in in the MANIFEST.MF file. You have to change it according to your setup. The url of the project is then found by the subsequent lines:

URL url = FileLocator.find(bundle, new Path("/"), null);
classPath[0] = FileLocator.toFileURL(new URL(url, "bin")).getFile();
classPath[1] = FileLocator.toFileURL(new URL(url, "junit.jar")).getFile();

Note: I am not sure about the last line here. Could be useless.

Next, also replace the deprecated SocketUtil.findUnusedLocalPort on line 61 with:

port = SocketUtil.findFreePort();

Last, the SocketTestRunner class is given to the external JVM by name, so you have to change the first line of the class, where MAIN_CLASS is defined, to match your own package structure:

static final String MAIN_CLASS = "org.eclipse.contribution.junit.SocketTestRunner";

to:

static final String MAIN_CLASS = "org.theyellowmarker.gamma.SocketTestRunner";

Now everything works again, as expected. You can download my plug-project here: myjunit.zip

and the dummy project containing the test cases here: ademoproject.zip

Make sure, when running the plug-in “in action” (that is in the second Eclipse workbench) to right click on the ASillyClassTest symbol with the green class dot on its left, otherwise, you don’t get the “Run My Test” menu entry in the context menu:

contributing_eclipse_6.jpg

On test will fail, one will succeed. The console output on the first Eclipse workbench should be something like this:

2 test[s] started...
Test org.theyellowmarker.test.ASillyClassTest-&gt;testDemoTrue() started.
Test org.theyellowmarker.test.ASillyClassTest-&gt;testDemoFalse() started.
Test org.theyellowmarker.test.ASillyClassTest-&gt;testDemoFalse() failed.
junit.framework.AssertionFailedError: null
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertFalse(Assert.java:34)
at junit.framework.Assert.assertFalse(Assert.java:41)
at org.theyellowmarker.test.ASillyClassTest.testDemoFalse(ASillyClassTest.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.theyellowmarker.gamma.SocketTestRunner.runTests(SocketTestRunner.java:39)
at org.theyellowmarker.gamma.SocketTestRunner.main(SocketTestRunner.java:26)

All tests finished

As I move forward in the Book, I will publish eventual updates on this topic.

P.S: Here is the full set of files after “Circle 1″: first-circle.zip