Сделать виджет вордпресс. Создание Widget - делаем виджет на Android устройство. Пишем код. Создаем базовую страницу

В современной матрице IT-технологий квалифицированный администратор - персона хоть и не всегда видимая, зато важная и весьма занятая. Отбиваясь от назойливых пользователей, он постоянно должен присматривать за ареалом своего цифрового мира - сайтами. Давай же поможем нашему админу и создадим полезный виджет, внимательно следящий за доступностью всех его ресурсов. И да, погоду этот виджет показывать не будет.

Проектируем виджет

Цель нашего проекта - создать виджет, который периодически пингует указанные пользователем сайты и выводит соответствующую информацию на домашний экран. Традиционно будем использовать редактор кода Eclipse с плагином ADT .

В андроиде любой виджет представляет собой визуальный компонент, работающий в рамках того приложения, в которое он встраивается (как правило, это домашний экран). Кроме того, виджет умеет выводить устройство из режима ожидания, чтобы отобразить на экране актуальную информацию. Поэтому при разработке виджета нужно свести к минимуму время его обновления (можно, конечно, и пренебречь, но ANR в виджете - это уже моветон). Вполне логично напрашивается некоторый фоновый сервис, который будет пинговать сайты и записывать результат для дальнейшего анализа. Таким образом, задача виджета сведется к извлечению этих данных и выводу информации в виде текстовой строки - ссылки на сайт и некоторой графики - доступности сайта (рис. 1). Также нам потребуется простенькая форма для ввода списка подконтрольных сайтов, то есть GUI. Кстати, настоятельно рекомендую ознакомиться со статьей в мартовском номере «Хакера» «Хакерский Cron на Android», поскольку там подробно рассмотрена работа фонового сервиса.

Ping? Нет, не знаю...

В Java есть замечательный класс InetAddress , имеющий в своем чреве не менее замечательный метод isReachable() . Этот метод проверяет доступность ресурса и принимает в качестве параметра тайм-аут, то есть время, по истечении которого не отвечающий ресурс считается недоступным:

If (InetAddress.getByName("www.сайт").isReachable(5000))... // Сайт доступен

Лаконично, не правда ли? Вся проблема в том, что этот код прекрасно работает в Windows, но в Android’е всегда возвращает false, даже если приложению дать разрешение на доступ в интернет. По непонятной причине для отправки ICMP-пакета (Echo-Request) требуется рут.

Мы же ничего требовать не будем и поступим следующим образом: будем подключаться к сайту по протоколу HTTP и смотреть на код ответа. Если получим код 200 (HTTP OK), значит, сайт жив и работает, в противном случае считаем, что что-то не так (сайт недоступен).

Разрешения

Так как наша цель - сайты в интернете, необходимо получить соответствующие разрешения у пользователя в манифесте проекта (AndroidManifest.xml):

Первая строка запрашивает разрешение на доступ в интернет, тогда как вторая позволяет отслеживать состояние подключения к сети (в терминологии Play Market - «просмотр состояния сети») - если сеть недоступна, пинговать что-либо особого смысла нет. Функция проверки подключения к сети выглядит следующим образом:

Public boolean isConnected() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo ni = cm.getActiveNetworkInfo(); if (ni != null && ni.isConnected()) { return true; } return false; }

Для доступа к сервису управления сетевыми подключениями используется константа Context.CONNECTIVITY_SERVICE, после чего метод getActiveNetworkInfo возвращает объект типа NetworkInfo, который содержит информацию о текущем соединении. Если подключение установлено, метод isConnected вернет true.

SQLite? No... Shared Preferences!

Как ты сам понимаешь, нам необходимо где-то хранить список сайтов и их (не)доступность. Сначала я хотел вновь использовать базу данных SQLite, но решил не повторяться и рассказать о другой полезной технологии Android - общих настройках (Shared Preferences ). Общие настройки - довольно простой механизм, основанный на парах «ключ - значение» и предназначенный для сохранения примитивных данных приложения (число, строка, булево значение). С точки зрения Android настройки хранятся в виде обычного XML-файла внутри приватной директории приложения (data/data/имя_пакета/shared_pref/).

Для наших целей напишем небольшой класс (PingPref) для сохранения и чтения данных:

Public class PingPref { private static final String PREF = "pref"; private static final String pre_ = "site"; private static final String _url = "_url"; private static final String _status = "_status"; private SharedPreferences mSettings; PingPref(Context context) { mSettings = context.getSharedPreferences(PREF, Context.MODE_PRIVATE); } public void setData(int num, String url, int status){ Editor editor = mSettings.edit(); // Формируем строку вида siteN, где N - порядковый номер сайта String key = pre_ + String.valueOf(num); editor.putString(key + _url, url); // Ключ siteN_url editor.putInt(key + _status, status); // Ключ siteN_status editor.commit(); } public String getData(int num) { String key = pre_ + String.valueOf(num); String url = mSettings.getString(key + _url, ""); int status = mSettings.getInt(key + _status, -1); return new String {url, String.valueOf(status)}; } }

В конструкторе класса нужно вызвать метод getSharedPreferences в контексте приложения, указав имя файла общих настроек и режим доступа. Константа Context.MODE_PRIVATE указывает на то, что файл настроек будет доступен только внутри приложения (Google настоятельно рекомендует использовать только это значение). Каждый сайт будем хранить в двух ключах: siteN_url (ссылка) и siteN_status (доступность). В качестве последней используем число: 1 - сайт жив, 0 - сайт ушел (читай: «его ушли»), –1 - статус не определен (например, в случае отсутствия доступа к сети). Сеттеры (put.String, put.Int) и геттеры со значениями по умолчанию (get.String, get.Int) в пояснениях не нуждаются. Содержимое файла pref.xml в работе представлено на рис. 2.


GUI

Здесь все просто - несколько полей ввода (EditText) да кнопка (Button). Вся эта красота представлена на рис. 3. Обработчик кнопки (см. Main.java) считывает содержимое полей (применяется коллекция ArrayList) и записывает их в файл общих настроек, используя метод setData описанного выше класса PingPref:

ArrayList sites = new ArrayList(4); pf = new PingPref(this); ... public void bPing_click(View v){ fillSites(); for (int i = 0; i < sites.size(); i++) pf.setData(i+1, sites.get(i), -1); startservice(); } public void fillSites(){ sites.clear(); sites.add(ed1.getText().toString()); ... } public void startservice(){ Intent i = new Intent(this, PingService.class); this.startService(i); }

В качестве первоначального статуса доступности сайта, как и условились, устанавливаем –1. В заключение происходит запуск фонового сервиса startService, подробнее о котором поговорим далее.


Фоновый сервис

Начиная с Android 3.0 (версия API 11), любой функционал, связанный с сетевой активностью, должен обязательно выполняться во вторичном потоке. Любая попытка подобной работы в главном (графическом) потоке приложения приведет к выбросу исключения NetworkOnMainThreadException и немедленному завершению программы. Это правило относится и к фоновому сервису, так как он тоже фактически выполняется в главном потоке. Как ты уже, наверное, догадался (а если нет - срочно покупай мартовский «Хакер»), мы будем использовать IntentService. Данный фоновый сервис берет на себя всю работу по созданию вторичного потока, позволяя нам сосредоточиться непосредственно на функционале.

Для начала зарегистрируем сервис в манифесте:

Основная работа сервиса кипит и бурлит внутри onHandleIntent, текст которого приведен ниже (отладочная печать присутствует):

Private ArrayList sites = new ArrayList(4); private PingPref pf = new PingPref(this); private AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); ... @Override protected void onHandleIntent(Intent intent) { Log.d(TAG_LOG, "Сеанс PingService работает..."); loadSites(); // Чтение списка сайтов boolean isConnected = isConnected(); // Есть соединение? if (!isConnected) { setSitesFail(); // Ставим для всех сайтов флаг -1 Log.d(TAG_LOG, "Соединение отсутствует!"); } else for (int i = 0; i < sites.size(); i++){ String site = sites.get(i); if (!site.equalsIgnoreCase("")) { // Сайт доступен? Да - flag=1, иначе flag=0 int flag = isSiteAvail(site)? 1: 0; pf.setData(i+1, site, flag); Log.d(Main.TAG_LOG, site + ": flag=" + flag); } } refreshWidget(); // Обновляем виджет // Создаем отложенное намерение Intent si = new Intent(this, PingService.class); PendingIntent pi = PendingIntent.getService(this, 0, si, PendingIntent.FLAG_UPDATE_CURRENT); am.cancel(pi); // Сбрасываем предыдущую сигнализацию // Связь есть? Да - повтор пинга через 15 мин, иначе - проверка связи через 30 мин long updateFreq = isConnected ? AlarmManager.INTERVAL_FIFTEEN_MINUTES: AlarmManager.INTERVAL_HALF_HOUR; // Определяем время следующего запуска сервиса = текущее + интервал long timeToRefresh = SystemClock.elapsedRealtime() + updateFreq; // Устанавливаем сигнализацию am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, timeToRefresh, updateFreq, pi); Log.d(Main.TAG_LOG, "Следующий сеанс примерно через " + updateFreq/60/1000 + " мин."); Log.d(Main.TAG_LOG, "Сеанс PingService завершен"); }

Функция loadSites заполняет коллекцию ArrayList адресами сайтов, сохраненных ранее в общих настройках. Далее происходит проверка на соединение с сетью: если isConnected возвращает false - для всех сайтов устанавливаем флаг -1 (setSitesFail), в противном случае запускаем цикл опроса всех ресурсов (isSiteAvail) с записью результатов (setData). Для активной работы со всемирной паутиной по протоколу HTTP в Java предусмотрен специальный класс HttpURLConnection, использующий объект-ссылку (URL) для указания адреса сайта:

Private boolean isSiteAvail(String site){ try { URL url = new URL(site); HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); urlc.setRequestProperty("Connection", "close"); urlc.setConnectTimeout(5000); urlc.connect(); int Code = urlc.getResponseCode(); if (Code == HttpURLConnection.HTTP_OK) return true; } catch (MalformedURLException e) {} catch (IOException e) {} return false; }

Так как мы не собираемся в дальнейшем запрашивать каких-либо ресурсов с сайта, в заголовке запроса смело указываем лексему соединения setRequestProperty("Connection", "close"), то есть после ответа сервер разорвет связь. Метод setConnectTimeout устанавливает тайм-аут соединения и подбирается экспериментально (в моем случае пять секунд при соединении 3G вполне хватило). Возвращаемое методом getResponseCode значение HttpURLConnection.HTTP_OK определяет положительный вердикт функции. Имей в виду: при использовании мобильного доступа к интернету шанс словить IOException и MalformedURLException весьма высок. Это происходит потому, что метод isConnected объекта NetworkInfo не всегда оперативно реагирует на изменение состояния сети, и мы можем прийти в isSiteAvail с отсутствующим соединением. Так что, если внезапно все сайты окажутся недоступными, паниковать, конечно, следует, но не сразу.

INFO

Объект HttpURLConnection обрабатывает только те ссылки, которые начинаются с http://, то есть протокол нужно указывать явным образом.

Функция refreshWidget инициирует обновление виджета посредством трансляции (передачи) уникального широковещательного намерения FORCE_WIDGET_UPDATE, которое наш виджет будет отлавливать, так как он является широковещательным приемником. Термин «широковещательность» означает глобальный характер обработки намерений - любое другое приложение может обработать наше намерение, равно как и мы можем подписаться на обработку чужого. Чтобы не было путаницы, намерения должны быть уникальными. Кстати, если например, нужно открыть интернет-ссылку (одно намерение), а в системе установлено несколько браузеров (несколько широковещательных приемников) - появится окно с выбором предпочитаемого. В следующем разделе мы рассмотрим этот механизм более подробно.

Private void refreshWidget() { Intent i = new Intent(PingWidget.FORCE_WIDGET_UPDATE); sendBroadcast(i); }

Ближе к концу создаем уже знакомое тебе отложенное намерение на повторный запуск сервиса через не менее знакомый менеджер сигнализаций. Только вместо метода set будем использовать setRepeating, а точнее - setInexactRepeating. Последний помогает в некоторой степени уменьшить энергозатраты, собирая для выполнения близкие по времени сигнализации. Поэтому вместо точного интервала мы передаем константу AlarmManager.INTERVALFIFTEEN_MINUTES для опроса сайтов примерно через каждые 15 мин и AlarmManager.INTERVAL_HALF_HOUR (~30 мин) в случае отсутствия соединения для новой попытки. Возможно, ты захочешь указать другие константы объекта AlarmManager: INTERVAL_HOUR (час), INTERVAL_HALF_DAY (12 ч), INTERVAL_DAY (раз в сутки). Замечу, что эти интервалы очень_ условные, и при необходимости соблюдения более точного расписания следует использовать метод setRepeating, но, как уже отмечалось, он более прожорлив. К слову, будить устройство мы не станем - используем AlarmManager.ELAPSED_REALTIME, так как обновление информации для виджета при выключенном экране не только не требуется, но и, вероятно, вызовет укоризненный взгляд коллег из рубрики X-Mobile.

Добравшись до середины статьи, мы провели всю подготовительную работу и теперь можем с чистой совестью приступить к главной теме нашего изыскания - созданию виджета.

Виджет

В Android виджет реализуется в виде широковещательного приемника, реагирующего на некоторые события (строго говоря - намерения(Intent)), для наполнения визуальной разметки актуальными данными по таймеру, с помощью сервиса, по клику и так далее. Разработка виджета начинается с регистрации его класса (PingWidget) в манифесте проекта:

Здесь тег intent-filter содержит минимум одно стандартное действие - android.appwidget.action.APPWIDGET_UPDATE, используемое для обновления содержимого виджета (еще есть DELETED, ENABLED и DISABLED, но они необязательны). Так как обновлять виджет мы будем, во-первых, самостоятельно, во-вторых, в разные моменты времени, добавим еще одно действие - com.example.pinger.FORCE_WIDGET_UPDATE для нашей задачи. Кроме того, нам потребуется отдельный XML-файл, описывающий настройки виджета (файл res\xml\widget_provider.xml):

Атрибуты minHeight и minWidth определяют минимально допустимые высоту и ширину виджета. Для расчета этих значений применяется формула

Min = 70 dp * (количество ячеек) – 30 dp.

Домашний экран в Android разделен виртуальной сеткой, состоящей из ячеек, размеры которых зависят от физических размеров устройства. Можно сказать, что ярлык приложения на домашнем экране соответствует одной ячейке. Наш виджет будет иметь размеры 4 х 2 или 250 dp x 110 dp (в аппаратно-независимых пикселях). Изменение размеров виджета пользователем мы не планируем, поэтому resizeMode устанавливаем в none.

Атрибут updatePeriodMillis задает минимальный период между обновлениями виджета (в миллисекундах) системой, но нам сейчас он неинтересен, так как виджет мы будем обновлять вручную, как только возникнет такая необходимость. Представь, наш фоновый сервис не запущен, а на рабочем экране висит виджет (типичное состояние устройства после перезагрузки) - Android вызовет процедуру его обновления незамедлительно, а уже потом через updatePeriodMillis миллисекунд. При первом обновлении просто запустим наш сервис, и как только он начнет работать, дальнейшее обновление информации в виджете будет инициировать именно он. Поэтому сейчас смело ставим 86 400 000 (то есть раз в сутки) и двигаемся дальше.

Если ты хочешь, чтобы в меню виджетов вместо иконки приложения красовалась симпатичная картинка (см. рис. 4), добавь ссылку на соответствующий ресурс в формате PNG в атрибуте previewImage. О том, как быстро и просто получить такое превью, читай врезку.

Атрибут initialLayout позволяет указать разметку виджета в формате XML. Да, ты не ошибся, разметка виджета во многом напоминает разметку активности или диалогового окна - те же метки, кнопки, картинки, менеджеры компоновки и прочее. Фрагмент разметки нашего виджета представлен ниже (widget.xml):

... />

Наш виджет состоит из небольших картинок (im1, im2, im3, im4) типа ImageView и текстовых меток (txt1, txt2, txt3, txt4) типа TextView. Для компоновки используем RelativeLayout, то есть все компоненты визуально выровнены друг относительно друга. Разумеется, картинки и надписи мы будем менять при отрисовке виджета. Поле alpha задает непрозрачность виджета в диапазоне от 0 (прозрачный) до 1 (непрозрачный), а вот background позволяет задать картинку для фона с эффектами стекла, бликами и тенями (да, я сторонник скевоморфизма). Для генерации такой текстуры можно воспользоваться онлайн-редакторами, которых в интернете очень много (см. полезные ссылки). Кстати, для правильного масштабирования виджета на разных экранах фон желательно перевести в формат NinePatch, о котором расскажет врезка.

Итак, от визуальной стороны виджета (см. рис. 5) плавно переходим к логике его работы (класс PingWidget.java):

Public class PingWidget extends AppWidgetProvider{ public static String FORCE_WIDGET_UPDATE = "com.example.pinger.FORCE_WIDGET_UPDATE"; @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetIds) { startService(context); } @Override public void onReceive(Context context, Intent intent){ super.onReceive(context, intent); if (FORCE_WIDGET_UPDATE.equals(intent.getAction())) updateWidget(context); } private void updateWidget(Context context) { AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); ComponentName thisWidget = new ComponentName(context, PingWidget.class); int appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget); drawWidget(context, appWidgetManager, appWidgetIds); } ... }

NinePatch vs PNG

Изображения формата NinePatch (или растягивающиеся) - это файлы формата PNG, в которых области, предназначенные для масштабирования, помечены явным образом. Android SDK включает в себя визуальный редактор draw9patch , который находится по адресу SDK/Tools/draw9patch.bat.

На рис. 7 ты можешь видеть область растягивания нашего виджета (Patches), помеченную фиолетовым цветом. Какой бы размер виджета ни был, логотип твоего любимого журнала, а также закругленные уголки искажаться не будут. Эта область задается с помощью линеек слева и сверху от изображения. Обрати внимание на рамку толщиной в один пиксель с черными полосами - именно эта информация будет добавлена к исходному изображению.

На рис. 8 темным цветом показана область для контента (Content). Здесь мы видим, что все наши картинки и текстовые метки будут иметь небольшой отступ от рамки виджета. Эту красоту определяют линейки справа и снизу от изображения.

Результат работы сохраняется в формате PNG c добавлением цифры 9 перед расширением файла (например, widget.9.png). При указании ссылки на графический ресурс указывать девятку не нужно (то есть android:background="@drawable/widget").

Класс AppWidgetProvider, являющийся широковещательным приемником, предоставляет нам удобные обработчики жизненного цикла виджета: onUpdate и onReceive (есть и другие - onDeleted, onDisabled, onEnabled, но мы их не рассматриваем). Первый вызывается при обновлении интерфейса виджета с периодичностью updatePeriodMillis (см. выше), как и договорились - просто запускаем сервис (как вариант, можно использовать уже полученные, но, возможно, неактуальные данные - все зависит от задачи). Второй, onReceive, срабатывает при получении определенного действия - FORCE_WIDGET_UPDATE, зарегистрированного нами ранее в манифесте проекта. Именно этот код и отвечает за манипуляции с картинками и текстовыми полями в UI виджета. Функция updateWidget сначала запрашивает объект класса AppWidgetManager, который применяется для обновления виджетов и предоставляет информацию о них. В частности, нас интересуют идентификаторы всех виджетов (массив appWidgetIds), ведь их может быть несколько и обновить нужно каждый из них:

Private void drawWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetIds) { final int N = appWidgetIds.length; for (int i = 0; i < N; i++) { int appWidgetId = appWidgetIds[i]; RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget); // Обновляем первую строку String data = pf.getData(1); views.setTextViewText(R.id.txt1, data); views.setImageViewResource(R.id.im1, getPicture(data)); ... appWidgetManager.updateAppWidget(appWidgetId, views); } } private int getPicture(String type) { switch (type) { case "1": return R.drawable.green; case "0": return R.drawable.red; default: return R.drawable.gray; } }

В единственном цикле функции drawWidget происходит итерация по всем работающим в данный момент виджетам. Класс RemoteViews используется в качестве компонента для доступа к разметке, размещенной внутри процесса другого приложения (мне одному это напоминает Inject?). Если бы мы работали с активностью или фрагментом, то могли бы использовать вполне обычное findViewById. Но наш виджет работает в рамках домашнего экрана, поэтому для получения доступа к разметке необходимо в конструкторе RemoteViews указать название пакета (context.getPackageName()) и ресурс с разметкой (R.layout.widget). Используя views.setTextViewText и views.setImageViewResource, изменяем надпись и картинку (вспомогательная функция getPicture возвращает ссылку на подходящий ресурс). Как только мы внесли правки по всем строкам, фиксируем их в виджете, вызывая updateAppWidget.

Вместо заключения

Мы проделали большую работу, и наш виджет работает как часы - админ наверняка будет доволен. Но вот один вопрос так и остался не заданным: как остановить периодические запуски сервиса, если он больше не нужен? Спешу тебя обрадовать, в коде приложения (загляни на dvd.сайт или мой сайт) остановка уже реализована с помощью специального флага setStopServiceFlag, срабатывающего в момент нажатия кнопки «Назад» в главной активности приложения (на кнопку «Домой» не распространяется). Обязательно изучи этот вопрос - это и будет твоим домашним заданием.

Превью для виджета

В Play Market живет мегаполезное приложение для разработчиков виджетов - Widget Preview, которое позволяет встроить в себя любой зарегистрированный в системе виджет, после чего делает его снимок. Результат можно сохранить в файл или отправить по почте.

Виджет представляет собой небольшое приложение, которое может быть установлено на веб-странице. Эта статья-рецензия содержит инструкции, которые помогут вам добавить такое приложение на своем сайте.

Виджет , также называющейся веб-гаджетом, фрагментом, портлетом и т.д., является элементом графического интерфейса пользователя, который предоставляет информацию и позволяет пользователю взаимодействовать с приложением. Например, он может быть использован, чтобы позволить пользователям проигрывать интерактивные игры, а также добавлять и изменять содержимое веб-сайта. Встраивание этих замкнутых кодов на веб-странице, блоге или сайте социальной сети может сделать их более интерактивными, так как личный контент может быть превращен в веб-приложения, которые могут использоваться на любом сайте – не без пользы для Вас и посетителей.

Откуда берутся виджеты для сайтов

Если вы хотите поставить веб-гаджет на свой веб-сайт, блог или на свой профиль на любом социальном медиа сайте, вы сначала должны найти такие приложения. Есть некоторые сайты, которые позволяют пользователям создавать такие приложения основываясь на собственной базе данных. Вы можете просто вставить код и поместить его на своем сайте. Вы можете найти их в каталогах виджетов, таких как 101widgets.com (http://101widgets.com/) или Babywonder.ru (http://widgets.babywonder.ru/) или создать их с помощью Widget editor (специального Интернет сервиса для самостоятельного создания виджетов с индивидуальным подходом).

Как сделать виджет

Помимо готовых виджетов существуют сервисы, реализующие ваш творческий потенциал, предоставляя возможность создать виджет самостоятельно. Например, Вы с лёгкостью сделаете блок слайд-шоу с выбранными картинками или практичный вывод любого ресурса. Как раз, о втором случае и пойдёт речь ниже…


Прежде всего, следует поискать сайты, которые позволяют пользователям сделать веб-гаджет. Посидите в интернете и перейдите к любому из этих сайтов. На странице веб сервиса найдите кнопку «Создать» или «Сделать» (возможно, что Интернет сервис будет англоязычным, поэтому ориентируйтесь по визуальному отображению элементов). Вы должны нажать на эту кнопку. Теперь следующий шаг, следуя подсказкам мастера настройки, который затребует ввести в поле URL RSS потока (адрес RSSленты веб сайта) вставьте заранее скопированный адрес ленты (например, для блогов на WordPress, он выглядит так « »). После этого нажмите на кнопку «Продолжить». Для выбора цвета фона, вы можете использовать селектор цвета. После того, как выбор цвета будет сделан, Вы можете назвать веб гаджет, введя имя в текстовом поле и совместить его. Затем нажмите на «Сохранить виджет», чтобы получить

Знаете ли вы, что вы можете создать виджеты для WordPress своими руками? Несмотря на то, что существует множество других виджетов, которые идут вместе с разными темами и плагинами, WordPress предоставляет возможность создать виджет вручную для всех своих пользователей. В этом вы узнаете, как создать виджеты для WordPress и добавить их на ваш сайт. Если вас это заинтересовало, то мы можем вас обрадовать – единственными ингредиентами, которые вам понадобятся, являются лишь базовые знания о WordPress и PHP. Итак, без лишних слов, давайте приступать.

Перед тем, как вы начнете это руководство, вам понадобится следующее:

  • Доступ к панели управления WordPress
  • Любой текстовый редактор

Немного о WordPress виджетах

Виджеты WordPress предназначены для более легкого процесса добавления различных блоков на ваш сайт с помощью интерфейса перетаскивания. WordPress уже имеет стандартные встроенные виджеты. Эти виджеты дают вам некоторые базовые инструменты и совместимы с любой темой WordPress. Но иногда, вам может потребоваться добавить новые возможности и блоки для сайта. В таком случае, лучшим решением станет поиск нужного плагина, который имеет нужный вам функционал. Хотя вы и можете найти плагины для большинства стандартных задач, иногда трудно найти нужный, который удовлетворит ваши потребности. Это именно тот случай, когда вам может понадобиться создать виджеты для WordPress самому. Эта возможность дает пользователю полный контроль над своим сайтом и его функционалом.

Перед началом руководства

Перед тем, как создать виджеты для WordPress, вам необходимо подумать о нескольких вещах. Первое, вы можете создать виджет в качестве пользовательского плагина. Это позволит использовать его на любом сайте, который использует этот плагин. Или, вы можете просто добавить виджет в файл functions.php или определенную тему, что сделает его совместимым лишь для этой темы. Второе, у вас есть возможность добавить виджет на запущенный и работающий сайт или в локальную среду. В соответствии с рекомендациями по разработке, мы советуем для начала добавить плагин в локальную среду (ознакомьтесь с нашим руководством о ). После того, как вы убедитесь в отсутствии ошибок и его правильной работе, вы сможете легко портировать его на ваш сайт .

Как работают пользовательские виджеты WordPress: Widgets API

WordPress позволяет вам создавать свои виджеты, предоставляя вам доступ к Widgets API . Чтобы создать пользовательский виджет, вы должны использовать стандартные классы WP_Widget из API. Эти базовые классы предлагают более 20 функций, которые вы можете свободно использовать и комбинировать. Из всех этих функций, 4 являются минимальным требованием для работы любого виджета. Вот список этих функций:

  • __construct() – функция конструктора
  • widget() – содержит вывод виджета
  • form() – определяет настройки виджета в панели управления WordPress
  • update() – обновляет настройки виджета

Конечно, существует и множество других методов, которые предоставляют дополнительный функционал. Чтобы узнать больше о классах WP_Widget , посетите данную страницу .

Как создать виджеты для WordPress

Теперь, когда мы составили концепт нашей задачи, давайте приступим к ее реализации. Для этого урока мы создадим простой пользовательский виджет Привет мир, чтобы вы могли узнать об азах создания виджета в WordPress. Конечно, вы можете перейти к созданию более сложных виджетов по своему усмотрению.

Еще один нюанс, мы пишет этот код в файле functions.php текущей темы, но вы можете делать это в любом пользовательском плагине.

Теперь откройте любой текстовый редактор на вашем компьютере и создайте новый класс, который расширит базовый класс WP_Widget , вот так:

Class hstngr_widget extends WP_Widget { //Вставляйте функции сюда }

Теперь мы начнем добавление 4 ранее упомянутых функций, одну за другой. Первой в списке идет метод конструктора, которую мы используем для указания ID, названия виджета и описания:

Function __construct() { parent::__construct(// widget ID "hstngr_widget", // widget name __("Тестовый Виджет Hostinger", " hstngr_widget_domain"), // widget description array("description" => __("Как создать виджеты для WordPress", "hstngr_widget_domain"),)); }

Public function widget($args, $instance) { $title = apply_filters("widget_title", $instance["title"]); echo $args["before_widget"]; //if title is present if (! empty($title)) echo $args["before_title"] . $title . $args["after_title"]; //output echo __("Привет мир, от сайт", "hstngr_widget_domain"); echo $args["after_widget"]; }

Здесь мы настроили вывод виджета так, чтобы он отобразил ‘Привет мир, от сайт’, и название виджета указанного пользователем.

Теперь нам необходимо написать бек-энд виджета с помощью метода form() :

Public function form($instance) { if (isset($instance[ "title" ])) $title = $instance[ "title" ]; else $title = __("Стандартный Заголовок", "hstngr_widget_domain"); ?>

" name="get_field_name("title"); ?>" type="text" value="" />

Здесь вы можете увидеть как был настроен пользовательский виджет. Если пользователь предоставил заголовок, то тогда он будет добавлен в созданную HTML форму. В противном случае, будет добавлено название Стандартный Заголовок в качестве заголовка. Этот код отвечает за то, как отображается виджет в панели управления WordPress.

И наконец последнее, но не по значению, мы добавим функцию обновления, чтобы обновлять виджет при каждом изменении его настроек.

Public function update($new_instance, $old_instance) { $instance = array(); $instance["title"] = (! empty($new_instance["title"])) ? strip_tags($new_instance["title"]) : ""; return $instance; }

Этот код принимает текущий заголовок вновь созданного экземпляра, удаляет любые теги HTML/PHP, передает заголовок экземпляру и возвращает его.

Осталась еще одна вещь, которую вам необходимо сделать, вам нужно использовать дополнительную функцию, чтобы зарегистрировать виджет в WordPress:

Function hstngr_register_widget() { register_widget("hstngr_widget"); } add_action("widgets_init", "hstngr_register_widget");

Обратите внимание, что этот код должен быть помещен вне функции hstngr_widget .

Мы определили новую функцию под названием hstngr_register_widget() , которая регистрирует наш виджет с помощью ID виджета, указанного в функции __construct() . Затем мы связали эту функцию при помощи widgets_init , которая загружает этот виджет в WordPress через встроенный метод add_action() . В финальном варианте ваш WordPress виджет должен выглядеть примерно вот так:

Function hstngr_register_widget() { register_widget("hstngr_widget"); } add_action("widgets_init", "hstngr_register_widget"); class hstngr_widget extends WP_Widget { function __construct() { parent::__construct(// widget ID "hstngr_widget", // widget name __("Тестовый Виджет Hostinger", " hstngr_widget_domain"), // widget description array("description" => __("Как создать виджеты для WordPress", "hstngr_widget_domain"),)); } public function widget($args, $instance) { $title = apply_filters("widget_title", $instance["title"]); echo $args["before_widget"]; //if title is present if (! empty($title)) echo $args["before_title"] . $title . $args["after_title"]; //output echo __("Привет мир, от сайт", "hstngr_widget_domain"); echo $args["after_widget"]; } public function form($instance) { if (isset($instance[ "title" ])) $title = $instance[ "title" ]; else $title = __("Стандартный Заголовок", "hstngr_widget_domain"); ?>

" name="get_field_name("title"); ?>" type="text" value="" />

Вы можете использовать Файловый Менеджер, FTP-клиент или Редактор WordPress для добавления этого кода в файл functions.php вашей темы. Добавьте код в файл function.php активной темы и нажмите Обновить файл для сохранения изменений.

Теперь зайдите в панель управления WordPress и перейдите во вкладку Внешний вид → Виджеты . Далее вы должны найти виджет под названием Тестовый Виджет Hostinger в списке виджетов.

Перетащите виджет в область для виджетов в правой части страницы. Теперь вы сможете выставить заголовок для виджета. Сохраните его и посетите вашу страницу..

Поздравляем, вы успешно узнали, как создать виджеты для WordPress. Теперь вы можете посмотреть как выглядит ваш виджет.

Заключение

Создать виджеты для WordPress – наверное это казалось вам очень трудной задачей, однако, это возможно для каждого человека с базовыми знаниями в HTML и PHP. В этом руководстве вы узнали, как создать виджеты для WordPress при помощи нашей краткой инструкции. Теперь вы можете начать создание еще более функциональных виджетов. Если вам понравилось наше руководство, то посетите другие .

Виджеты в WordPress позволяют облегчить пользователям процесс размещения элементов на своем сайте. Существует много различных тем и плагинов для WordPress, которые используют виджеты, дающие возможность пользователям создавать свои собственные макеты. Есть различные плагины для улучшения управления виджетами. В данной статье мы покажем вам, как создать произвольный виджет для своего сайта WordPress.

Что собой представляет WordPress-виджет?

Виджеты создавались с целью обеспечения простого способа управления дизайном и структурой материалов в WP-теме. Виджеты хороши тем, что их можно перетаскивать в сайдбар или в любые готовые к виджетам области своего сайта. Они придают прекрасную гибкость плагинам, благодаря чему их так часто и используют разработчики тем. позволяют разработчикам добавлять функциональность к своим продуктам, давая возможность пользователям обращаться к ней без необходимости написания какого-либо кода.

Конечно, как пользователь, вы всегда можете создавать свои собственные , которые впоследствии вы сможете использовать в любой теме.

Создание виджета в WordPress

Код виджета можно оформить двумя способами: либо добавить его в файл functions.php вашей темы, либо создать отдельный функциональный плагин.

В данном руководстве мы создадим простой виджет, который просто приветствует посетителей. Скопируйте следующий код и поместите его в плагин или в functions.php вашей темы.

// Creating the widget class wpb_widget extends WP_Widget { function __construct() { parent::__construct(// Base ID of your widget "wpb_widget", // Widget name will appear in UI __("WPBeginner Widget", "wpb_widget_domain"), // Widget description array("description" => __("Sample widget based on WPBeginner Tutorial", "wpb_widget_domain"),)); } // Creating widget front-end // This is where the action happens public function widget($args, $instance) { $title = apply_filters("widget_title", $instance["title"]); // before and after widget arguments are defined by themes echo $args["before_widget"]; if (! empty($title)) echo $args["before_title"] . $title . $args["after_title"]; // This is where you run the code and display the output echo __("Hello, World!", "wpb_widget_domain"); echo $args["after_widget"]; } // Widget Backend public function form($instance) { if (isset($instance[ "title" ])) { $title = $instance[ "title" ]; } else { $title = __("New title", "wpb_widget_domain"); } // Widget admin form ?>

" name="get_field_name("title"); ?>" type="text" value="" />

Теперь перейдите в раздел Внешний вид – Виджеты и перетащите виджет WPBeginner Widget в свой сайдбар, чтобы увидеть его в действии.

Довольно просто, не правда ли? Сначала мы создаем произвольный виджет. Затем мы определяем, что именно виджет делает и как он отображается в бэкенде. После чего мы определяем, как следует обрабатывать изменения, сделанные виджетом. Наконец, мы регистрируем и загружаем виджет.

В этом коде некоторые вещи могут вызвать у вас вопросы. Скажем, к примеру, что делает wpb_text_domain. WordPress использует gettext для обработки трансляции и локализации. Так вот: wpb_text_domain и __e указывают gettext на то, что эти строки доступны для перевода. , смотрите в нашем руководстве.