Sunday, October 20, 2013

Setup a Drupal 7 Multilingual site

This post is about how to setup a multilingual website with content translation.

I will do another post about entitity translation, but setting up a site with entity translation is, in my opinion, not ready for production releases. [*]


1. Install a Drupal 7 site
2. download needed interface translations
for drupal core from here: http://ftp.drupal.org/files/translations/7.x/drupal/
3. save them
(the languages you plan to install) in /profiles/standard/translations/
4. Enable locale and content translation (are in drupal core)
5. Download and install
internationalization (i18n)
https://drupal.org/project/i18n
variable

https://drupal.org/project/variable
You need this module when for instance you have a node page as your front page, and automatically wnat yo switch this to the german version when changing language.
localization update
https://drupal.org/project/l10n_update
Provides automatic downloads and updates for translations.
6. Under internationalization choose 
which modules tom enable
menu translation
You have to make a choice: If both (or all of) your siets wille have the exact same sytructure, with all content translated, you will be verwy happy with the menu translation module. Its a RAD feature for the menu's. But when you have sites which have a different structure for all language versions, this module will make you very, very, verry unhappy.  Then you'll be better of with simply maken menu blocks and showing them dependent on the language.
In this showcase We'll be using this, cause the language versions of the site will be exactly congruent.
path translation
Normal nodes and users will be codennecte in translation sets. But to be able to add a language switch to for instance a page view, or a panel page, you will need path translations.
translation sets
This will couple the different language versions (which are nodes) in a language set.
String translation
Enables translations for string in modules, templates etcetera (added with the t-function) that are not added to the po files. Not strickly neccesary but come in handy.
Multilingual content
Also not strickly neccesary but helps the workflow. You can set default languages, lock node translations on existing nodes, etcetera.
Field translation
This option is also not a content deirected translation module, bu helps the workflow. You can translate texts associated with field settings etcetera. So helpfull when you have a multilingual site and want users or administrators to see help texts et cetera in their own language.
There is another module 'entity translations' which deals with the language versions of fields within a node, but thats quite another story...
Block languages
You definitely want that. It enables you to handle blocks just as you handle nodes. You can translate a block, and set for which langua version it has to appear.
Multilingual select
When you want to be able to select languages in a view, you need this module. Variable translation
You need this module for instance when yoy want to set a different homepage, and the homepage being a specific node, on for each language version.
5. Go to configuration /admin/config
6. Go to languages /admin/config/regional/language
7. add the languages you need
 (im my case I installed germand and french next to english, and disable french because the site will for now be english/german, and in a later stage be extended with the french version.
8. Add language prefixes to the path
That's on the language pag, /admin/config/regional/language, and click on edit behind each alnguage
The custom way is to add the language code as a path prefix.
In my case 'en' for english, 'de' for german (as in 'deutch') and 'fr' for french.
(on existing siytes this option wil defenitely break all existing nodes paths! So google around how to avoid that.) [*]
9. Language detection
While you are still on the language page, click the tab 'Dtection and selection'
/admin/config/regional/language/configure
Simply choose Determine the language from the URL (Path prefix or domain).
(there is a lot to say about the other options, but we simply skip that for another day)[*]
10. Import core (and module) interface languages
If you've saved the language po files on de server in the map profiles/standard/translations during install of teh language this languager file will be imported.
Otherwise you have to download the po file later, go to configuration, admin/config, and under regional and language, select translate interface: Translate the interface. Then choose the import tab, and the rest is just following orders...

10.1 Automation
Because you've installed the internationalization update module, you also have a tab 'update' on this page, where you can check which module ranslations have not been added yet...
admin/config/regional/translate/update
Now you can dowmnload and import alle these files by hand, but a better way is to simply push the update button  underneath your page. get a cup of coffe, eat some bisquits, talk to the wife (or the man), play with your children. Drupal automatically imports all translation files needed.


11. Enable multilingual contentypes
Go to each translatable contenttype and under publishing options enable the 'multilingual settings with translation'.
Dont't forget the translation part. You won't be the first frantically looking for this translate tab
Go to the multilingual settings under the same contenttype and choose the settings you want. I usually do this







12. Multilingual paths

If you've not yet installed pathauto, do so immediately!
https://drupal.org/project/pathauto
Because you want to make your paths also multilingual, so if you have a standard in your autopath for for instance a contenttype 'loveletters', say 'love-letters/[node:title]' you can set  a pattern for the french version like 'lettres-d-amour/[node:title]'
You'll probably also need transliteration
https://drupal.org/project/transliteration
To convert any diacritic characters like the æ danish.
After installingTransliteration, go to Configuration > Search and metadata > Url aliases > Settings
There check the option ' Transliterate prior to creating alias' and 'Reduce strings to letters and numbers'.
A page with 'Jæle' in the name will then be saved with an url 'jaele'.


13. Roles
Create an editor role, an set permissions for this role for the site maintainers.

14. Homepage
In my case I wil need two (and lateronon three) nodes for each language version to be the homepage.
The homepage wil consist of some views and block.
Fisrst I add a node for the english frontpage, and tranlate this one for the german frontpage.
We need now to have Variable and Variable translation installed.
14.1
Go to configuration, regional and language, multilingual settings, the variables tab.
Choose the site information sub tab and select the deafult front page.
Better is to select all options given there.
14.2
Now go to the configuration > site information page. And add the url to the default front page.
It's best to add it with the node path like node/2'. (no slash in front)
Select one of the the other languages on the top of the configuration page (which is simply a menu for the language contect of the translateble variables in the current configuration page) to change the setting for these languages.
NB! The configuration page has a language prefix before it, which may be confusing.
14.3
If you go to the home page and change languages with the language switch, you'll see everything works hunky dory.


15. Multilingual menu's
One way to ad multil;ingual menu's is to simply add menu blocks, and make them visible on the basis of the language of the current page.
But as I am building a website with equivalent structures, I want every menu and item to be translatable.
15. 1
Go to configuration, regional and language, multilingual settings, the variables tab. Then select the Menu settings tab.
15.2 Select the 'Source for the Main links' to be translatable.
15.3 Create an new menu item (say Top menu)
15.4 Set ' Translate and Localize. Menu items with language will allow translations. Menu items without language will be localized. ' under Multilingual options.
15.5 Click the translate tab and change menu name for every language.
15.5 Go to structure, content types and add thin menu to all contentypes that you will possibly link to from this menu.

16. Translatable blocks
It is of course quite handy to be able to create translations of block. Thats working now if you've followed the instructions above.
One thing though is that you are defauylt only allowed to translate plain text. So if youve made a block with filtered html content, and try to translate that, you get an error message.
You have to go to admin/config/regional/i18n/strings and allow translation for filtered html and full html also.



17. User profiles
The problem is that, unless you install entity translation, which has some major flaws in D7 (honestly, the ast time I did a major check on that was about a year ago) de option of adding fields to the account, does not allow for translation of the content.
I tried out Profile2, but that module strangely enough does not support translations. Not even the entity translation of the fields. (Or at least not that I could find a way to accomplish this.....)
SolutionThe solution I came up was to use entity translation just for the users, and use the other translation modules for the rest of the site.
17.1 Install Entity translation
17.2 Navigate to Configuration > Regional and Language >  Entity translation
17.3 Open tab 'Translatable entity types'
17.4 enable user and disable node
(In this case I do not want to use this possibility and it only clutteres my maintenance interface)
17.5 Enable the module Field translations
17.6 Go to Configuration > People > Account settings and open tab manage fields
17.7 Add any fields you like and in each field check the option under 'Field translation': users may translate this field
(The module field translations is something totally different and just supports the translation of the labels, not of the field content itself, which come in handy but is not allied to the translatiom of the field contents)
17.8 On adding fields choose wisely if you also want them on the registration form, and if you want them translatebale....


18. Images
Wel, there's a subject that sometime makes my head spin. An imafe is a file, and for most files in a multisite setup the german file needs to be different form the english file, and the freanch file and the indian file. So, any filefield you setup as an normal field.
On translating the node you reove the otherlanguage file and replace it with an upload in the language you are translating to.
But: Images are different.
18.1 Specifications
Usually you probably ussually want to use the same image on both language versions, but, and there the is problem, you want to be able to translate the alt, title and caption of the image.
On the other hand, somatime the image contains a lot of language (charts, graphs, et cetera) in which case you want to be able to remove the image just like the normal file case, and replace it with another.
So we want the same setup for an image as for a file, so that on translation you can chroose wether you remove the image or not. But, while keeping the same image, you do want to translate the alt and title texts.
(In this example I could not get the media widget in ckeditor to work, so in the end I skipped media as a ckeditor widget and chose for a hybrid solution, using the media widget for the filefields and IMCE for the image uploads in teh RTEditor.)
18.2 MEDIA settings
18.2.1 Go to admin > configuration > regional and anguage > entity translation
18.2.2 Add 'file' to the translatable entity types.
This merely adds the possibility of entity translation to the file type
18.2.3 Go to structure > file types > image > manage fields
18.2.4 Click on edit in tge alt and title row and enable translation under 'Users may translate this field.'
Then, for every image there is a link 'add {language} translation' en de media popup widget
Thats is to say: there should be.
For my install (Media 7.x-2.0-alpha3 and file entity 7.x-2.0-alpha3) the link only appears when your admin interface is in the language of the other (nonn sourec) language.
So, I habe an Eglish site with a second language german. To be able to translate the alt and title values, I need to translate the node, save it, switch to the german interface, edit the node, open the media widget for the image and only then the add translation link is visible....

18.3 IMCE settings
Is specified a few specific folders for the file uploads on certain contenttypes.
I created two subdirectories in the files folder where the file fields mentioned above save their images. Fo IMCE I added a profile that only has access to those folders>
Now placing an image in the wysiwyg editor is ok. Translation of alt and title works the same as the translation of the text.


19. Entity references
Well, there are really some annoying problems with entity reference and a multilanguage site.
19.1  Entity reference autocomplete uses interface language instead of the node's.
What this means is that when you edit a french node in the english admin interface, it will only show english nodes
There is an option to filter the autocomplete function using an "entity reference" view. But there is also only the option of using the 'current usres' language, and that is teh interface language.
So the only way to solve this is to always switch to the interface language of the node you are editing, and then the autocomplete will show the correct nodes in the same language as the nod eyou are editing.
But this is annoying and error prone
19.2 translation workflow
Another thing is you would like a translation workflow where the entity reference field in Node x in language A to referenced node y in  language A, should automatically translate to an reference entity field in node xt (translation of x in language B) to referenced node yt (translation of y in language B).
This is not the case. The referenced entity in node xt in language B is pointing to node y in language
(Adding the Translation redirect more or less solves this problem for unauthenticated user, biy redirecting them to the translated versions of the 'wrong' links, but thats not really a solution.)

The combination of 19.1 and 19.2 make translation of an entity reference field very cumbersome and error prone!
I tried using the entity reference field translatable with entity translation and not translatable with entity translation. The issue remains!houtje-touwtje solution
A solution is to switch your admin interface when translating or editing a node.
It would solve the problem, which I think is Drupal core, but it is a rather quirky solution cause a maintainer would probably have his/hers admininterface language stable.
There used to be such a setting "Switch interface language to fit node language when creating or editing a translation" but that is gone now. For some bad reasons I think.
https://drupal.org/node/1438288
https://drupal.org/node/1551688



Links for this issue

sandbox project dedicated to solving this issue (no solution)
https://drupal.org/sandbox/svendecabooter/1736970
referencing the same problem
https://drupal.org/node/2033053
referencing the same problem
No solution either
http://drupal.stackexchange.com/questions/74355/translated-node-does-not-use-translated-entity-reference-how-to-fix-this



20. Multilingual page views
The path to a page view is alwas the same, and for some solutions it will be better to have a single page view, as opposed to having to add two the same views for a single view. And then again, the opposite language fview will be accessible from the other language to.
Solution is then to install i18n page views
This module a new page view type: The only difference is that you can define different paths for your language versions.
Furthermore the paths connect the page view just like a translation set, so the language swich works just as designed.

21. The trouble with field collections
There is a flaw in the field collection module when it comes to content translation.
Suppose you create a new contenttype and add a  (repeatable) fieldcollections to it.  Create a node and fill alle fields, also some field collections. Then create a translation for this node.

Bug: The fieldcollections in that translations will then have the same entity id as the ones in the node in the original source language. So you end up with two nodes sharing the same field collections field. What then happens on editing the fieldcollection fields  in language x, the corresponding fields in language y then also get edited.
They are the same.
(Enabling entity tranlation on these field collection fields creates other problems which I will not elaborate on at this point.)
This problem does not arise twhen you add new field to both nodes in the translation set, after they have been created. Then these fields are two different entities and unique for either node.
solution
There is a long discussion going on about the patch for the field translation module, but in the meantime there is a solution which works great for my sites. I did not think this one up myself but it is conceived by a guy called Martin. Hook into the translation workflow, and remove the id for the fieldcollection entities when the original node is cloned.

Just build a module, add this code


function MyModule_field_attach_presave($entity_type, $entity) {
    // Clear the item_id on the field collection entity before saving in order to force
    // creation of a new field collection rather than overwriting the original
    if (empty($entity->is_new)) {
        if ($entity_type == 'field_collection_item') {
            if (isset($entity->item_id)) {
                $entity->item_id ='';
                $entity->save(TRUE);
            }
        }
     }

}


X. Search
If you've setup the site as mentioned above, search will default be set so that when you search content, you'll only get the content in the language version you are in now. So that is good. Praise Drupal!





Friday, September 27, 2013

Warning - Dutch fairy tale

Het verhaal van de Kapper van Hamelen

Er was eens een stadje (lang geleden maar niet zo ver weg) waar een verschrikkelijke rattenplaag heerste. Wat de mensen ook deden, niets hielp om de ratten te verjagen. Op het laatst zaten ze 's ochtends brutaal op de nachtkastjes te piepen, ze sliepen bij de mensen in de bedden, en ze vraten alles op.

Op een goede dag kwam er een kapper op bezoek in het stadje. "Wat is er aan de hand?" vroeg hij toen hij de mensen treurig en ongekamd over de straten zag sjokken. "O, het is vreselijk!" zeiden de mensen. "De hele stad zit vol met die stinkende, smerige ratten. En niets helpt!" De kapper fronste zijn wenkbrauwen. "Niets helpt?" "Nee, we hebben alles al geprobeerd!" Daarop meldde de kapper zich bij het stadbestuur en zei daar dat hij, tegen een niet onaanzienlijke vergoeding, dit varkentje wel kon wassen. De burgemeester beloofde hem daarop een kruiwagen vol goud, en de kapper zei dat iedereen die nacht binnen moest blijven met de slaapmuts stijf over het hoofd getrokken.

En zo geschiedde het. De hele nacht was de kapper druk in de weer, en toen de mensen de volgende morgen wakker werden, en verwachtten (hoewel met enige twijfel, ik bedoel maar, wat kan zo'n kapper nou?) dat alle ratten verdwenen zouden zijn, was dit tot hun verbazing toch niet het geval. De ratten waren er nog steeds, overal, op de tafeltjes, de kastjes, in de gordijnen en op de grond. Alleen waren ze nu allen keurig geknipt, hun vacht zag er glanzend en geborsteld uit en ze roken heerlijk naar rozen of viooltjes.

De burgers waren woedend, en de burgermeester weigerde de kapper zijn goud te betalen. "Maar ik heb het probleem opgelost!" Schreeuwde de woedende kapper, die er niets van begreep. En als dank voor zijn harde werk die nacht, werd de kapper het stadje uitgeschopt. Slechts een paar mensen zagen de woede in zijn ogen, en hoorden hem mompelen. "Wacht maar, dit zet ik jullie betaald!" "Is het misschien toch niet eerlijk om hem op zijn minst een deel van het goud te betalen?" vroeg een van hen. Maar de burgermeester schudde zijn hoofd. "Van zo'n kapper hebben wij niets te duchten. Het is een charlatan."

Die avond gingen de mensen sjacherijnig en moe weer naar bed, omringd door duizenden geurende, zijdezachte ratten. (Sommigen moesten hun kinderen zelfs verbieden de knaagdieren te knuffelen en te aaien.) Maar toen ze de volgende morgen wakker werden ontdekten ze wat de kapper had bedoeld met 'dit zet ik jullie betaald'. Al hun kinderen, hun onschuldige kinderen, waren die nacht, zonder uitzondering, prachtig geknipt. De een nog mooier dan de ander.


I met a fish today




I met a fish today.

A fish with no legs, no hair and no voice to speak of.
And this fish wanted to be a bird.
(I know these things; fishes wanting to be birds, cows longing for blood, horses dreaming of hatching)
So I knitted it some wings and taugth it how to fly.

And the fish asked howcome
- the trees
- the why of them branching
- the uses of vertigo
- the absence of teeth
And I told it all these things.

Except for the teeth, cause you never know...

Monday, July 1, 2013

The words without my sister

(About the work of my sister, Jenne Bleijenburg.)

My sister did not speak until she was four. When you look at old family pictures, you see this rather wild girl, mostly smiling, eyes wide open, lots of hair.  Bruises, bleeding lips, that kind of a girl.  But she did not speak. If my parents wanted to know something from her, they asked me or my other sister:
"So, what's with Jenne?"
"She wants a cookie."
When she finally started talking she could utter whole and grammatically correct sentences, so there was no cognitive defect or something. Just no need and no desire for words.
c Jenne Bleijenburg
Would I be turtle?

The language of my sister
We are a talking species, we need to grasp our life in words, in some mystical stuff we call 'meaning'. But my sister, I think, growing up in her speechless universe, gained some extra space in her brain just for images, reserved for just looking at things and people without the necessity to describe or explain it. This 'wordless' mode of looking at - and understanding - the world is what I think makes her work this powerful. 

Game of subscripts
I often play a game with her photographs: I try to think of subscripts that extend the image. The more I can think of, the better the image is.
But every subscript is a bit like raping the image, because the subscripts flatten the image as a meaningful object on its own.

Unwrapping the visible universe
The second important thing to know about my sister is that she would always guess what was in a present before unwrapping it. I do not credit her with telepathic powers or something like that, but she sees trails  in the universe that I don't.


c Jenne Bleijenburg
There 'll be dragons
Jennes elevator pitch
Jenne is looking for the states in the universe where the image escapes the narrative. 
She herself would never formulate it like this. But I think she should.

People and pots
Jenne started as an abstract painter, but switched to photography. In the beginning she made only still lifes, still lifes  like poems. A scarred bowl and a rusty pot, a shiny apple someone forgot to eat. The only thing moving in those pictures is time; time passed by.
Later on she started photographing people.
And I must say, I like the people best. Apples are for eating, bridges for crossing rivers, landscapes to get lost,  but people are for looking at, for relating to.
And with people she does the same as with the apples and the pots; she decides where the image is necessary. Jenne, on pointing her camera on these people, knows she is intruding. It makes her feel uncomfortable.
A person is not a pot. But that is exactly what you see in most of her work; she herself is always part of the image.
c Jenne Bleijenburg
The eye of god

The eye of god
Photography has the pretence of truth. The camera is like the eye of a god, being able to freeze any moment, analyze it, ponder on it, traverse it in all different directions and look at it from all angles and perspectives.
A photograph pretends to be time undressed, shameless and naked to the bone.
But it is not.
There is no truth in the image. Truth only exists in the mind. And the camera never sees what we see, or what the gods see. The camera is just a small machine.

Egbert Bleijenburg, groningen, juli 1 2013

Saturday, February 16, 2013

Access is King


I have a dream; That all man, black and white, yellow and brown, rich and poor, and especially the poor, will be connected to the web. Just as the roads are free for travelling, internet connection should be free. Should be considered to be a basic human right.
The web has become one of the main intellectual infrastructures of humanity. Just like the roads are the basic infrastructure of a country, and are therefore free to be used by anyone in the possession of legs, a bike, a car, so I think  access to the internet should be free for everyone.


1938, none of the events depicted here, 
have had any consequences for world war II
Life as cartoon character
I must admit I lack the knowledge to support this statement based on sound economic arguments. I studied physics and philosophy, and now I have this here webdevelopment-company. I usually barely understand what my accountant tells me. 
But I am convinced that the world will benefit should we decide to support this freedom of access. Akin to the OLPC project, the UN should flood the whole world with basic rechargable, reusable consoles. 
The web will feed an new enlightenment, just like the invention of the printing press fed the enlightment by flooding the market with a tsunami of affordable books.

Hypoxia
There are billions of minds capable of becoming scholars, solving the unsolvable environmental and social problems.
Hiding connectivity from these masses on economic grounds, or on whatever ground, is like a man denying some parts his brains oxygen. (There could be economic sound reasons to do so...)
No one is his right mind would decide to do that. But that is just what we do to the world. 
Let's see the group of all our minds as the brains of the world: A large part is not, or barely, connected to the other part.
The world now behaves like a man with his corpus callossum dissected: Weird, and in hindsight perplexed about its own actions.
All these unconnected people, they are like cures for cancer, aids, malaria etcetera, written on paper and stored in sealed cannisters on the planet Xon234523.
They contribute to world development just as much as any cartoon character in a single comic from 1938.


Reality
A live without connection to the web is a live lost. Acces is King, and purpose and invention are its children. The internet is this great new toy, humanities one-stop-shop library, it's the parallel universe where we store all our knowledge(and porn of course). If all man are created equal, than all man should be given access, and the basic means to access this web. I believe then, and only then, the world will thrive and prosper.

Tuesday, January 22, 2013

The EU Directive 2009/136/EC virus

Warning
All sites in europe are now affected by a brand new virus known by its technical name "EU Directive 2009/136/EC".  Or more commonly known als the "Allow this site to use cookies" popup.

We want to place our cookies.
It's annoying. At least I think it is annoying. All sites ask me the same thing, over and over, in an autistic repetition that reminds of Dr. Christian Szell in Marathon Man. 
Is it save?
Is it save?
Is it save? 



Do you allow our cookies? Do you know our cookies? Do you love our cookies? Do you want our cookies?
They will enrich your experience!

No! It is not save. Yes it is save.

And we are all like little cyber versions of Dustin Hofmann. We don't know if it is save! We haven't got the slightest idea if we want this website to place its cookies! We most of the time don't care. We simply want to browse, browse, browse.....
I don't know about you, but as long as my virusscanners don't warn me for a site, I always click 'Ok' or 'Agree'.

Stupid solution
So there is a law. Ok, we have to deal with that.
A law is a law is a law is a law, as the poem goes. 
And for all purposes and intentions, it is a good law. The web is a dangerous place to be, spammers and vendors trying to analyze our inner thoughts and our deepest intentions, to make us buy their stuff, or for them to steal stuff from us.

But whoever thought up the solution to place the responsibility for compliance by all website owners? Not that that is a unreasonable choice, but what a waste of time!
Now hordes of developers and siteowners have to read the law, understand its implications, and try to design a way to comply. And the method of compliance is not a simple extraction proces, the law does not define specifications for compliance. You build something and hope you comply. Or better, you read a lot of discussions about how others are doing this, do a lot of copy paste, implement this and think you comply. Different solutions for all different implementations.
But all this development time would be time better spent trying to solve global warming, world hunger, read Wittgenstein or watch quiz-programs on tv. (If anyone still does that nowadays)

The good solution: An EU App
This one always agrees.
So, is there a better way to implement this law?
Yes, of course there is.
The EU should provide a browser App, along with the law itself,  that makes it possible for every user to easily see the cookies used on a site, to easily find info about the cookies used, and to easily allow or block these cookies, and remember this for ever and ever.
The App should be included in every new browser version, and in all minor upgrades.
Interface and interaction should be the same for all browsers.
When the EU should have funded development of this App, that would have been community money well spent because the distributed and parallel development of solutions for all specific cases is a waste of creative energy and time.
Time that should have been spent adding value to the web instead of compliance.

EU Directive 2009/136/EC
 

Wednesday, January 16, 2013

Genesis

So, I will start a blog about my company.  

The reasons and objectives of this blog will be explained later.
Honestly:  Because I haven't got the faintest Idea of these objectives at the moment. 

The main motivation is that my work sometimes seems like sitting at the bottom of a very deep pit, working the machinery of a whole and exciting world above me. I work in the engine room of the web, and a simple blog is something on a deck of one of the cruisers.

This is what we do: We build software for the web that most of the time does not work, break down, crash, makes me wanna scream and tear my hair out. And then one of my clients calls me and I am totally confident that it will all work out. Yes, no problem, deadline will be adhered to, problems will be solved, mountains climbed, countries conquered. 
And in the end it always does work out. I solve the puzzle, or we solve the puzzle to be precise.

Spaghetti
I build whole stories made of spaghetti-like modules that all knit together something that works. We xml, soap, php, parse, sql like these are verbs instead of nouns.  Whole days long, behind the little screens, sitting in awkward positions drinking coffee, talking jibberish and using google as a shoulder to cry on. Or as an older and wiser friend, but one who most of the time does not pay enough attention to my specific problems, or the exact context of my specific problems.

Slippery
The web is a slippery environment: There are the different browsers, Operation systems, changing API's, services, dll's, changing scripting versions, preferred protocols et cetera.
Whatever works today may not work tomorrow. It sometimes feels like when you measure the height of a mountain wearing a blue hat, the height will differ from when you measure it wearing a red hat. Or it appears to be no mountain at all, but a valley, or a monkey, or the way an old man can look at girls passing by.....