Create a Poll with PHPixie

Share this article

When choosing a PHP framework you need to make sure that it emphasizes features which are the most important to you. If you are looking for something fast, simple, and easy to learn than PHPixie may be a perfect choice. To illustrate the basics of developing with PHPixie we will create a small polling application. By the end of this tutorial you will have a working poll application and an understanding of how easy it is to code projects using PHPixie. Before going on, make sure you download PHPixie from the project’s website and extract the downloaded archive into the root web directory of your web server. Visit http://localhost/ (or other address as appropriate) in your browser and you should see the ‘Have fun coding!’ welcome message.

Creating the Database

First we’ll need to create two tables in the database: polls will store the topic we would like to get opinions for, and options will contain possible answers for each poll and the amount of votes each received. Open up your MySQL client and run these queries:
CREATE TABLE polls (
    id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    topic VARCHAR(255) NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE options (
    id INTEGER NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) DEFAULT NULL,
    poll_id INTEGER UNSIGNED NOT NULL,
    votes INTEGER NOT NULL DEFAULT 0,
    PRIMARY KEY (id),
    FOREIGN KEY (poll_id) REFERENCES polls(id)
);
To configure the database connection, we edit the database.php file inside the application/config directory:
<?php
return array(
    'default' => array(
        'user' => 'dbuser',
        'password' => 'dbpassword',
        'driver' => 'pdo',

        // 'Connection' is required if we use the PDO driver
        'connection' => 'mysql:host=localhost;dbname=polls',

        // 'db' and 'host' are required if we use Mysql driver
        'db' => 'polls',
        'host' => 'localhost'
    )
);
PHPixie can be configured to use multiple database connections, but since we are working with just the single database we specify it as default. That’s all the configuration required, so we can move to writing code now.

Models

A common way to describe the Model-View-Controller architecture is as follows:
  • Models represent data objects we work with (polls and options in our case)
  • Controllers handle user requests and are the heart of our application
  • Views are templates that controllers use to display the response
Typically, models handle operations like retrieving data from the database and saving it. PHPixie takes care of these operations using an ORM layer so we don’t need to write any database queries at all. We just need to define our models like this:
<?php
class Poll_Model extends ORM {
    // Each poll can have many options
    public $has_many = array('options');

    // This way we can define some additional
    // dynamic properties for a model.
    // Later on we will be able to access it via $poll->total_votes
    public function get($property) {
        if ($property == 'total_votes') {
            $total = 0;
            foreach ($this->options->find_all() as $option) {
                $total += $option->votes;
            }
            return $total;
        }
    }
}
The above code should be placed in application/classes/model/poll.php. Relationships may be defined using 3 arrays: belongs_to, has_one, and has_many. The first (belongs_to) defines a one-to-one relationship when a table references another table using a foreign key, in our case options belongs to polls using the poll_id field. The foreign key is automatically guessed using model names by PHPixie. On the other side of the belongs to relationship falls has_many, in our case each poll has many options. has_one is a special case of has_many, limiting the amount of referenced objects to one. To define a relationship, we just need to add the name of the model we want to the appropriate array. A more thorough relationship configuration is possible, with the ability to specify which field to use for the relationship, set a different name for it, or to create a many-to-many relationship via a linking table, but in our case using this simple approach is enough. The find_all() method looks up records in the database. When we reference the options property, ORM is silently building a database query to select all of the options for the current poll. Calling find_all() subsequently executes that query and returns these options also as ORM models. Overriding the get() method allows us to add properties to our model dynamically. If a property we are trying to access is not found in the model class, ORM will call the class’ get()
method passing the name of the property as an argument. Any result that get() will return will be considered the value for that property and stored inside the model, so that when we access the property once more we will get the cached value. As internal model operations usually invoke some kind of database action, it is preferable to have data cached, so that’s why we’re overriding get(). Note that while get() is often used to cache data from find_all(), it is not meant only for that. For example, we could use get() to define a property that we would access multiple times but should only be retrieved once. This internal cache persists only for the current object. Of course if you don’t want this behavior at all it is always possible to add your own total_votes() method to the model that will recalculate the votes each time it is called. The code for the options model is placed in application/classes/model/option.php:
<?php
class Option_Model extends ORM {
    public $belongs_to = array('poll');

    public function get($property) {
        if ($property == 'percent') {
            if ($this->poll->total_votes == 0) {
                return 0;
            }
            return floor($this->votes / $this->poll->total_votes * 100);
        }
    }
}
This model follows similar logic as the previous one. We define a belongs_to relationship with polls and a percent property, the only difference being that for one-to-one relationships it is not necessary to call the find_all() method, so we can access the poll that this option belongs to just as if it was a property. PHPixie relies heavily on naming conventions to save us time when creating models, although it doesn’t force us to name everything according to these conventions (it’s easy to alter this behavior). Here we’re following the convention of using the plural form when naming tables in the database and singular form when naming models.

Basic Controller

The URL for a specific action by default is /// e.g. http://localhost/polls/add. It is also possible to pass an extra ID parameter after the action which we will use to access individual polls. Our controller will have to know how to display three types of pages:
  • Main page with all the polls listed
  • A single poll page where we can see current results and cast a vote
  • A form to add a new poll
Each page must have an action defined for it inside the controller and we will need a HTML template for every page too. So, a simple Controller that just displays the templates would look like this:
<?php
class Polls_Controller extends Controller
{
    public function action_index() {
        // This is how we load up a template
        $view = View::get('index');
        $this->response->body = $view->render();
    }

    public function action_poll() {
        $view = View::get('poll');
        $this->response->body = $view->render();
    }

    public function action_add() {
        $view = View::get('add');
        $this->response->body = $view->render();
    }
}
A big issue with this setup is that there would be a lot of code repeated inside the templates because every page needs a header and footer. The solution is to create one general template and then include subtemplates inside it. We can do this using the before() and after() methods defined inside the controller and they will execute respectively before and after an action is called. Now our controller will look like this (save the following as application/classes/controller/polls.php):
<?php
class Polls_Controller extends Controller
{
    protected $view;

    public function before() {
        // We load up the main view and
        $this->view = View::get('main');

        // Now we find a full path to a view that has
        // the same names as the action to be excuted
        $template = Misc::find_file('views', $this->request->param('action'));

        // We pass the view we located to our main template.
        // All properties assigned to a view will be available
        // as variables inside the template
        $this->view->template = $template;
    }

    public function after() {
        // After an action completes we render the view
        $this->response->body = $this->view->render();
   }

   public function action_index(){
        $view = View::get('index');
        $this->response->body = $view->render();
    }

    public function action_poll() {
        $view = View::get('poll');
        $this->response->body = $view->render();
    }

    public function action_add() {
        $view = View::get('add');
        $this->response->body = $view->render();
    }
}
We can pass any variables we like to the view just by assigning them as properties. Now before we add any more code to the controller, let’s take a look at the views themselves.

HTML Layouts Using Views

Views are basically HTML files with inserted PHP code to display the values assigned to place-holder variables from inside the controller. Our main view is quite small as all it has to do is present some common HTML and include a correct subtemplate. The following is application/views/main.php:
<!DOCTYPE html>
<html>
 <head>
  <title>PHPixie polls</title>
  <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-combined.min.css" rel="stylesheet">
  <link href="/style.css" rel="stylesheet">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
 </head>
 <body>
  <div class="container">
   <div class="span4"></div>
   <div class="span4">
    <h2>PHPixie Polls</h2>
    <!-- Here is where we include a subtemplate -->
<?php include($template);?>
   </div>
   <div class="span4"></div>
  </div>
 </body>
</html>
We’ll use Bootstrap as a base for our page styles so we don’t have to concentrate too much on the design. The only modifications we need to make to the CSS are in the web/style.css file.
.nav .muted {
    float: right;
}

td form {
    margin-bottom: 0px;
}

.filled {
    background: #08C;
    height: 20px;
}

.bar {
    width: 100px;
}
Now we can create the individual pages.

Creating Individual Pages

The polls page should just present a list of available polls. It only requires a slight modification to controller/polls.php
.
<?php
//...
public function action_index() {
    // We pass all stored polls to the view
    $this->view->polls = ORM::factory('poll')->find_all();
}
The view will for the page will be a simple list with a link to the poll creation page. The following is code for views/index.php:
<ul class="nav nav-tabs nav-stacked">
<?php
foreach($polls as $poll) {
?>
 <li>
  <!-- This is how a link to a single poll will look like -->
  <a href="/polls/poll/<?=$poll->id;?>"><?=$poll->topic;?>
   <div class="muted"><?=$poll->total_votes; ?> Votes</div>
  </a>
 </li>
<?php
}
?>
</ul>
<a class="btn btn-block" href="/polls/add"><i class="icon-plus"></i> Add a Poll</a>
If we were to add some data to the database at this point we would see the following when accessing http://localhost/polls/index (index can be omitted from the URL as it is the default action):

phpixie-01

Creating polls requires a bit more work. We have to check if the form was submitted, if so we save a poll and redirect the user back to the listing, otherwise we display the form. Add the following update to controller/polls.php:
<?php
//...
public function action_add() {
    // We only need to perform this if the form was submitted
    if ($this->request->method == 'POST') {

        // Creating a new poll
        $poll = ORM::factory('poll');

        // This is how you access POST form data
        $poll->topic = $this->request->post('topic');

        // Save the poll to the database
        $poll->save();

        // Similarly we create and save options specified for this poll
        foreach($this->request->post('options') as $name) {
            if (empty($name)) {
                continue;
            }
            $option = ORM::factory('option');
            $option->name = $name;
            $option->save();

            // We add each option to the 'options' relation we defined for the poll
            $poll->add('options', $option);
        }

        // This will prevent after() from executing
        // we need to do this because there is no point of returning any data
        // if we redirect the user
        $this->execute=false;
        $this->response->redirect('/polls/');
        return;
    }

    // If the form was not submitted the after() method will
    // take care of showing the creation form
}
There is nothing special about the template for poll creation. Use the following to create views/add.php:
<script>
$(function() {
    $('#addOption').click(function(evt) {
        evt.preventDefault();

        var newOption = $('.option:eq(0)').clone();
        newOption.find('input').val('').attr('placeholder', 'Option #'+($('.option').length + 1));
        $('#options').append(newOption);
    })
})
</script>
<form method="POST">
 <fieldset>
  <legend>Add a new poll</legend>
  <label>Topic</label>
  <input type="text" placeholder="Type your topic here..." name="topic">
  <label>Options</label>
  <div id="options">
   <div class="option">
    <input type="text" name="options[]" placeholder="Option #1">
   </div>
   <div class="option">
    <input type="text" name="options[]" placeholder="Option #2">
   </div>
   <div class="option">
    <input type="text" name="options[]" placeholder="Option #3">
   </div>
  </div>
  <button class="btn" id="addOption"><i class="icon-plus"></i> Add option</button>
  <button class="btn btn-primary"><i class="icon-ok icon-white"></i> Save poll</button>
 </fieldset>
</form>
<a class="btn btn-link" href="/polls">&lt; Back to polls</a>
Note that we specified the name for the option text input like options[], this way it will be passed as array of options to PHP. We also added a convenient Add Option button to add additional rows. The result should look as follows:

phpixie-02

I hope at this point you can already predict some of the code you will see here. This controller has to fetch the poll specified by the ID in the URL, and it should also handle users voting for an option. Again, make the following updates to controller/polls.php:
<?php
//...
public function action_poll() {

    // Handle voting
    if ($this->request->method == 'POST') {

        // If an option is was supplied via POST we increment
        // its votes field by 1
        $option_id = $this->request->post('option');
        $option = ORM::factory('option')->where('id', $option_id)->find();
        $option->votes += 1;
        $option->save();

        // Now we redirect the user back to current polls' page
        // This is done so that refreshing a browser window will not
        // produce multiple votes
        $this->response->redirect('/polls/poll/' . $option->poll->id);
        $this->execute = false;
        return;
    }

    // You can get the url id parameter using param()
    $id = $this->request->param('id');
    $this->view->poll = ORM::factory('poll')->where('id', $id)->find();
}
The find() method acts just like find_all() but it returns only the first result. Inside the view we want to draw bars that would depict the relative amount of votes, and this is why we added that percent property to the options model earlier. The following code is for views/poll.php:
<h3><?=$poll->topic;?></h3>
<table class="table">
<?php
foreach ($poll->options->find_all() as $option) {
?>
 <tr>
  <td><?=$option->name;?></td>
  <td><?=$option->votes;?></td>
  <td class="bar">
   <div class="filled" style="width:<?=$option->percent;?>%;"></div>
  </td>
  <td>
   <form method="POST">
    <input type="hidden" name="option" value="<?=$option->id;?>">
    <button class="btn btn-mini">Vote</button>
   </form>
  </td>
 </tr>
<?php
}
?>
</table>
<a class="btn btn-link" href="/polls">&lt; Back to polls</a>
And this is how it will look like:

phpixie-03

Almost Done

Before we declare our application complete we still need to make sure it is available by visiting http://localhost/. To do this, we have to change the default controller in the application/config/core.php configuration file from ‘home’ to ‘polls’ like this:
<?php
return array(
    'routes' => array(
        array('default', '(/<controller>(/<action>(/<id>)))', array(
            'controller' => 'polls',
            'action' => 'index'
            )
        )
    ),
    'modules' => array('database', 'orm')
);
Now we have a fully functional poll application as well as a grasp on how PHPixie handles things and how easy it is to develop with it. If you’d like to download the code for this article to explore, you can find it on GitHub. There is still a lot to learn though. Things like custom routes and complex ORM relationship can help you tailor your project even more. Learn more about them by visiting the PHPixie website. Image via Fotolia

Frequently Asked Questions about Creating a Poll with PHPixie

How can I create a database for my poll in PHPixie?

Creating a database for your poll in PHPixie involves several steps. First, you need to set up a new MySQL database. This can be done through your hosting control panel. Once the database is set up, you need to configure PHPixie to connect to this database. This is done by editing the ‘database.php’ file in your PHPixie application’s ‘config’ directory. You need to provide the database name, username, password, and host information in this file. Once the database connection is set up, you can create a new table for your poll. This can be done using SQL commands. The table should have fields for the poll question, the possible answers, and the number of votes for each answer.

How can I display the poll results in PHPixie?

Displaying the poll results in PHPixie can be done by querying the database for the poll data and then displaying this data in a view. The query should select the poll question, the possible answers, and the number of votes for each answer. This data can then be passed to a view, which can display the data in a suitable format. The view can use HTML and CSS to format the poll results in a visually appealing way. For example, you could display the poll results as a bar chart, with each answer represented by a bar and the length of the bar corresponding to the number of votes for that answer.

How can I prevent multiple voting in my PHPixie poll?

Preventing multiple voting in your PHPixie poll can be achieved by tracking the IP addresses of the users who have voted. When a user votes, their IP address can be stored in the database along with their vote. Before a vote is recorded, the application can check if the user’s IP address is already in the database. If it is, the application can refuse to record the vote and display a message to the user informing them that they have already voted. This method is not foolproof, as users can change their IP address or use a VPN to bypass this restriction, but it can help to prevent casual multiple voting.

How can I add a comment section to my PHPixie poll?

Adding a comment section to your PHPixie poll involves creating a new table in your database for the comments. This table should have fields for the comment text, the user who posted the comment, and the time the comment was posted. You can then create a form in your view for users to submit comments. When a comment is submitted, it can be inserted into the comments table in the database. The comments can then be displayed below the poll by querying the comments table and passing the results to the view.

How can I add a customer review section to my PHPixie poll?

Adding a customer review section to your PHPixie poll is similar to adding a comment section. You need to create a new table in your database for the reviews. This table should have fields for the review text, the user who posted the review, the time the review was posted, and a rating. The rating can be a number from 1 to 5, representing the user’s satisfaction with the product or service being polled. You can then create a form in your view for users to submit reviews. When a review is submitted, it can be inserted into the reviews table in the database. The reviews can then be displayed below the poll by querying the reviews table and passing the results to the view.

Roman TsjupaRoman Tsjupa
View Author

Roman Tsiupa is the lead developer of the PHPixie framework. Aside from web development his interests range from low-level programming to server management and optimization. In his free time he makes HTML5 games and WebGL demos.

Intermediate
Share this article
Read Next
How to Use jQuery’s ajax() Function for Asynchronous HTTP Requests
How to Use jQuery’s ajax() Function for Asynchronous HTTP Requests
Aurelio De RosaMaria Antonietta Perna
Quick Tip: How to Align Column Rows with CSS Subgrid
Quick Tip: How to Align Column Rows with CSS Subgrid
Ralph Mason
15 Top Web Design Tools & Resources To Try in 2024
15 Top Web Design Tools & Resources To Try in 2024
SitePoint Sponsors
7 Simple Rules for Better Data Visualization
7 Simple Rules for Better Data Visualization
Mariia Merkulova
Cloudways Autonomous: Fully-Managed Scalable WordPress Hosting
Cloudways Autonomous: Fully-Managed Scalable WordPress Hosting
SitePoint Team
Best Programming Language for AI
Best Programming Language for AI
Lucero del Alba
Quick Tip: How to Add Gradient Effects and Patterns to Text
Quick Tip: How to Add Gradient Effects and Patterns to Text
Ralph Mason
Logging Made Easy: A Beginner’s Guide to Winston in Node.js
Logging Made Easy: A Beginner’s Guide to Winston in Node.js
Vultr
How to Optimize Website Content for Featured Snippets
How to Optimize Website Content for Featured Snippets
Dipen Visavadiya
Psychology and UX: Decoding the Science Behind User Clicks
Psychology and UX: Decoding the Science Behind User Clicks
Tanya Kumari
Build a Full-stack App with Node.js and htmx
Build a Full-stack App with Node.js and htmx
James Hibbard
Digital Transformation with AI: The Benefits and Challenges
Digital Transformation with AI: The Benefits and Challenges
Priyanka Prajapat
Quick Tip: Creating a Date Picker in React
Quick Tip: Creating a Date Picker in React
Dianne Pena
How to Create Interactive Animations Using React Spring
How to Create Interactive Animations Using React Spring
Yemi Ojedapo
10 Reasons to Love Google Docs
10 Reasons to Love Google Docs
Joshua KrausZain Zaidi
How to Use Magento 2 for International Ecommerce Success
How to Use Magento 2 for International Ecommerce Success
Mitul Patel
5 Exciting New JavaScript Features in 2024
5 Exciting New JavaScript Features in 2024
Olivia GibsonDarren Jones
Tools and Strategies for Efficient Web Project Management
Tools and Strategies for Efficient Web Project Management
Juliet Ofoegbu
Choosing the Best WordPress CRM Plugin for Your Business
Choosing the Best WordPress CRM Plugin for Your Business
Neve Wilkinson
ChatGPT Plugins for Marketing Success
ChatGPT Plugins for Marketing Success
Neil Jordan
Managing Static Files in Django: A Comprehensive Guide
Managing Static Files in Django: A Comprehensive Guide
Kabaki Antony
The Ultimate Guide to Choosing the Best React Website Builder
The Ultimate Guide to Choosing the Best React Website Builder
Dianne Pena
Exploring the Creative Power of CSS Filters and Blending
Exploring the Creative Power of CSS Filters and Blending
Joan Ayebola
How to Use WebSockets in Node.js to Create Real-time Apps
How to Use WebSockets in Node.js to Create Real-time Apps
Craig Buckler
Best Node.js Framework Choices for Modern App Development
Best Node.js Framework Choices for Modern App Development
Dianne Pena
SaaS Boilerplates: What They Are, And 10 of the Best
SaaS Boilerplates: What They Are, And 10 of the Best
Zain Zaidi
Understanding Cookies and Sessions in React
Understanding Cookies and Sessions in React
Blessing Ene Anyebe
Enhanced Internationalization (i18n) in Next.js 14
Enhanced Internationalization (i18n) in Next.js 14
Emmanuel Onyeyaforo
Essential React Native Performance Tips and Tricks
Essential React Native Performance Tips and Tricks
Shaik Mukthahar
How to Use Server-sent Events in Node.js
How to Use Server-sent Events in Node.js
Craig Buckler
Five Simple Ways to Boost a WooCommerce Site’s Performance
Five Simple Ways to Boost a WooCommerce Site’s Performance
Palash Ghosh
Elevate Your Online Store with Top WooCommerce Plugins
Elevate Your Online Store with Top WooCommerce Plugins
Dianne Pena
Unleash Your Website’s Potential: Top 5 SEO Tools of 2024
Unleash Your Website’s Potential: Top 5 SEO Tools of 2024
Dianne Pena
How to Build a Chat Interface using Gradio & Vultr Cloud GPU
How to Build a Chat Interface using Gradio & Vultr Cloud GPU
Vultr
Enhance Your React Apps with ShadCn Utilities and Components
Enhance Your React Apps with ShadCn Utilities and Components
David Jaja
10 Best Create React App Alternatives for Different Use Cases
10 Best Create React App Alternatives for Different Use Cases
Zain Zaidi
Control Lazy Load, Infinite Scroll and Animations in React
Control Lazy Load, Infinite Scroll and Animations in React
Blessing Ene Anyebe
Building a Research Assistant Tool with AI and JavaScript
Building a Research Assistant Tool with AI and JavaScript
Mahmud Adeleye
Understanding React useEffect
Understanding React useEffect
Dianne Pena
Web Design Trends to Watch in 2024
Web Design Trends to Watch in 2024
Juliet Ofoegbu
Building a 3D Card Flip Animation with CSS Houdini
Building a 3D Card Flip Animation with CSS Houdini
Fred Zugs
How to Use ChatGPT in an Unavailable Country
How to Use ChatGPT in an Unavailable Country
Dianne Pena
An Introduction to Node.js Multithreading
An Introduction to Node.js Multithreading
Craig Buckler
How to Boost WordPress Security and Protect Your SEO Ranking
How to Boost WordPress Security and Protect Your SEO Ranking
Jaya Iyer
Understanding How ChatGPT Maintains Context
Understanding How ChatGPT Maintains Context
Dianne Pena
Building Interactive Data Visualizations with D3.js and React
Building Interactive Data Visualizations with D3.js and React
Oluwabusayo Jacobs
JavaScript vs Python: Which One Should You Learn First?
JavaScript vs Python: Which One Should You Learn First?
Olivia GibsonDarren Jones
13 Best Books, Courses and Communities for Learning React
13 Best Books, Courses and Communities for Learning React
Zain Zaidi
5 jQuery.each() Function Examples
5 jQuery.each() Function Examples
Florian RapplJames Hibbard
Implementing User Authentication in React Apps with Appwrite
Implementing User Authentication in React Apps with Appwrite
Yemi Ojedapo
AI-Powered Search Engine With Milvus Vector Database on Vultr
AI-Powered Search Engine With Milvus Vector Database on Vultr
Vultr
Understanding Signals in Django
Understanding Signals in Django
Kabaki Antony
Why React Icons May Be the Only Icon Library You Need
Why React Icons May Be the Only Icon Library You Need
Zain Zaidi
View Transitions in Astro
View Transitions in Astro
Tamas Piros
Getting Started with Content Collections in Astro
Getting Started with Content Collections in Astro
Tamas Piros
What Does the Java Virtual Machine Do All Day?
What Does the Java Virtual Machine Do All Day?
Peter Kessler
Become a Freelance Web Developer on Fiverr: Ultimate Guide
Become a Freelance Web Developer on Fiverr: Ultimate Guide
Mayank Singh
Layouts in Astro
Layouts in Astro
Tamas Piros
.NET 8: Blazor Render Modes Explained
.NET 8: Blazor Render Modes Explained
Peter De Tender
Mastering Node CSV
Mastering Node CSV
Dianne Pena
A Beginner’s Guide to SvelteKit
A Beginner’s Guide to SvelteKit
Erik KückelheimSimon Holthausen
Brighten Up Your Astro Site with KwesForms and Rive
Brighten Up Your Astro Site with KwesForms and Rive
Paul Scanlon
Which Programming Language Should I Learn First in 2024?
Which Programming Language Should I Learn First in 2024?
Joel Falconer
Managing PHP Versions with Laravel Herd
Managing PHP Versions with Laravel Herd
Dianne Pena
Accelerating the Cloud: The Final Steps
Accelerating the Cloud: The Final Steps
Dave Neary
An Alphebetized List of MIME Types
An Alphebetized List of MIME Types
Dianne Pena
The Best PHP Frameworks for 2024
The Best PHP Frameworks for 2024
Claudio Ribeiro
11 Best WordPress Themes for Developers & Designers in 2024
11 Best WordPress Themes for Developers & Designers in 2024
SitePoint Sponsors
Top 9 Best WordPress AI Plugins of 2024
Top 9 Best WordPress AI Plugins of 2024
Dianne Pena
20+ Tools for Node.js Development in 2024
20+ Tools for Node.js Development in 2024
Dianne Pena
The Best Figma Plugins to Enhance Your Design Workflow in 2024
The Best Figma Plugins to Enhance Your Design Workflow in 2024
Dianne Pena
Harnessing the Power of Zenserp for Advanced Search Engine Parsing
Harnessing the Power of Zenserp for Advanced Search Engine Parsing
Christopher Collins
Build Your Own AI Tools in Python Using the OpenAI API
Build Your Own AI Tools in Python Using the OpenAI API
Zain Zaidi
The Best React Chart Libraries for Data Visualization in 2024
The Best React Chart Libraries for Data Visualization in 2024
Dianne Pena
7 Free AI Logo Generators to Get Started
7 Free AI Logo Generators to Get Started
Zain Zaidi
Turn Your Vue App into an Offline-ready Progressive Web App
Turn Your Vue App into an Offline-ready Progressive Web App
Imran Alam
Clean Architecture: Theming with Tailwind and CSS Variables
Clean Architecture: Theming with Tailwind and CSS Variables
Emmanuel Onyeyaforo
How to Analyze Large Text Datasets with LangChain and Python
How to Analyze Large Text Datasets with LangChain and Python
Matt Nikonorov
6 Techniques for Conditional Rendering in React, with Examples
6 Techniques for Conditional Rendering in React, with Examples
Yemi Ojedapo
Introducing STRICH: Barcode Scanning for Web Apps
Introducing STRICH: Barcode Scanning for Web Apps
Alex Suzuki
Using Nodemon and Watch in Node.js for Live Restarts
Using Nodemon and Watch in Node.js for Live Restarts
Craig Buckler
Task Automation and Debugging with AI-Powered Tools
Task Automation and Debugging with AI-Powered Tools
Timi Omoyeni
Quick Tip: Understanding React Tooltip
Quick Tip: Understanding React Tooltip
Dianne Pena
12 Outstanding AI Tools that Enhance Efficiency & Productivity
12 Outstanding AI Tools that Enhance Efficiency & Productivity
Ilija Sekulov
React Performance Optimization
React Performance Optimization
Blessing Ene Anyebe
Introducing Chatbots and Large Language Models (LLMs)
Introducing Chatbots and Large Language Models (LLMs)
Timi Omoyeni
Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters
Migrate to Ampere on OCI with Heterogeneous Kubernetes Clusters
Ampere Computing
Scale Your React App with Storybook and Chromatic
Scale Your React App with Storybook and Chromatic
Daine Mawer
10 Tips for Implementing Webflow On-page SEO
10 Tips for Implementing Webflow On-page SEO
Milan Vracar
Create Dynamic Web Experiences with Interactive SVG Animations
Create Dynamic Web Experiences with Interactive SVG Animations
Patricia Egyed
5 React Architecture Best Practices for 2024
5 React Architecture Best Practices for 2024
Sebastian Deutsch
How to Create Animated GIFs from GSAP Animations
How to Create Animated GIFs from GSAP Animations
Paul Scanlon
Aligning Teams for Effective User Onboarding Success
Aligning Teams for Effective User Onboarding Success
Himanshu Sharma
How to use the File System in Node.js
How to use the File System in Node.js
Craig Buckler
Laravel vs CodeIgniter: A Comprehensive Comparison
Laravel vs CodeIgniter: A Comprehensive Comparison
Dianne Pena
Essential Tips and Tricks for Coding HTML Emails
Essential Tips and Tricks for Coding HTML Emails
Rémi Parmentier
How to Create a Sortable and Filterable Table in React
How to Create a Sortable and Filterable Table in React
Ferenc Almasi
WooCommerce vs Wix: Which Is Best for Your Next Online Store
WooCommerce vs Wix: Which Is Best for Your Next Online Store
Priyanka Prajapati
GCC Guide for Ampere Processors
GCC Guide for Ampere Processors
John O’Neill
Navigating Data Management: Warehouses, Lakes and Lakehouses
Navigating Data Management: Warehouses, Lakes and Lakehouses
Leonid Chashnikov
Get the freshest news and resources for developers, designers and digital creators in your inbox each week