
Eine “Google Custom Search Engine” über mehrere Domains
Es gibt (mindestens) zwei Arten, einzelne Domains in Googles “Benutzerdefinierten Suchmaschinen” zu unterscheiden:
- Für jede Domain eine eigene Suchmaschine anlegen. Vorteil: Separate Keywords, Description, … für jede Suchmaschine. Nachteil: Jede Suchmaschine kostet separat beim Upgrade auf die kostenpflichtigen Features
- Die Domains alle derselben Suchmaschine hinzufügen, und bei Aufruf per Parameter “as_sitesearch” filtern (Quelle, Docs). Vor-/Nachteile sind genau umgedreht.
PS: Option 2 funktioniert nicht nur für Domains, sondern auch für Verzeichnisse, also etwa “example.com/de” vs. “example.com/en”
MacBook: DVD-Laufwerk region-free patchen
Von Olaf habe ich die “Lone Gunmen” auf DVD bekommen (vielen Dank!), leider in der NTSC-Version mit Region Code 1. Mal abgesehen vom NTSC kann weder mein Blu-ray-Player, noch mein MacBook Region 1. Für meinen Player habe ich (auf die Schnelle) auch keine Anleitung zum Patchen gefunden, wohl aber für mein MacBook – in der Praxis gibt es allerdings einige Hürden:
Zuerst muss man herausfinden, welches Laufwerk genau zu patchen ist. Dazu schaut man in seinen “Systembericht” (Apple Menu, Über diesen Mac, Weitere Informationen, Systembericht), oder auf der Kommandozeile:
|
1 2 3 4 |
$ system_profiler -detailLevel mini | grep -A4 ^Disc Disc Burning: MATSHITA DVD-R UJ-8A8: Firmware Revision: HA13 |
Wir suchen also einen Patch für ein Matshita Laufwerk mit der Firmware HA13; beide Informationen sind wichtig. Es gibt Sammlungen mit sehr vielen solcher Patches, meine war natürlich nicht darunter 🙂 Eine Suche nach dem beschriebenen Dateinamen (hier: “MATSHITADVD-R___UJ-8A8__HA13_RPC1.dat”) brachte den Erfolg.
Dann benötigt man das Tool zum Aufspielen des Patches. Man liest dabei abwechselnd vom “MatshitaFlasher” und von “simple_flash”. Tatsächlich ist ersteres nur ein Wrapper für letzteres – was gut ist, denn der MatshitaFlasher läuft nur auf PowerPCs. Man kann simple_flash trotzdem extrahieren: Rechtsklick, Paketinhalt zeigen, Contents->Resources->simple_flash. WICHTIG: Neuere Versionen werfen beim Flashen Fehler wie
Does not appear to be a matshita device
oder
Selected drive (null) does not appear to be a matshita device
, deshalb empfehle ich Version 0.6 des MatshitaFlasher.
Beim Flashen schließlich kommt es darauf an, dass das Laufwerk leer ist; andernfalls gibt es den Fehler
Could not open device
, und dass die richtige Datei verwendet wird. Im oben verlinkten ZIP gibt es auch eine .dat ohne “_RPC1”, die scheint das Backup der originalen zu sein. Also, folgendes funktioniert:
|
1 2 3 4 5 |
$ ./simple_flash 0 MATSHITADVD-R___UJ-8A8__HA13_RPC1.dat compiled at Apr 14 2011 22:33:18 Selected device: MATSHITADVD-R UJ-8A8 HA1 Continue? yes Finished |
HTH
Björk Guðmundsdóttir
https://soundcloud.com/kiyimuzik/hopelandic-bjork
<3 via
Composer: Erste Learnings
Ich versuche gerade, ein Composer-Package zu definieren und aus dem SVN zu installieren, bekomme aber immer die Meldung
Your requirements could not be resolved to an installable set of packages
Es wird nicht ganz klar, ob das an der packages.json im SVN liegt, an der lokalen composer.json, oder irgendwo dazwischen (zB an der Verbindung zum SVN). Leider liefert composer install auch im verbose Modus keine hilfreiche Informationen, aber
|
1 |
composer show acme/my-package --verbose |
hilft. Es zeigt Informationen (zB die description) aus der packages.json (also scheint die Verbindung zum SVN zu klappen), als Version aber nur “dev-trunk”. Offenbar zählt die in der externen composer.json angegebene Version nicht, sondern allein die Tatsache, dass das Package im trunk liegt. Folgendes funktioniert schließlich:
externe composer.json:
|
1 2 3 4 |
{ "name": "acme/my-package", "description": "Lorem ipsum" } |
lokale composer.json:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "name": "acme/hello-composer", "description": "Dummy project", "license": "proprietary", "repositories": [ { "type": "vcs", "url": "https://svn.domain.tld/path/to/project/", "package-path": "src/php/Acme/MyPackage/" } ], "require": { "acme/my-package": "dev-trunk" } } |
Wichtig dabei: “url” enthält nicht “trunk”, und alles hinter “trunk” wandert aus der URL nach “package-path”. So kann man mehrere Packages in einem SVN-Projekt ablegen.
Update “Versionierung”
Eine packages.json wird im externen Package ebensowenig benötigt, wie eine Versionsnummer in der externen composer.json! Die Versionsinformationen ergeben sich implizit aus Tag-/Branchnamen (oder halt “dev-trunk”), was ja auch Sinn macht, denn natürlich enthält das Repository alle Versionen.
Eine ganz bestimmte Revision kann man wohl mit
|
1 |
"reference": "trunk@12345" |
angeben (Quelle)
Update “SVN”
Mit dem oben beschriebenen Vorgehen muss man für jedes “require” Package ein eigenes Repository definieren. Das ist übrigens unabhängig davon, ob alle Packages in einem SVN-Projekt liegen, oder jedes Package sein eigenes Projekt hat – so lange man nicht jedem Package sein eigenes SVN-Repository geben möchte, kommt man da nicht drumrum. IMHO eine Designschwäche; Composer ist halt sehr auf git fixiert.
Anyway: Eine Möglichkeit, die “repositories” in der lokalen composer.json zu begrenzen, wäre der Einsatz von Satis:
[Satis] can be used to host the metadata of your company’s private packages, or your own.
[…]
You don’t need to copy all your repositories in every project anymore. Only that one unique repository that will update itself.
*Notwendig* ist das nicht, aber es macht die Sache übersichtlicher.
Update “SVN”/2.
Ohne Satis sind “verschachtelte” Abhängigkeiten nicht möglich (siehe), die unschöne “Lösung”: Alle Abhängigkeiten im Root-Projekt definieren (Quelle) 🙁
PS: Composer – und folglich auch Satis – laufen auf uberspace 🙂
Optimizely: Custom Javascript in Variation
Optimizely: Wer als Teil einer Variation eigenen JS-Code ausführen möchte, muss diesen Code in
|
1 2 3 |
(function($) { /* code goes here */ })(window.jQuery); |
kapseln (Quelle).
BTW: Man sollte
|
1 |
/* ... */ |
statt
|
1 |
// ... |
verwenden, da das JS in eine Zeile minifiziert wird.
Bass Porn
★★★★
Symfony: Multiple Twig Extensions
Bei der Verwendung von mehreren Twig Extensions mit jeweils eigenen Funktionen bekommt man schnell eine Fehlermeldung à la
The function “my_function” does not exist in mytemplate.html.twig at line 42
Meine erste Idee war, dass das an der Art der Registrierung in den Extensions liegt:
|
1 2 3 4 5 6 |
public function getFunctions() { return array( new \Twig_SimpleFunction('my_function', array($this, 'mySpecialPhpFunction')), ); } |
– vielleicht überschreibt ja jeder Aufruf von getFunctions() das vorherige Array? Mein Ansatz: Statt der Rückgabe eines Arrays in getFunctions() lieber jede Funktionen (hier: im Konstruktor der Extension) separat adden:
|
1 |
$this->container->get('twig')->addFunction(new \Twig_SimpleFunction('my_function', array($this, 'mySpecialPhpFunction'))); |
Leider lag es gar nicht daran. Stattdessen hatte ich einfach in der zweiten, neuen Extension nach dem Copy&Paste vergessen, den Namen zu korrigieren:
|
1 2 3 4 |
public function getName() { return 'my_extension'; } |
Der fungiert offenbar als eine Art Namespace, in dem sie die Arrays vermutlich tatsächlich überschrieben haben 🙂 Anyway: Die alternative Methode der Definition von Funktionen mag noch mal hilfreich sein.
Symfony: “Unable to find template”
Die Überschrift ist etwas irreführend. Es geht darum, dass referenzierte Templates nach dem Muster
bundle:section:template.format.engine
aufgebaut sein müssen. Der Teil “template” muss (?) dabei den relativen Pfad enthalten, zB
MyProjectBundle::pages/testpage.html.twig
, andernfalls kommt es zu der Fehlermeldung aus der Überschrift. Nun will man vielleicht nicht an drölf Stellen diesen Pfad (oder das Bundle!) angeben (sei es der Zentralisierung wegen, sei es aus Faulheit beim Tippen). Lösung: FilesystemLoader, bzw. das geerbte Twig_Loader_Filesystem->addPath(…):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class TestpageController extends Controller { public function indexAction($name, Request $request) { // ... $loader = $this->container->get('twig')->getLoader(); // add bundle and everything below: $loader->addPath('my/template/root'); $loader->addPath('my/template/root/subfolder'); // no more redundant stuff required: return $this->render('testpage.html.twig', $vars); } } |
bzw. im Template:
|
1 2 3 4 |
{% extends 'layout.html.twig' %} {# instead of #} {# extends 'MyProjectBundle::layout.html.twig' #} |