Friday, December 9, 2011

Java abstract classes

Pretty basic stuff, but nicely explained:

In Java:
- Abstract classes have one or more abstract method.
- Cannot be instantiated, but can:
  - Have a constructor (callable from subclasses using super()).
  - Be referenced (Figure f = new Rectangle()).
- Subclasses of abstract classes (Rectangle extends Figure) must implement the abstract methods or must themselves be abstract.

Read the tutorial: http://www.java-samples.com/showtutorial.php?tutorialid=288

Tuesday, December 6, 2011

Table of Contents using XSL-FO

XSL-FO lets you convert XML into formatted text for use on the web of in PDFs.

A neat feature to have in you PDFs is a table of content. In your fo:root tag, after setting the 'layout-master-set' and before handling the sections of your xml:
<fo:page-sequence master-reference="A4" force-page-count="no-force">
<xsl:call-template name="header"/>
<xsl:call-template name="footer"/>
<fo:flow flow-name="xsl-region-body" font-family="Arial" font-size="10pt">
<fo:block color="white" keep-with-next.within-page="always">&#160;</fo:block>
<fo:block background-color="white" text-align="center" border="2pt solid black" font-weight="bold" font-size="12pt" keep-with-next.within-page="always">
Contents
</fo:block>
<fo:block color="white" keep-with-next.within-page="always">&#160;</fo:block>
<xsl:for-each select="section">
<fo:block text-align-last="justify">
<xsl:value-of select="header"/>
<fo:leader leader-pattern="dots" leader-length.maximum="100%"/>
<fo:page-number-citation ref-id="{@sectionid}"/>
</fo:block>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>


Remember for XSL to find the place you are linking to, you need to create a block item with id attribute of the correct section id value:
<fo:block id="{@sectionid}" />
e.g.
<xsl:template match="section">
<fo:page-sequence master-reference="A4" force-page-count="no-force">
<xsl:call-template name="header"/>
<xsl:call-template name="footer"/>
<fo:flow flow-name="xsl-region-body" font-family="Arial" font-size="10pt">
<fo:block id="{@sectionid}" />
<xsl:apply-templates select="header" />
<xsl:apply-templates select="content" />
<xsl:apply-templates select="lastpage" />
</fo:flow>
</fo:page-sequence>
</xsl:template>



NOTE: ref-id may let you select the id with or without curly brackets "{@sectionid}" or "@sectionid".


Also if you want to have a clickable link to the pages listed wrap the line in a basic-link tag:
<fo:basic-link internal-destination="{@sectionid}"></fo:basic-link>
e.g.
<fo:block text-align-last="justify">
<fo:basic-link internal-destination="{@sectionid}">
<xsl:value-of select="header"/>
<fo:leader leader-pattern="dots" leader-length.maximum="100%"/>
<fo:page-number-citation ref-id="{@sectionid}"/>
</fo:basic-link>
</fo:block>


Sources:
http://www.mail-archive.com/fop-users@xmlgraphics.apache.org/msg00300.html
http://www.stylusstudio.com/xsllist/200503/post30180.html
http://www.dpawson.co.uk/xsl/sect3/N8703.html
http://www.xmlpdf.com/tableofcontents.html
http://stackoverflow.com/questions/541370/xslt-how-to-select-xml-attribute-by-attribute
http://www.dpawson.co.uk/xsl/examples.html

Tuesday, October 4, 2011

Jquery UI Sortable Helper option

Jquery UI's sortable and droppable http://jqueryui.com/demos/sortable/#portlets is great for a modular page system.

When you move modules around you see the content of each and they retain the size they had before you 'picked them up'. Sometimes you want to have a replacement draggable object instead of the original.

For this, the Sortable plugin has a 'helper' option, the example uses the value 'clone' for it, but if you want to use a different item you need to give it a function that returns a jquery object from the DOM:

$("#columncontent1, #columncontent2").sortable({
helper: function() {
return $('#draganddrophelper');
}
});


alternatively you can create a new one inside the function:

$("#columncontent1, #columncontent2").sortable({
helper: function() {
return $('<div id="dragdrophelper" style="height: 90px;"></div>');
}
});

Friday, September 23, 2011

IE8 max-height bug

The CSS tag max-height can be useful to make your divs extend to the height of the page.
IE8 doesn't understand max-height. A workaround is this hack:
div {
max-height: 1000px;
<!--[if IE 8]>
max-height: none\9;
<![endif]-->
}
</style>

Sources: http://my.opera.com/dbloom/blog/2009/03/11/css-hack-for-ie8-standards-mode and http://www.sitepoint.com/forums/showthread.php?618830-IE8-Bug-I-need-to-fix

Friday, August 26, 2011

Tuesday, June 28, 2011

Logging in to HTTPS websites using PHP cURL

To log in to a HTTPS website using PHP cURL you need to do the following:

enable cURL by uncommenting the line extension=php_curl.dll in your php.ini file.

Set up cURL to either accept all certificates or add the needed certificate authority to cURLs CA list (check out http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/)

Then you need to load the page to get the session cookie:
// Create temp file to store cookies
$ckfile = tempnam ("/tmp", "CURLCOOKIE");

// URL to login page
$url = "https://www.securesiteexample.com";

// Get Login page and its cookies and save cookies in the temp file
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Accepts all CAs
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile); // Stores cookies in the temp file
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);


Now you have the cookie, you can POST login values (check the source of the login page to check if you need any other fields too)
$fields = array(
'username' => 'yourusername',
'password' => 'yourpassword',
);
$fields_string = '';
foreach($fields as $key=>$value) {
$fields_string .= $key . '=' . $value . '&';
}
rtrim($fields_string, '&');

// Post login form and follow redirects
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Accepts all CAs
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile); //Uses cookies from the temp file
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Tells cURL to follow redirects
$output = curl_exec($ch);


Now you should be able to access any pages within the password-restricted area by just including the cookies for each call:

$url = "https://www.securesiteexample.com/loggedinpage.html";
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Accepts all CAs
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile); //Uses cookies from the temp file
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec($ch);


Found from http://coderscult.com/php/php-curl/2008/05/20/php-curl-cookies-example/, http://davidwalsh.name/execute-http-post-php-curl, http://stackoverflow.com/questions/3519939/make-curl-follow-redirects, and http://www.php.net/manual/en/function.curl-setopt.php.
Also see http://php.net/manual/en/book.curl.php.

Tuesday, June 21, 2011

Mount TonidoPlug as Local Drive

So you want to access your TonidoPlug USB harddrive as a native drive in Windows? Here is how:

Follow http://www.codelathe.com/blog/index.php/2010/03/17/mounting-tonido-shares-as-local-drives/.

To get NetDrive, go to http://www.netdrive.net/download.html for a free for non-commercial home use version. otherwise they'll try to sell it to you. :)

Instead of using the URL or Shared Location from your shares list on the TonidoPlug in the Site IP or URL field in NetDrive, just enter the base url. E.g. http://<username>.tonidoid.com/ .

This should open your root directory of the TonidoPlug, navigate to the USB drive. You can find it under T:\Drive_Root\media (or whatever drive letter you chose). Then you can make a shortcut directly there if you want.

Now you should no longer get the
Mounting drive T: failed
Login failed. Please check the internet connection.

error.

Also check out http://www.tonido.com/forum/viewtopic.php?f=9&t=1410 if you have trouble with the username.