Новата ни платформа за онлайн магазини – geeneric.com

От известно време разработваме платформа за онлайн магазини базирана на WordPress и WooCommerce.
Може да създадете вашият онлайн магазин безплатно на geeneric.com

Пишете ми какво мислите за платформата – отворен съм към всякакви идеи за подобрения.

JavaScript Събития (Custom Events) без DOM простотиите

Събитията са много добра техника да направите кода си независим между различните модули. С тях може да пишете значително по-добър и по-лесен за поддръжла JS.

Въпреки това има много случаи в които няма нужда обектите в кода да разчитат на DOM дървото за да вдигат събития. (Например когато репрезентацията на самия обект е на няколко места в страницата или такава репрезентация може да липсва дори).

Това беше и причината да напиша супер проста JS библиотека – eventy.js – С нея можеш да направиш всеки обект от кода си такъв, какъвто да вдига събития (events) и да предоставя начин за абониране към тях.

Работи дори за класове, които си си дефинирал и може да се вдигат събития от класа или от инстанция на този клас. (Същото важи и за абонирането).

Пробвай го на https://github.com/ninio/eventy.js

Да спрем да се заблуждаваме с разпознаването на пипащи се (touch) устройства

До всички JS дживелъпъри: Време е да спрем да се самозаблуждаваме. Това, че потребителят има устройство, което поддържа пипане (touch) не значи, че ще го използва само по този начин. Не знаете за какво говоря? Ето:

 var clickEventToUse = ( 'ontouchstart' in window ? 'touchend' : 'click' )

Все още не знаете? Представете си лаптоп с touchscreen (все по-голям брой лаптопи напоследък). Този код принуждава потребителя да използва устройството си само с пипане и прави библиотеката неизползваема за мишка и клавиатура. Сега си представете, че потребителя има втори монитор, който не поддържа touch. Да – за да извършите определено действие трябва да си преместите прозореца на другия екран и да започнете да го пипате. Много извратено! А fix-а може да е нещо супер просто:

function doSomething() {
    // don't look, do something
}
$( 'selector' ).on( 'click', function( e ) {
    doSomething();
}).on( 'touchend', function( e ) {
    e.preventDefault(); // we don't want the click triggered second time, do we?
    doSomething();
});

Време е да оправим положението!

Пускане на асинхронни ajax рекуести към масив от url-и и обработването им наведнъж

Днес имах много интересен случай, в който трябваше да вземем няколко SVG файлове с ajax и после да ги обработим наведнъж когато всички рекуести са готови.

Знам за $.when но съм го използвал само когато броя на рекуестите са фиксиран брой.

Нещо като това тук:

$.when( $.ajax( 'first.svg' ), $.ajax( 'second.svg' ) ).done( function( ajax1, ajax2 ) {
    // do stuff with both things.. as ajax1[0] is the svg document
    // for the first.svg and ajax2[0] is the svg document for the 
    // second.svg
});

Ясно е, че ще ползваме нещо сходно и за това слагаме всеки от ajax извикванията в масив, че да можем да ги добавяме динамично.

// svgUrlArray is an existing array with all the urls of the svgs

// we create a new array with all the ajax calls
var svgAjaxArray = [];

for( var svgIndex = 0; svgIndex < svgUrlArray.length; svgIndex++ ) {
    svgAjaxArray.push( $.ajax( svgUrlArray[ svgIndex ] ) );
}

След това подаваме масива на $.when

$.when( svgAjaxArray ).done( function() {
    // this is executed a bit too early 
});

И хендлъра на done събитието е извикан прекалено рано. Защо?

Защото Array не е Deffered обект – той е просто масив и стойността му е готова за използване веднага (точно като Deffered обект, който се resolve-а веднага при създаването си). И за това done callback-а се извиква веднага.

И какво ни е най-лесното решение тогава?

$.when.apply( $, svgAjaxArray ).done( function() {
    // Now we're talking ;)
    // You must use the arguments variable to get all the entries
    // because you don't know what is the length of the ajaxArray
});

Вече може да обработваме произволен брой от асинхронни заявки и да ги обработваме след като всички са приключили. Array!

Async Call Stack в Chrome Canary

Ако използвате Chrome Canary за разработка, вече може да използвате async радио бутон в полето с Call Stack-а, който ви показва състоянието на стека ви при breakpoint,

devtools-async

Ако го пуснете в Call Stack-а на функциите които са в резултат на асинхронно действиие имате пълния списък на тези които са ги извикали.

Якотата тук е, че няма нужда да слагате нови брейкпоинтове преди рекуеста (или друго асинхронно нещо) да се случи за да проверите дали всичко е наред. Заедно с този Call Stack имате и видимост за това какви са били стойностите на променливите преди и след асинхронното действие.

Преди няколко месеца спрях да ползвам Chrome Canary за разработка, основно поради бавнотата му и забиването на моменти, но изглежда като да заслужава пореден шанс (започвайки от днес 🙂 ).

П.С.: Ако и вие ще го пробвате, не забравяйте че за стабилни задачи и тнт Chrome Canary е на Nightly Build принцип и често е нестабилен.

WooCommerce BGN Plugin

За леснота написах кода от публикацията „Добавяне на нова валута в WooCommerce“  в плъгин за BGN.

Може да свалите WooCommerce BGN плъгина тук

Инсталиране:

  1. Свалете zip-а
  2. Качете го
  3. Активирайте плъгина.
  4. Отворете настройките и в списъка с валути най-отдолу трябва да видите Bulgarian Lev.

Успешно продаване!

Изисквания – WooCommerce 😉

ЧЗВ:

1. Инсталирах плъгина, но цените продължават да са ми в (нещо различно от лев)

Да. Плъгинът добавя опцията да избереш BGN в WooCommerce. За теб остава да избереш тази опция в настройките на WooCommerce и да позиционираш правилно символа на валутата „лв.“

2. Цените излизат в обърната последователност: „лв.12“

Отвори настройките на WooCommerce и в табът Каталог (Catalog) има секция Pricing Options. Там dropdown с Currency Position. За BGN най-подходящо е да е отдясно с интервал (но може да си избереш каквото ти душа иска и на където сърце дърпа)

 

Случайни наблюдения над новогодишните цели

Както много народ на тая планета и аз си поставям новогодишни цели. За съжаление успеваемостта ми на тези цели странно-статистически се върти около 30%, колкото гледам е и на Влади рейта, съдейки по неговата публикация.

Тази година реших да променя начина и периода на поставяне на новогодишните цели по 2 причини:

1. Извод до който достигнах тази година е, че не е напълно лошо, че има неща от новогодишните си желания и обещания които не си изпълнил. В моя списък част от целите са станали я безсмислени, я вече са от нищожно значение за мен поради други фактори. И това май е нормално, все пак са вече на цяла 1 година.

2. Тези които продължават да са смислени, но непостигнати (и съответно единственото логично нещо е просто да ги преместиш в новия списък) са неща които изискват доста воля, борбЪ и не винаги резултатите са лесно видими. Точно тези неща най-лесно се изоставят когато те грабне водовъртежа.

Тези ми 2 (две) наблюдения ме подтикват към следните промени:

1. Промяна в поставянето на самите цели:

  • Първо поставям генерални цели или каквито там първи ми дойдат на акъла (като да съм щастлив, успешен…)
  • Пиша си какво за мен е да си / да се чувстваш такъв и как си го представям
  • Тук-таме се питам защо да видя дали няма някоя скрита причина да искам нещо
  • Вече си имам цели и конкретни причини защо искам да ги постигна.

2. План (план за целите винаги имам, но е тотално несъобразен с останалия живот)

  • Тегавите цели искат план както „Козътъ си сака пръч“
  • Планът е съобразен с текущия график
  • и е реалистичен

3. Ревизия (хъхъ) всеки месец.

  • За да ми държат влажно ще си преглеждам целите всеки месец
  • Саморазрешил съм си да добавям и махам цели
  • Планът се прави наново всеки месец

Това ще ми е схемата тая година.. да видим какво ще излезе 🙂

Как да улесним кодърския ни живот със Sublime Text 2

Днес (на 21. Март 2013) в init Lab ще проведем workshop за това как да улесним живота си използвайки хитрините които ни предоставя Sublime Text 2.

Ето ги и слайдовете за презентацията:

 

 

Update на WooCommerce до версия 2 и липсваща информация за продукт в front-end-а

WooThemes пуснаха новият WooCommerce 2.0 наскоро и ъпдейтването изглеждаше доста съблазнително с новия интерфейс и другите красоти в него.

Все пак ъпдейтването не е най-доброто нещо което може да се направи особено ако темата ти е направена за 1.6

Като резултат – след ъпдейта информация като цена и подобни липсваше на началната страница на сайта по някаква причина. Разбира се в администрацията всичко изглеждаше окей и очебийният извод е, че начинът по който е направена темата (дело на самите WooThemes) не работи с новата версия. Също така проверих, но все още нямаше ъпдейт за тази тема.

Хората които са писали тема за по-старата версия най-вероятно са използвали класът WC_Product за да вземат данните за определен продукт. Проблемът тук е, че вече не може да създадете такава инстанция по postID. Най-вероятно това е свързано с новосъздадената функция get_product(), която е слабо документирана в официалната документация и никъде не се упоменава, че заменя конструктора на WC_Product класа.

В моя случай в темата направена от WooThemes имах следния код:

//inside the loop
$_product = &new WC_Product( $loop->post->ID );

Това явно не работеше и за това го смених с новата функция get_product()

$_product = get_product(  $loop->post->ID );

Това е.

Според мен би било добре ако те си ъпдейтваха поне собствените wp теми за да поддържат новата версия.

Дати, време и iOS Safari

Safari на iOS е един от най-добрите мобилни браузъри. Въпреки това има едно нещо в него, което често ме кара да се чудя защо web-app-а ми не работи – JS Date обектът.

Във всеки нормален браузър можеш да създадеш Date обект от низ просто така:

var myDate = new Date('2013-01-21T13:46:20');

Но в Safari (iOS) това просто дава JS грешка.

За да го оправите трябва да използвате добрия стар split() и да направите нещо като това:

//First we split the date string
var iosDateArr = '2013-01-21T13:46:20'.split('[- :T]');
//And use the constructor with 6 args
cDate = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]);

Забележете че месеца е намален с 1. Това е защото в този конструктор месеците започват от 0 за Януари и са до 11 за Декември.

Успех с JS програмирВането и по-малко подобни проблеми 🙂