Bernhard Häussner
Tags: Artikel mit dem Tag «Webdev» durchstöbern

Howto: Start using Subversion

31.01.2010, 14:46
Subversion

Subversion

Sometimes you want to start using Subversion code control with an existing project. This tutorial explains the steps required to create a repository and add the files of the existing project.

Start by creating a repository:

svnadmin create /dir/to/store/repo/repository-name

This will create a directory „repository-name“ containing the database of files and revisions.

Then let's add some internal directories to our repository:

svn mkdir file:///dir/to/store/repo/repository-name/trunk \
 -m "Creating repo directory structure"

Now that you have created the repo-directory that should contain all the files, import the existing project files. Start by checking out the empty repo-dir to into your project dir. This will make your project dir a working copy (that is: create a dir named „.svn“ containig some internal info) but won't change anything else.

cd /existing/poject/dir
svn checkout file:///dir/to/store/repo/repository-name/trunk .

Then go on adding (or planing to add) all the files:

svn add *

This command will list all the files that will be loaded into the repository. You can always look at the planned changes with svn st.

You probably want to exclude some files such as configuration files, runtime data. You just have to revert the add-command again:

svn revert runtimedata # exclude whole dir
svn revert config/my.ini # exclude single file

Then apply the changes to your repository (commit it):

svn commit \
-m "initial import"

And that's it. You project is added to the repository without extra files. That can be crucial if your runtime data has a huge file size. If you're paranoid or just curious check the repository for success:

svnlook tree /dir/to/store/repo/repository-name

This should show the imported directory tree. Now you can start making changes to your files and commit them as usual.

vim app.cpp
svn commit -m "typo"
svn log -r 1:HEAD #show full revision history

If you ever got stuck, you may use the built in help:

svn help #list commands
svn help commit #list options
svnlook help tree #works too

I will start using subversion for everything... soon.

Kommentare: 4 Einträge

Symmetrisch Zeichnen

17.12.2009, 10:43

Neben Symmetrie in der Natur bin ich auch begeistert von den Symmetrien, die der Computer erstellen kann. Und was wäre diese Symmetrie ohne die, für den Computer typische, Interaktivität? Also habe ich (zunächst mit Processing aber dann mit) HTML5-Canvas eine kleine Javascript-Sache gebastelt, mit der man direkt im Browser symmetrisch zeichnen kann.

Irgendwie macht das Spaß und, naja, es sieht auch oft erstaunlich gut aus.

[Updated 2011-09-29] Da mir das einfache herumzeichnen schnell zu langweilig wurde, habe ich das Script immmer weiter ausgebaut. Deswegen finden sich unter dem Link nun mehrere Variationen, die es sich auszuporbieren lohnt![/Updated]

Zum Zeichenbrett

Und hier noch ein Video:


Drawing Symmetry (6)

Viel Spaß beim Malen!

Kommentare: 2 Einträge

jQuery Plugin intoViewport

06.08.2009, 20:08

Das Plugin intoViewport erledigt als Erweiterung zu der populären Javascript-Bibliothek jQuery das scrollen bestimmter HTML-Elemente einer Webseite in den Sichtbereich des Browsers, aber nur wenn nötig und nur so weit wie nötig. Es hat nur eine Größe von 480 Byte (minified).

Demo

Dieses minimale jQuery-Beispiel würde den 4. Link auf der Seite in das Darstellungsfeld des Betrachters scollen:

$('a').eq(4).intoViewport();

Scrollen - so viel wie nötig und so wenig wie möglich

Das Script vergleicht jeweils Höhe und Y-Position des übergebenen DOM-Elements und des aktuell sichtbaren Seitenausschnitt des Browsers (Viewport).

Sollte das Element über den Viewport herausragen, oder gar komplett über diesem sein, scrollt es so weit nach oben, bis das gesamte Element sichtbar ist, also wird die Oberkante des Ausschnitts an die Oberkante des Elements verschoben.

Sollte das Element hingen weiter unten liegen, scrollt es nach unten, und wiederum nur so weit, dass es Element gerade sichtbar ist.

Ist das Element schon komplett im Viewport, so tut es überhaupt nichts. Die Scroll-Maßnahmen sind möglichst restriktiv gehalten, da scrollen ungefragt, oder gar sinnlos, den Benutzer der Seite für gewöhnlich verwirrt.

Im Fall, dass das Element größer als das Browserfenster ist, versucht das Plugin möglichst viel des Elements anzuzeigen und scrollt die Oberkante des Elements an den Oberen Bildschirmrand, sodass man immer noch oben beginnen kann zu Lesen.

Wieso, Weshalb, Warum?

Das Plugin soll verhindern, dass, beispielsweise mit jQuery, später eingeblendete Elemente vom Surfer unbemerkt erscheinen, wie Warnmeldungen.

Benötigt habe ich das Plugin auch für meine Suchfunktion, wo nach Möglichkeit die Ergebnisliste komplett angezeigt werden soll. Denn hier sind versteckte Teile fatal: man tippt (meist) mit beiden Händen und kann daher nicht scrollen. Außerdem wird bei der Tastaturnavigation durch die Suchergebnisse der Bildschirmausschnitt dem gewählten Ergebnis folgen.

Die Einsatzgebiete sind sicher noch vielfältiger und der Kreativität sind, wie immer, keine Grenzen gesetzt.

Es grenzt sich von der Javascript-Funktion scrollIntoView() dadurch ab, dass es sanft (animiert) scrollen kann, dadurch den User nicht total orientierungslos lässt. Zwar gab es schon Lösungen zum sanften Scrollen mit jQuery, aber diese beinhalteten leider nicht den Test, ob und wie weit gescrollt werden muss.

Der Javascript-Quelltext

Für Interessierte, hier der Sourcecode des Plugins:

(function($) {
  jQuery.fn.intoViewport = function(options) {
    options = $.extend({
      // Configuration
      // Add whatever options animate schould get by default
      duration:  200,
      easing: "swing"
    }, options || {});
    return this.each(function(){
      // scroll to certain destination:
      function scrTo(dest) {
        $("html,body").stop().animate({ scrollTop: dest}, options );
      }
      var
        //current viewport Y-position
        scr=$(document).scrollTop()||$(window).scrollTop(),
        // viewport Y-size
        wheight=$(window).height(),
        // element Y-position
        top=$(this).offset().top,
        // element Y-size
        eheight=$(this).outerHeight();
        // case element before viewport:
        if (scr>top) {
          scrTo(top); // scroll up to element
        // case viewport before element (bottom part of e. outside):
        } else if (scr!=top && top+eheight>scr+wheight) { 
          // scroll down till everything is inside
          scrTo(top+Math.min(eheight-wheight,0));
          //              ^ but don't hide top part again
        }
      });
    };
})(jQuery); //compatibility

Ich habe das Plugin allerdings nicht nicht in zu vielen Browsern und Situationen getestet. Daher könnte es sein, dass es in einigen Browsern nicht funktioniert. Auch könnte es Probleme geben, wenn die Elemente innerhalb von scrollbaren Elementen liegen, wie <div>s mit der CSS-Eigenschaft overflow:auto;.

Kommentare: 2 Einträge

Javascript Library Builder

31.07.2009, 13:07
JS-Build

JS-Build

Es gibt einige Methoden Javascript auf HTML-Seiten einzubinden. Ein Block im <body>, in onclick-Attributen und ähnlichem, oder als Verknüpfungen im <head> aber am besten in einer externen Datei, die nach dem HTML-Dokument geladen wird. Nur will man beim Entwickeln die einzelnen Javascript-Teile meist in getrennte Dateien legen und auf der Seite dann möglichst viel in eine (am besten möglichst kleine) Datei packen, um Requests zu sparen. Dieses Problem kann der Javascript Library Builder lösen, ein recht kurzes Shell-Script, welches eine Sammlung von .js-Dateien in wenige Dateien minimiert.

Man nehme zum Beispiel eine solche Dateistruktur:

lib/
  php/...
  js_frontend/
    00_jQuery.js
    01_jQ_plugin.js
    02_effekte.js
    licence.txt
  js_backend/
    03_ajaxCalls.js

Der Scriptaufruf wäre so einfach wie:

jslibbuild.sh -o build lib/js* 

Ich habe auf dieser Seite 27 einzelne Dateien, die ich in zwei Javascript Dateien packe, nämlich für die Seite und für das CMS. Diese Beispiel-Dateistruktur würde jetzt in den zwei Dateien js_frontend.min.js und js_backend.min.js im Ordner build resultieren. Der Datei js_frontend.min.js würde zusätzlich nach dem minimieren mit jsmin die Datei licence.txt vorgehängt, sodass z.B. in Kommentaren (die von jsmin geschluckt werden) vermerkte Autorenhinweise erhalten bleiben, was unter anderem bei den CC-Lizenzen nötig ist.

Dazu akzeptiert das Script die optionale Option -l nach der der Name der Lizenz-Dateien angegeben wird. Eine weitere optionale Option ist -c, um das build-Verzeichnis vor dem Anlegen der neuen Dateien zu löschen. Das ist nötig, wenn ein ganzer source-Ordner gelöscht wird, aber dringend zu vermeiden, wenn weitere Dateien im build-Ordner liegen. Hier noch ein Beispiel:

jslibbuild.sh -c -l gpl.txt -o /srv/www/htdocs/js ~/web/lib/js/* 

Das Script benötigt jsmin, steht unter GPLv2+ und kann hier heruntergeladen werden:

Zum „installieren“ einfach in den Ordner ~/bin kopieren. Das Script ist eigentlich ziemlich einfach, kann aber doch einiges an Arbeit ersparen.

Kommentare: keine

My MySQL API onion for PHP

26.07.2009, 17:42
MySQL Onion

MySQL Onion

A huge part of web applications is usually the interaction with the SQL database. This is why I want as little work as possible connecting, escaping values, getting the right tables an so on in PHP. But it should stay simple and allow modular approaches. Therefor I'm using some nested APIs for doing queries easily:

PDO

The very fist thing I am using is PDO. It can handle many RDBMS, but I am most of the times using MySQL or SQLite. By using PDO as an API for the following layers I can make sure most of the code will work for many RDBMSs. PDO even simplifies transactions and prepared statements. Here's some sample PHP code using PDO:

$pdo=new PDO('mysql:host='.$host.';dbname='.$db, $user, $passwort);

$pdo->exec('UPDATE test SET foo="bar" WHERE id=4');

$satement=$pdo->prepare('SELECT * FROM blogeintraege WHERE id=:id');
$satement->bindValue(':id',3,PDO::PARAM_INT);
$satement->execute();
$data=$satement->fetchAll();

PDO Simplifier

The next layer is a class that will hold a MySQL database Connection (a PDO Object) and offer some simple functions for doing e.g. a simple prepared statement. Instead of binding each values manually, you can throw an array in.

It also includes a cache, if you want to run statements more than once. It can append a prefix to all queried tables and checks dynamically inserted tables for validity to avoid SQL-injections and MySQL errors. It is used like that:

$res=$db->sql("SELECT * FROM blogeintraege");
$res=$db->sql(
  "SELECT * FROM #test WHERE id=:id",
  array('id'=>$id),array('id'=>PDO::PARAM_INT),
  array('test'=>'blogeintraege'),
  array('limits'=>array(0,$l),'buffered'=>false)
);

For one array element this does not look too tiny, but the more values are bound, the more useful it gets. And it is very useful if you already have your values in an array, like $_GET.

Note that nearly everything is optional. The table array can contain more tables, for example you can have an array of tables for different languages, if they are in different tables. The bind-types don't need to be specified too. You can even leave out everything except the query as shown in the fist line of code. The Result will by default be returned as a nice array (the GROUP_CONCAT fields are array'ed too) but you can use all other PDO fetch types.

This layer follows a rather functional approve, so I needed another layer for accessing the central sql()-Function in an OOP manner. This should avoid some runtime errors and you can modify the SQL in a modular system.

Statement builder

So I created a wrapper object, that holds a pointer to the database and will construct the parameters for sql(). This comes in handy as more and more optional parameters are added.

The PDO Simplifier has a method to build such statement-objects called sqlO(). This is how the wrapper is used:

$db->sqlO('INSERT INTO blogtaglinks SET ##,type=3')
   ->setSet(array('ID_tag'=>$lasttagid,'ID_entry'=>$id))
   ->exec();
$res=$db->sqlO("SELECT * FROM #test WHERE id=:id")
        ->setData(array('id'=>$id))
        ->setDataTypes(array('id'=>PDO::PARAM_INT))
        ->setTables('test'=>'blogeintraege'),
        ->setLimits(0,$l)
        ->setBuffered(false)
        ->exec();
);

As you can see, it is a little more code, but the code is pretty self-explanatory and now one can build the sets and the other parameters as arrays and then include them easily in the statements.

A bit different: Zend Framework's $db->select() approach

A next step would be to build queries with a single API. This is a feature implemented by the Zend Framework, where you can build your SQL with some API functions and it will even work across various databases:

select = $db->select()
  ->from('blogeintraege',array('id','Titel'))
  ->where('id < ?', $id)
  ->order('id DESC')
  ->limit(0,10);

Well doesn't that look nice?

Kommentare: keine
[ Seite 1 2 3 4 ] Nächste Seite »
 
Χρόνογραφ
© 2008-2014 by Bernhard Häussner - Impressum - Login
Kurz-Link zur Homepage: http://1.co.de/