You've opened a new tab!

Sound familiar? You know IE holds back the Internet right?

Here you'll be able to find my brief notes on computer/linux things I'm currently doing, and if I had any troubles, details about how they were overcome.

My public GPG key
My public SSH key

My github

My nicknames:

  • cgerpheide (official)
  • phoxicle (IRC, forums, twitter)
  • HorseRayX (AOL -- haven't used this one since I was 11)

A list of my favorite XKCDs:

C0mput3rz & T3chno1ogy

MacPorts MySQL Installation of system tables failed!

Some problems installing MySQL using macports on Mac OS X: After macports install, trying to run mysql_install_db results in error:

$ sudo /opt/local/lib/mysql5/bin/mysql_install_db --user=mysql
Installing MySQL system tables...
ERROR: 1004  Can't create file '/var/tmp/#sql10274_1_0.frm' (errno: 9)
120609 22:53:01 [ERROR] Aborting
120609 22:53:01 [Note] /opt/local/libexec/mysqld: Shutdown complete
Installation of system tables failed!

To solve that, we need to change some permissions:

$ sudo chown -R mysql:mysql /opt/local/var/db/mysql5
$ sudo chmod u+rwx,go= /opt/local/var/db/mysql5

Then try again:

$ sudo /opt/local/lib/mysql5/bin/mysql_install_db --user=mysql
Installing MySQL system tables...
OK
Filling help tables...
OK

The default tables should now be properly filled. Then you should be able to execute the mysqladmin command to set the new root password as described in the output from mysql_install_db:

$ /opt/local/lib/mysql5/bin/mysqladmin -u root password newpassword

If you get the Access denied for user 'root'@'localhost' error, make sure you have restarted mysql after successfully executing the mysql_install_db script.

Smooth animations in jQuery UI Accordion

I was having trouble making my accordion slide (the default) animations smooth using the jQuery UI. The accordion would slide, but then sort of "jump" about 10 pixels up just after the slide effect.

If you are having the same problem, the fix was simple: I had a margin set on the accordion header, and I changed it to padding.

a.accordion_header {
  display:block;
  padding: 10px 0; /* Margin makes animation not smooth! */
}

Apparently the accordion plugin calculates the target height without the header margins included, so the animation ends up jumping a bit to make up for it.

Resources:

Facebook LIKE woes: button reverts back after click

More and more I feel like my posts are just giving simple but nonobvious workarounds to silly problems.

Today's topic is facebook LIKE. I encountered a problem recently where I was trying to provide a URL for a like button, but when I clicked on the button, it would show the little count bubble for a second and then revert back to the un-liked state. In my case I was using the FBXML version of the like button.

So it turns out that (<- I swear every one of my posts now has that line) this happens when you provide an invalid URL. I had tried urlencoding the URL, but apparently that doesn't help. So far I've found that the following characters do not work:

Do not work:

  • URLs with GET parameters (ex: http://yoursite.com/?foo=bar)
  • URLs with underscores (ex: http://yoursite.com/foo_bar)
    • Fix: Use hyphens instead (ex: http://yoursite.com/foo-bar)

FIXED: TYPO3 Shortcut page not showing up in menu

Recently encountered a strange behavior in TYPO3. I was having trouble with a page not showing up in a menu, when I changed the page type to Shortcut.

It turns out that I had set both the Shortcut mode to "First subpage of current page", as well as setting a page for the Target page. Altough either setting works by itself, when you have set BOTH, it seems to break the menu rendering, and the page no longer shows up.

To fix: Either change the Shortcut mode to "Selected page" or remove the page set as the Target page.

Changing doctype when using TYPO3 TemplaVoila Framework

According to the TS Setup documentation, you can change your TYPO3 site's doctype by adding the following to your TS Setup:

# Change TYPO3 doctype on normal installation
config.doctype = xhtml_strict

However, if you are using the new Templavoila Framework, this value is overriden by a page-specific setting. So, if you want to change the doctype and you are using the Framework, you must instead use the following lines:

# Change doctype when using TV Framework
page.config.doctype = xhml_strict

where xhtml_strict can again be interchanged with any of the valid values listed in the config documentation above.

References:

Adding flexforms to plugins in newer versions of TYPO3

To add a flexform to your plugin, in addition to creating the flexform, you also need to add a couple lines to ext_tables.php to make TYPO3 aware of your plugin. If you used the extbase_kickstarter to kickstart your extension, some boiler plate code has already been added to ext_localconf.php and all you have to do is uncomment them, clear cache and reload:


$TCA['tt_content']['types']['list']['subtypes_addlist'][$_EXTKEY . '_pi1'] = 'pi_flexform';
t3lib_extMgm::addPiFlexFormValue($_EXTKEY . '_pi1', 'FILE:EXT:' . $_EXTKEY . '/Configuration/FlexForms/flexform_pi1.xml');

If your extension key has an underscore in the name, however, you will find that you still see no flexform. This is because in some places in these lines the plugin signature (ex: cmgnews_pi1) is needed, instead of the extension key (ex: cmg_news). Conveniently, the blog_example provides an example of how to do this:


$extensionName = t3lib_div::underscoredToUpperCamelCase($_EXTKEY);
$pluginSignature = strtolower($extensionName) . '_pi1';
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
t3lib_extMgm::addPiFlexFormValue($pluginSignature, 'FILE:EXT:' . $_EXTKEY . '/Configuration/FlexForms/flexform_pi1.xml');

So that's it. Clear cache, reload the plugin, and you should now have a flexform :)

References:

PHP Magic methods and static keywords

It turns out that calling magic methods with static keywords (like parent::) do not always work:

// Doesn't work in some PHP versions
parent::findByType($type); // findByType() is magic

A quick fix is to call the method directly using __call:

parent::__call('findByType',array($type));

Just a heads up...

Android emulator window too large to resize in Mac OS X

Speaking of silly problems, have you ever found that in Mac OS X you have a window that's too large to get to the bottom right corner in order to resize it? This is the case with the android emulator on a 13" Macbook Pro, with 1280x800 resolution, which makes it so some parts of the emulator screen actually extend below the display. Usually this is fixable by clicking the green "maximize" button, but in the case of the android emulator (and probably some other programs), this is disabled.

The solution (thanks to Jeff Shaw for making me aware of this), is to set special command line options to the emulator to set the emulator window to 60% size.

  1. Open your Run/Debug Configurations, and go to the Target tab.
  2. Scroll down to the field Additional emulator Command Line Options and add -scale 0.6 as the value
  3. That's it! Save your options and when you restart the emulator it should now be reasonably sized :)

Old method (before Jeff's excellent advice): Open up a terminal and type:

telnet localhost 5554
window scale 0.8
quit

Did you know that in most linux window managers, you can resize a window by holding alt and clicking and dragging the middle mouse button from anywhere on the window itself? Come on Apple, gotta keep up.

References:

John "maddog" Hall at ADW2010

This is actually old news that I never got around to blogging about, and every day I regret it. So here it goes:

Athens Digital Week 2010 took place in, well, Athens from October 7-10 earlier this year. This is a yearly event which offers presentations and booths for many digital arenas, including robotics, open source, gaming, and more (find more info on their website).

As a volunteer for the Hellenic Linux User Group (HEL.L.U.G.), I attended one day manning the booth and attending talks. Most notably, I got to meet John "maddog" Hall from Linux International! maddog was invited by HELLUG and gave a presentation on his Cacua project -- see my notes on the presentation here.

When I walked in I went up to the HELLUG booth, setting my things down to join my friends there. maddog was sitting besides the table. After about five minutes where it was obvious I was a linux-interested female, maddog stood up and offered me a pair of penguin earrings without saying anything. And of course I, not recognizing him at first, responded in greek:

Me: "Τι είναι αυτά;"
maddog: [points to his ear]
Me: "Ναι οκ ξέρω τι είναι, αλλά γιατί μου τα δώσατε;"
maddog: "Earrings"
Me: " ... OHH.. Yes, thank you very much!"

Immediately after I turned around I realized who he was. It's the first time I've accidentally spoken to a fellow American in Greek accidentally too. As the event proceeded I got a lot of time to sit down and talk with maddog, discussing the dissemination of linux, American imperialist politics, his Cacau project, as well as my little life story about ending up in Greece. Overall it was a very satisfying experience, and now I can also boast that John "maddog" Hall gave me earrings. Also joining our conversations was the current HELLUG president, Richard Kweskin, another American. Together we comprised our own American corner at the conference's open source room.

Here are some pics. The first is me and maddog; the second is Richard and maddog. We also all have the same shoes :) You can find more pics from the event in HELLUG's album.

G2 Time :)

This summer, my T-Mobile G1 was stolen by a trio of five-year-old gypsies in Athens. So naturally, when the G2 came out this fall, I picked one up (or rather had Ian mail it to me from the US).

First, here are some pics! Because I'm a fanboi:

In addition to just being grateful to finally have a smartphone again, I am most stunned by the speed, voice actions and swype. Really, the voice transcription had me thinking for a second that it might even be faster than me typing on a full size keyboard (!) Since then I've decided that's not true, but really, it's very impressive, and undoubtedly much faster than typing on the phone keyboard when you are typing simple speech (not strange words or abbreviations).

That said, so far I've seen two glaring defects. As the fanboi I am, I forgive them despite the first one being so severe, but I will list them here:

  • Valid unlock code from T-Mobile breaks all network connectivity. Yes, even with a perfectly legitimate unlock code from T-Mobile, I could not connect to networks. It turned out to be a bug in a "security feature" meant to keep you from rooting the phone which came along with a horrible glitch. T-Mobile Android support told me I'd have to exchange the phone the next time I came to the US. Instead, ironically I ended up rooting the phone according to some fix my friend found on the internet. See my previous post on that for details. Seriously, I just got the phone mailed to Greece, and it can't connect to networks and so I have to get it exchanged? #FAIL.
  • It charges via a micro-USB port, not mini-USB. This annoys me, obviously, because I don't tend to own or carry around micro-USB cables (the G1 was mini-USB). However, under the naive assumption that Google is promoting micro-USB as the new standard, I will respect that and try to keep micro-USB cables with me as well.

Besides those issues, I am so far extremely happy with the phone, and so I am overlooking the two issues I have had so far and my future expectations are high.

FIXED: "Error while searching for networks" on unlocked T-Mobile G2

After a week of failed attempts, I finally got rid of the "error while searching for networks" message on my G2! I had brought a T-Mobile G2 from the US and wanted to use it with my Vodaphone SIM card here in Greece. I had already had it unlocked by T-Mobile, but after that whenever I would try to scan for networks it would just say "Error while searching for networks" and never see nor connect to any phone networks. After talking for a while with T-Mobile "android specialists", they determined it's a problem with the firmware, and I'll have to get the device exchanged next time I come to the US, hoping that it would be fixed by then.

But today, my friend kargig found a wiki with a solution:

This page describes how an added "security" feature is actually preventing your phone from connecting to networks, despite being "unlocked." The fix, as described in detail at that link, involves rooting your phone and then running a program called "gfree."

Of course, as this is altering your phone's firmware, it probably voids any warranty you have and involves a certain level of risk. For me though, the process was very smooth (and easy!) and worked perfectly: I can now connect to my vodaphone network on my T-Mobile G2, as well as see the other networks available!

Hope this can direct other distressed users with the same issue, so they can have as happy a day as I am :)

"Unknown format in import" with .p12 file in Mac OS X

Today I encountered the error "Unkown format in import" when trying to import a private key in Mac OS X that had been exported as a .p12 (psck12) file, regardless of whether I double clicked on the file, dragged it into Keychain Access, or ran the import command from the terminal.

The problem was actually that I had uploaded the key previously using FTP, and because the key is a text file, ftp altered (and corrupted) the file when it was transferred. To fix this, I emailed myself the key instead, but it would probably also work to use FTP in binary mode (if using command line FTP, type "binary").

So, for anyone else that runs into this error... I suppose it is likely that the file is actually corrupt, and you may want to change the way you are transferring the file. I've heard similar stories about attachments in Outlook.

Android emulator mysteriously crashing on Mac OS X

Today I ran into a very frustrating problem: whenever I would start the android emulator, either through Eclipse or the command line, it would crash, with no helpful messages. When running through Eclipse, it simply crashes and shows you apple's "This application has quit unexpectedly" message. In the command line, you see that a segmentation fault occurs.

Well, it turns out that this is a known problem, and happens when a USB headset is plugged in (debugging nightmare right?). This can be fixed if you either unplug the headset, or change the sound line-in back to the default (not the headset). From command line, you can run the emulator with the no audio option:

$ emulator -avd MyAvd -noaudio

Even with google searching it took me a while to track down such a vague problem, so hopefully this will save someone the couple of hours I spent trying to debug this ridiculous problem.

References

Retrieving via POST and parsing webpage contents in PHP

Today I had set myself to the task of retrieving a page's contents via POST (where I had to submit some form parameters), and then extracting some pieces of information from the HTML so I could return it in an XML webservice.

Surprisingly, thanks to the library pecl_http and PHP's DOM parsing classes, this can result in a very simple, straightforward script. So if you are looking to do something similar, take a look at my script below for a headstart (which I think serves as a readable example):


// Get page contents
$fields = array(
    'param1' => 'foo',
    'param2' => 2,
);
$html = http_post_fields('http://www.example.com', $fields);
 
 // Create DOM object
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->resolveExternals = true;
@$doc->loadHTML($html);
 
 // Retrieve the TRs in question
$xpath = new DOMXPath($doc);
$rows = $xpath->query("//table [@class = 'important_class']/tr");

// Create XML
$xml = '<xml>';
foreach ($rows as $row) {
	$td = $row->firstChild;
	$xml .= '
	<el>
		<param1>'.$td->textContent.'</param1>
		<param2>'.$td->nextSibling->textContent.'</param2>
	</el>';
}
$xml .= '</xml>';
 
header('Content-type: text/xml');
echo $xml;

References

Managing multiple tables in the Android SDK

In developing my first android application, I came across the "problem" of creating and working with multiple database tables. Initially I just created a second DbAdapter class, with all of the information for my second table. However, I was ending up with some cryptic runtime exceptions being thrown whenever trying to run a select statement on the table (which turned out to not exist).

Searching the internet, surprisingly, the best example I could find was putting all of the CRUD methods for every table within one huge DbAdapter class. Obviously this is not ideal, because your class could become thousands of lines long. So, after a bit of playing, I came up with another solution where each table has its own DbAdapter class which simply extends an AbstractDbAdapter. The code for the abstract class is below, which was initially based on the Notepad Tutorial. Some notes beforehand:

  • The create statement(s) must all go in the abstract parent class, because the tables must all be created at the same time. Obviously this is not ideal (because then the parent must be updated each time you create a new child), but I think it's a small price to pay for being able to keep all of the CRUD methods separate. Note that in order to add a table to an existing app, you must uninstall it first.
  • The create statements must be separated inside the parent class, because db.execSQL() can only execute one statement at a time.
  • You'll notice I've also changed all private vars/methods to protected (though I'm not sure if it's necessary in every case).

So, the full code for my abstract class:


package com.pheide.trainose;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public abstract class AbstractDbAdapter {

    protected static final String TAG = "TrainOseDbAdapter";
    protected DatabaseHelper mDbHelper;
    protected SQLiteDatabase mDb;

    protected static final String TABLE_CREATE_ROUTES =
        "create table routes (_id integer primary key autoincrement, "
        + "source text not null, destination text not null);";
    protected static final String TABLE_CREATE_TIMETABLES =    
        "create table timetables (_id integer primary key autoincrement, "
    	+ "route_id integer, depart text not null, arrive text not null, "
    	+ "train text not null);";

    protected static final String DATABASE_NAME = "data";
    protected static final int DATABASE_VERSION = 2;

    protected final Context mCtx;

    protected static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(TABLE_CREATE_ROUTES);
            db.execSQL(TABLE_CREATE_TIMETABLES);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
            db.execSQL("DROP TABLE IF EXISTS routes");
            onCreate(db);
        }
    }

    /**
     * Constructor - takes the context to allow the database to be
     * opened/created
     * 
     * @param ctx the Context within which to work
     */
    public AbstractDbAdapter(Context ctx) {
        this.mCtx = ctx;
    }

    /**
     * Open or create the routes database.
     * 
     * @return this
     * @throws SQLException if the database could be neither opened or created
     */
    public AbstractDbAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

    public void close() {
        mDbHelper.close();
    }

}

Each child class will then simply extend this class, run the parent's constructor, and include all of the CRUD methods etc for that specific table. An example child class:


package com.pheide.trainose;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;

public class RoutesDbAdapter extends AbstractDbAdapter {

	public static final String KEY_SOURCE = "source";
	public static final String KEY_DESTINATION = "destination";
    public static final String KEY_ROWID = "_id";

    private static final String DATABASE_TABLE = "routes";

    /**
     * Constructor - takes the context to allow the database to be
     * opened/created
     * 
     * @param ctx the Context within which to work
     */
    public RoutesDbAdapter(Context ctx) {
    	super(ctx);
    }
    
    /**
     * Create a new route.
     * 
     * @param source
     * @param destination
     * @return rowId or -1 if failed
     */
    public long create(String source, String destination) {
    	ContentValues args = new ContentValues();
    	args.put(KEY_SOURCE,source);
    	args.put(KEY_DESTINATION,destination);
    	
    	return mDb.insert(DATABASE_TABLE, null,args);
    }
    

    /**
     * Delete the route with the given rowId
     * 
     * @param rowId
     * @return true if deleted, false otherwise
     */
    public boolean delete(long rowId) {
    	return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
    }

    /**
     * Return a Cursor over the list of all routes in the database
     * 
     * @return Cursor over all notes
     */
    public Cursor fetchAll() {
    	return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_SOURCE,
    			KEY_DESTINATION}, null, null, null, null, null);
    }

    /**
     * Return a Cursor positioned at the route that matches the given rowId
     * 
     * @param rowId id of route to retrieve
     * @return Cursor positioned to matching route, if found
     * @throws SQLException if route could not be found/retrieved
     */
    public Cursor fetch(long rowId) throws SQLException {
        Cursor mCursor =
            mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
                    KEY_SOURCE, KEY_DESTINATION}, KEY_ROWID + "=" + rowId, null,
                    null, null, null, null);
        if (mCursor != null) {
            mCursor.moveToFirst();
        }
        return mCursor;

    }

Hello Android "No such file or directory"

I got an error today trying to run the Hello World android application Hello, Android:

com/example/helloandroid/R.java: No such file or directory

Because all I could find online was a single tweet written in Spanish mentioning the error, I will tell you that upgrading Java and restarting my computer seems to have fixed it. I'm using Eclipse on Mac OS 10.5, building against the 2.1 Android SDK. Hope this can help someone.

Update: I saw a similar error again in a later project. The R.java file was not being automatically populated correctly with UI elements. The reason was because my activity class was importing R.java (which I guess happened after doing cmd-shift-o to auto-import all needed classes). Removing the import statement and from my activity class and cleaning the project (Project > Clean) fixed this.

References

Configuring FLOW3 alpha7 to use MySQL

Looking around the internet, I could find no real documentation on switching FLOW3 to use mysql except for one mailing list thread asking for help with a faulty config for alpha6. So, for those of you who are wondering, these are the steps you'll need to follow to configure FLOW3 to use MySQL instead of SQLite, at least in alpha7. Note, as this is an alpha release, it can of course change.

  1. Create a database in mysql.
  2. Run all the create statements inside of /Packages/Framework/FLOW3/Resources/Private/Persistence/SQL/DDL.sql. You'll probably have to add back tick marks (`) to SQL keywords to avoid syntax errors.
  3. Configure FLOW3 to use MySQL by editing the /Configuration/Settings.yaml file. These settings will override the default settings specified in /Packages/Framework/FLOW3/Configuration/Settings.yaml. Note that you may need to create this file yourself:
    FLOW3:
    
     persistence:
    
      # Options for the default PDO backend
      backendOptions:
        dataSourceName: 'mysql:host=localhost;dbname=yourdbname'
        username: root
        password: yoursqlpassword
    

And voila, FLOW3 now uses MySQL! Swappable persistence layers FTW.

Adding startup scripts on CentOS

So I remember:

# /sbin/chkconfig --add sshd

Useful SQL commands for TYPO3/LAMP

Note that some commands are at the shell prompt (#) and some at the MySQL prompt (>). Set your root password after a fresh install:

# mysqladmin -u root password NEWPASSWORD

In SQL, create a new database as well as a new user

> CREATE DATABASE typo3;
> CREATE USER 't3user'@'localhost' IDENTIFIED BY 'passwd';

Select the database and grant privileges to your new user

> USE typo3
> GRANT ALL ON typo3.* TO 't3user'@'localhost' IDENTIFIED BY 'passwd';

Exit and reload the grant tables (not always necessary)

# mysqladmin -u root -p reload

Now see if it worked by logging in

# mysql -u t3user -p typo3

References

Installing PHP 5.2 on CentOS

This weekend I wanted to install PHP 5.2 on my CentOS server, but it turns out that the most recent version of PHP in the package manager (yum) was 5.1.6. Why they haven't added 5.2 I don't know, but what you have to do is attach a 3rd party repository and install from there. The process is actually very simple; see the two links below for how to do it (the first is instructions on upgrading, the second is the actual repository). Completing this left me with PHP 5.2.11.

To install MySQL support for PHP, you can use yum to install the package php-mysql. Both of these steps require restarting Apache (/sbin/service httpd restart).

References:

Necessary PHP USE flags for TYPO3

Just as a helpful FYI, if you're looking to install TYPO3 on a gentoo box, be sure to enable the following USE flags for PHP. Then you can avoid having to recompile PHP 3 times like I did before getting the CMS Backend to work:

  • json
  • filter

The other flags I already had enabled (and I don't know which are required for TYPO3) are: ctype truetype hash simplexml xml cgi pdo sqlite xmlwriter

Typoscript for pheide.com

I configured the two menus I use on my site (yes, this site) in Typoscript today. The submenu is relatively straightforward, while the header menu took a little more documentation reading. Note that almost all of the styling is just CSS, so really it was a matter of configuring the correct wraps for each menu item. You'll see the NOrmal state config takes advantage of optionSplit, specifying a different wrap for every page element in the first level. The label you see inside the computer screen is the title of the Parent of the page you are visiting, so I've implemented that as another hierachical menu with just one, unclickable page (lib.activeLabel). This goes in the Template setup of the root page.


# Graphical header menu
lib.mainMenu = HMENU
 
lib.mainMenu {
  special = list
  special.value = 25,27,1,23,1,26,24
  1 = TMENU
  1 {
    NO.wrapItemAndSub (
      <li id="mill">|</li> || 
      <li id="purse">|</li> || 
      <li id="milk">|</li> || 
      <li id="notebook">|</li> || 
      <li id="bottle">|</li> || 
      <li id="scissors">|</li> || 
      <li id="books">|</li>
    )
    NO.stdWrap.wrap = <span class="label">|</span>
    # I despise Javascript
    NO.ATagParams = onmouseover="show(this);" onmouseout="hide(this);"
  }
}
 
# Label for current page
lib.activeLabel = HMENU
lib.activeLabel {
  entryLevel = 1
  special = list
  1 = TMENU 
  1 {
    NO.allWrap = :|
    NO.doNotLinkIt = 1
  }
}
 
# Subnavigation
lib.subMenu = HMENU
lib.subMenu {
  wrap = <ul id="cats">|</ul>
  entryLevel = 1
  1 = TMENU
  1 {
    NO.allWrap = <li>|</li>
    NO.stdWrap.htmlSpecialChars = 1
    
    ACT = 1
    ACT.stdWrap.htmlSpecialChars = 1
    ACT.allWrap = <li class="active">|</li>
  }
}
		

References

Installing PHP 5.2 and 5.3 together in Gentoo

PHP packages in Gentoo are marked with slots so that you can have major releases like PHP4 and PHP5 installed concurrently on your system. However, all packages within a major version use the same slot, so that when you upgrade from say, PHP 5.1 to 5.2, the 5.2 files will replace those from 5.1. Sometimes though we want to be able to even have medium or even minor releases both installed (in my case, I wanted PHP 5.3 for FLOW3, and PHP 5.2 for TYPO3). At the time of writing, PHP 5.3 is not in the portage tree yet (or actually any overlays), so now I face two problems: 1) find a working 5.3 ebuild and 2) install that ebuild alongside PHP 5.2.

Problem (1) was solved for me by downloading the 5.3.0 ebuild from the version bump request issue here. Put the ebuild files in /usr/local/portage/dev-lang/php/. There is also an ebuild for a slotted 5.3.1 attached to this issue -- which sounds even better -- but unfortunately it wasn't compiling for me.

So now that we have our ebuild, we need to install it together with 5.2. One approach would be to edit the ebuild, adding a new 5.3 slot and make sure no files are placed in generic php5 directories, which would then obviously conflict with other installations. But, I don't know enough about editing ebuilds to do that. So the gameplan becomes: move your current PHP files/folders out of the default locations, install PHP 5.3 normally, move around the PHP directories to your liking, and then figure out how to switch between the different versions. Ready? Go.

Explained in a bit more detail now... First step is move your current PHP installation (in my case 5.2) to a new location (or if you haven't installed PHP yet, install it now). Note, you may need to adjust your exact file locations, and I am assuming that the apache module is being used.

# mv /usr/lib/php5 /usr/lib/php5.2/
# mv /usr/lib/apache2/modules/libphp5.so /usr/lib/apache2/modules/libphp5_2.so

Now that our current installation is safe, install PHP 5.3. You should see that you can now upgrade from your new ebuild.

# emerge -av php

After compiling, PHP 5.3 will be installed in /usr/lib/php5 and PHP 5.2 will still be where we put it earlier. In my case, I wanted to have PHP 5.2 installed in the default PHP5 locations, so that future upgrades from portage would replace that release. So at this point I moved around these directories so that 5.2 was in /usr/lib/php5, and 5.3 was in /usr/lib/php5.3. Do as you wish. What you SHOULD do, however, is copy the apache shared object:

# cp /usr/lib/apache2/modules/libphp5.so /usr/lib/apache2/modules/libphp5_3.so

At this point we have two working PHP versions installed. If you start apache now, you should be able to use whichever object file is currently in libphp5.so. So, now all we have to do is figure out how to switch between them. Switching involves setting libphp5.so and setting the PHP-relevant symlinks inside of /usr/bin/ to the correct PHP path. To do this I have created a short script called php-minor-select. With this, you should be easily able to switch between PHP 5.3 and 5.2 (or other medium/minor installations).

And that's it. I recognize that there are probably easier and better ways to accomplish this, like creating a real slotted 5.3.0 ebuild and perhaps configuring the existing php-select to switch between them, but this was the most straightforward thing for me to do personally. Anyway, hope this proves useful to someone else as well :). Now although I haven't done FULL testing, my web apps seem to run correctly in both environments, and who wouldn't be excited about that?

Configuring a Ricoh R5C822 SDCard reader in Gentoo

Today I configured the SD Card reader in my Fujitsu P7230 laptop, kernel version 2.6.30. Currently working with the following modules: mmc_core, mmc_block, sdhci, and sdhci_pci (all located in Device Drivers > MMC/SD/SDIO card support). After recompiling, autoload the drivers by adding them in /etc/modules.autoload.d/kernel-2.6 (or whatever your kernel version is). You'll notice on reboot that new devices have been added like /dev/mmcblk0 and /dev/mmcblk0p1 when you insert a card. Then you can mount /dev/mmcblk0p1 wherever you like.

References

Fluxbox: finding open windows

On this page you can find a handy script that brings forward open instances of an application, else it starts a new instance, making an excellent keybinding for things like browsers or terminal. http://fluxbox-wiki.org/index.php?title=Keyboard_shortcuts

vim

To set the tab size in vim, add ':set tabstop=4' in your .vimrc, changing 4 with whatever number of spaces you want.

Apache

Made a local copy of my site on my laptop for easier playing. Used this site for reference on necessary packages to get a php/mysql (not that my site uses a DB yet, but oh it will) web server running locally, and also installed phpdocs, which is a vim plugin for generate phpdoc (=awesome).