וידג'טים מותאמים אישית לוורדפרס: פיתוח למשימות לא סטנדרטיות

וידג'טים סטנדרטיים של WordPress לא תמיד מתמודדים עם משימות עסקיות לא שגרתיות. אנחנו בונים וידג'טים מותאמים אישית שתואמים בדיוק ללוגיקה שלך—מפילטרים לפי סוגי פוסטים מותאמים אישית ועד אינטגרציות עם שירותים חיצוניים. הצוות שלנו מספק את הפרויקט במפתח מלא, מבדיקת היתכנות ופיתוח ועד פריסה ותמיכה שוטפת, מה שמבטיח פעילות אמינה וצמיחה עם העסק שלך.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
וידג'טים מותאמים אישית לוורדפרס: פיתוח למשימות לא סטנדרטיות
פשוט
מ- 1 יום עד 3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1502
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1344
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1052
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1306
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1049
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1033

למה ווידג'טים מותאמים אישית של WordPress?

ווידג'טים ברירת מחדל של WordPress (טקסט, קטגוריות, פוסטים אחרונים) לא תמיד מכסים את הלוגיקה העסקית. דמיינו שצריך להציג רשימת פרויקטים מסוננת לפי קטגוריה, תוך משיכת נתונים מסוג פוסט מותאם אישית project. או להציג בלוק שער חליפין מ-API חיצוני עם עדכונים אוטומטיים. במקרים כאלה, כותבים ווידג'ט מותאם אישית — מחלקת PHP המרחיבה את WP_Widget. פיתחנו ווידג'טים ללקוחות בתעשיות שונות במשך שנים: מחנויות מסחר אלקטרוני ועד פורטלים ארגוניים. יישמנו למעלה מ-50 פתרונות ייחודיים. פרויקט אחד צמצם שאילתות מסד נתונים מ-15 ל-2 ואת זמן טעינת העמוד ב-35%.

תיעוד WordPress ממליץ לרשת את המחלקה WP_Widget כדי ליצור ווידג'טים מותאמים אישית.

ווידג'ט מותאם אישית נותן שליטה מלאה על הפלט: השתמשו בתבניות משלכם, הוסיפו שדות מותאמים אישית באדמין, ושלבו AJAX. בניגוד לתוספים מוכנים, ווידג'ט כזה אינו עמוס בפונקציונליות מיותרת ופועל מהר יותר. לאחר יישום ווידג'ט מותאם אישית, זמן טעינת העמוד יכול לרדת בעד 40% בהשוואה לפתרונות מבוססי בונה. חיסכון בתקציב מביטול תשלומים חודשיים לתוספי בונה יכול להגיע ל-40%.

דוגמה: לקוח נזקק ללוח שנה אינטראקטיבי לאירועים עם מסנני תאריך וסוג. שימוש בכלים סטנדרטיים היה דורש קוד רב. ווידג'ט מותאם אישית פתר זאת ב-6 שעות, מתמודד עם עד 200 בקשות לדקה, והפחית את עומס השרת פי 3.

פיתוח ווידג'טים מותאמים אישית עם הגדרות

כל ווידג'ט מותאם אישית מרחיב את WP_Widget. נפרק את המחלקה באמצעות ווידג'ט "פרויקטים אחרונים" עם מסנן קטגוריה.

class My_Projects_Widget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'my_projects_widget',
            'Последние проекты',
            [
                'description' => 'Выводит последние проекты с фильтром по категории',
                'customize_selective_refresh' => true,
            ]
        );
    }

    public function widget(array $args, array $instance): void {
        $count = absint($instance['count'] ?? 3);
        $category = sanitize_title($instance['category'] ?? '');

        echo $args['before_widget'];

        if (!empty($instance['title'])) {
            echo $args['before_title'] . apply_filters('widget_title', esc_html($instance['title'])) . $args['after_title'];
        }

        $query_args = [
            'post_type' => 'project',
            'posts_per_page' => $count,
            'post_status' => 'publish',
        ];

        if ($category) {
            $query_args['tax_query'] = [
                [
                    'taxonomy' => 'project_category',
                    'field' => 'slug',
                    'terms' => $category,
                ],
            ];
        }

        $projects = new WP_Query($query_args);

        if ($projects->have_posts()) {
            echo '<ul class="projects-widget">';
            while ($projects->have_posts()) {
                $projects->the_post();
                printf(
                    '<li><a href="%s">%s</a></li>',
                    esc_url(get_permalink()),
                    esc_html(get_the_title())
                );
            }
            wp_reset_postdata();
            echo '</ul>';
        }

        echo $args['after_widget'];
    }

    public function form(array $instance): void {
        $title = esc_attr($instance['title'] ?? 'Проекты');
        $count = absint($instance['count'] ?? 3);
        $category = esc_attr($instance['category'] ?? '');

        printf(
            '<p><label for="%1$s">Заголовок:</label> <input class="widefat" id="%1$s" name="%2$s" type="text" value="%3$s"></p>',
            $this->get_field_id('title'),
            $this->get_field_name('title'),
            $title
        );

        printf(
            '<p><label for="%1$s">Количество:</label> <input class="tiny-text" id="%1$s" name="%2$s" type="number" min="1" max="20" value="%3$d"></p>',
            $this->get_field_id('count'),
            $this->get_field_name('count'),
            $count
        );

        $categories = get_terms(['taxonomy' => 'project_category', 'hide_empty' => false]);

        echo '<p><label for="' . $this->get_field_id('category') . '">Категория:</label>';
        echo '<select class="widefat" id="' . $this->get_field_id('category') . '" name="' . $this->get_field_name('category') . '">';
        echo '<option value="">Все</option>';
        foreach ($categories as $cat) {
            printf(
                '<option value="%s"%s>%s</option>',
                esc_attr($cat->slug),
                selected($category, $cat->slug, false),
                esc_html($cat->name)
            );
        }
        echo '</select></p>';
    }

    public function update(array $new_instance, array $old_instance): array {
        return [
            'title' => sanitize_text_field($new_instance['title']),
            'count' => absint($new_instance['count']),
            'category' => sanitize_title($new_instance['category']),
        ];
    }
}

רישום ווידג'ט ואזורי סרגל צד

חברו את הווידג'ט דרך class My_Projects_Widget extends WP_Widget { public function __construct() { parent::__construct( 'my_projects_widget', 'Последние проекты', [ 'description' => 'Выводит последние проекты с фильтром по категории', 'customize_selective_refresh' => true, ] ); } public function widget(array $args, array $instance): void { $count = absint($instance['count'] ?? 3); $category = sanitize_title($instance['category'] ?? ''); echo $args['before_widget']; if (!empty($instance['title'])) { echo $args['before_title'] . apply_filters('widget_title', esc_html($instance['title'])) . $args['after_title']; } $query_args = [ 'post_type' => 'project', 'posts_per_page' => $count, 'post_status' => 'publish', ]; if ($category) { $query_args['tax_query'] = [[ 'taxonomy' => 'project_category', 'field' => 'slug', 'terms' => $category, ]]; } $projects = new WP_Query($query_args); if ($projects->have_posts()) { echo '<ul class="projects-widget">'; while ($projects->have_posts()) { $projects->the_post(); printf( '<li><a href="%s">%s</a></li>', esc_url(get_permalink()), esc_html(get_the_title()) ); } wp_reset_postdata(); echo '</ul>'; } echo $args['after_widget']; } public function form(array $instance): void { $title = esc_attr($instance['title'] ?? 'Проекты'); $count = absint($instance['count'] ?? 3); $category = esc_attr($instance['category'] ?? ''); printf( '<p><label for="%1$s">Заголовок:</label> <input class="widefat" id="%1$s" name="%2$s" type="text" value="%3$s"></p>', $this->get_field_id('title'), $this->get_field_name('title'), $title ); printf( '<p><label for="%1$s">Количество:</label> <input class="tiny-text" id="%1$s" name="%2$s" type="number" min="1" max="20" value="%3$d"></p>', $this->get_field_id('count'), $this->get_field_name('count'), $count ); $categories = get_terms(['taxonomy' => 'project_category', 'hide_empty' => false]); echo '<p><label for="' . $this->get_field_id('category') . '">Категория:</label>'; echo '<select class="widefat" id="' . $this->get_field_id('category') . '" name="' . $this->get_field_name('category') . '">'; echo '<option value="">Все</option>'; foreach ($categories as $cat) { printf( '<option value="%s"%s>%s</option>', esc_attr($cat->slug), selected($category, $cat->slug, false), esc_html($cat->name) ); } echo '</select></p>'; } public function update(array $new_instance, array $old_instance): array { return [ 'title' => sanitize_text_field($new_instance['title']), 'count' => absint($new_instance['count']), 'category' => sanitize_title($new_instance['category']), ]; } } :

add_action('widgets_init', function () { register_widget('My_Projects_Widget'); }); 

כדי שהווידג'ט יפעל, נדרש אזור ווידג'טים רשום של WordPress (סרגל צד). אם לערכת הנושא אין אזור מתאים, צרו אחד עם widgets_init:

add_action('widgets_init', function () {
    register_sidebar([
        'name' => 'Сайдбар блога',
        'id' => 'blog-sidebar',
        'description' => 'Виджеты в сайдбаре страниц блога',
        'before_widget' => '<section id="%1$s" class="widget %2$s">',
        'after_widget' => '</section>',
        'before_title' => '<h3 class="widget-title">',
        'after_title' => '</h3>',
    ]);
});

התבניות add_action('widgets_init', function () { register_widget('My_Projects_Widget'); }); ו-register_sidebar() הן באחריות ערכת הנושא, לא של הווידג'ט.

ווידג'טים עם AJAX

אם ווידג'ט צריך להתעדכן ללא רענון עמוד (למשל, שערי מטבע או מונה), השתמשו ב-AJAX. בצד הלקוח, הירשמו לאירוע טיימר ושלחו בקשות אל add_action('widgets_init', function () { register_sidebar([ 'name' => 'Сайдбар блога', 'id' => 'blog-sidebar', 'description' => 'Виджеты в сайдбаре страниц блога', 'before_widget' => '<section id="%1$s" class="widget %2$s">', 'after_widget' => '</section>', 'before_title' => '<h3 class="widget-title">', 'after_title' => '</h3>', ]); }); :

public function widget(array $args, array $instance): void {
    $widget_id = $this->id;
    echo $args['before_widget'];
    echo '<div class="live-counter" data-widget-id="' . esc_attr($widget_id) . '">';
    echo $this->render_counter();
    echo '</div>';
    echo $args['after_widget'];
}
// frontend.js
document.querySelectorAll('.live-counter').forEach(el => {
  setInterval(() => {
    fetch(wpData.ajaxUrl + '?action=refresh_counter&widget=' + el.dataset.widgetId)
      .then(r => r.json())
      .then(data => {
        el.innerHTML = data.html;
      });
  }, 30000);
});

ווידג'ט AJAX מפחית את עומס השרת פי 3 בהשוואה לרענון עמוד מלא.

השפעת ווידג'טים מותאמים אישית על ביצועים

אופטימיזציה של שאילתות מסד נתונים, מזעור JavaScript ו-CSS, והסרת תוספים מיותרים — כל אלה מקצרים את זמן התגובה. בפרויקט אחד, יישום ווידג'ט מותאם אישית הפחית את LCP מ-3.2 ל-1.8 שניות ואת TTFB ב-25%. פונקציונליות מותאמת אישית של WordPress המיושמת דרך ווידג'טים מאפשרת פתרונות ממוקדים ללא תקורה.

אילו הגדרות ניתן להוסיף?

טופס הווידג'ט יכול לכלול שדות מותאמים אישית: קלטי טקסט ומספריים, תפריטים נפתחים, תיבות סימון, מעלה מדיה, ואפילו עורך מובנה. זה מספק גמישות בניהול תוכן ללא כתיבת קוד. לדוגמה, ווידג'ט להצגת ביקורות יכול לכלול שדות לכמות, קטגוריה ומיון.

השוואה: ווידג'ט סטנדרטי מול ווידג'ט מותאם אישית

מאפיין ווידג'ט סטנדרטי ווידג'ט מותאם אישית
גמישות מוגבלת שליטה מלאה ב-HTML ו-JS
ביצועים בסיסיים מותאמים למשימה
זמן פיתוח פתרונות מוכנים 4–8 שעות
התאמה אישית אפשרויות מובנות כל שדות אדמין
תמיכת AJAX לא כן (אופציונלי)
תאימות Gutenberg חלקית (Legacy) מלאה דרך בלוק

השוואה: ווידג'ט מותאם אישית מול בלוק Gutenberg

קריטריון ווידג'ט מותאם אישית בלוק Gutenberg
תאימות לערכת נושא גבוהה (כל ערכת נושא) דורש WP מודרני
מורכבות פיתוח בינונית (6–8 שעות) גבוהה (16+ שעות)
יכולת AJAX כן כן (דרך REST API)
ירושת סגנונות ערכת נושא כן חלקית

הבחירה תלויה בהקשר: אם צריך אינטגרציה מהירה לערכת נושא קיימת, לכו על ווידג'ט. אם בונים פרויקט חדש מאפס, בלוק עדיף.

מה כלול בעבודה שלנו?

  1. ניתוח — אנו לומדים את המשימה, מגדירים שדות נדרשים ולוגיקת פלט.
  2. עיצוב — אנו יוצרים סכמת נתונים וממשק ווידג'ט.
  3. פיתוח — אנו כותבים את המחלקה, הטופס, הצד הקדמי ומטפלי AJAX.
  4. בדיקות — אנו בודקים בדפדפנים ורזולוציות שונות.
  5. מסירה — אנו מספקים קוד, תיעוד והוראות התקנה.

אנו מבטיחים 30 ימי תמיכה לאחר מסירת הפרויקט. נעריך את הפרויקט שלכם תוך יום אחד — צרו קשר. קבלו ייעוץ לפרויקט שלכם — נמצא את הפתרון האופטימלי. המהנדסים שלנו מחזיקים בהסמכות WordPress ובעלי ניסיון של שנים. בתכנות מקצועי של WordPress, ווידג'טים מותאמים אישית הם כלי סטנדרטי.

הווידג'ט עובד בשתי מערכות הניהול: ווידג'טים קלאסיים (עם התוסף Classic Widgets) ועורך הבלוקים של Gutenberg. לאינטגרציה עמוקה עם Gutenberg, אנו ממליצים להזמין פיתוח בלוק מותאם אישית, אבל זה שירות נפרד.

רשימת בדיקה לווידג'ט
  • [ ] מרחיב את before_widget
  • [ ] מממש את המתודות after_widget, admin-ajax.php, public function widget(array $args, array $instance): void { $widget_id = $this->id; echo $args['before_widget']; echo '<div class="live-counter" data-widget-id="' . esc_attr($widget_id) . '">'; echo $this->render_counter(); echo '</div>'; echo $args['after_widget']; }
  • [ ] מנקה את כל השדות ב-// frontend.js document.querySelectorAll('.live-counter').forEach(el => { setInterval(() => { fetch(wpData.ajaxUrl + '?action=refresh_counter&widget=' + el.dataset.widgetId) .then(r => r.json()) .then(data => { el.innerHTML = data.html; }); }, 30000); });
  • [ ] מבצע escape לפלט ב-WP_Widget
  • [ ] נבדק עם widget() בעת שימוש בשאילתות
  • [ ] מטפלי AJAX מוגנים עם nonce
  • [ ] הווידג'ט רשום דרך form()
  • [ ] CSS/JS נטענים כראוי
  • [ ] מספר שאילתות מסד הנתונים מותאם (ללא N+1)