Sunday, 12 July 2099

Where to start with a blog

When you first start to blog sometimes it's very tempting to just start to write whatever comes to mind. The problem is of course that if you want to run a successful blog then the key is keyword research.

Keyword research is working out what people type into search engines so that you can tailor your writing to match these keywords. In doing so you stand a much higher chance of ranking your website in all the major search engines. Higher rankings means more visitors.

One of the best tools out there is a product called Long Tail Pro. Long Tail Pro makes researching keywords super easy. The find out more about Long Tail Pro check out this Long Tail Pro Review. I have personally used Long Tail Pro for a number of years and as I result have been able to turn my hobby into a profession.

Friday, 28 August 2020

Demystifying Django’s Magic

Demystifying Django’s Magic

Precious Ndubueze

According to the official documentation,

Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of Web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source.

DjangoProject.com

It is one of Python’s popular framework for building web applications and is most preferred for its scalability in creating a boilerplate with laid down configurations and files. This wraps up the whole goal of Django for developers;

“…building a great application in little time and less worry over basic settings.”

There are basic configurations, files and styling that cuts across all web application, no matter what you’re building. When using Django, these are generated for you automatically when you run certain commands at different points in the development cycle of your application. With this, you’ll have enough time to focus on the core aspect of your developing your application while Django handles the others for you.

It means that there are a lot of things happening underneath the hood. For someone who does not have a full grasp of the moving parts, this can be overwhelming. In this article we’re going to be learning about the following:

We’ll learn how these all fit together and the role they play. It’s important to know that it will not be possible to take a look at everything happening inside of Django. For cases outside the scope of this tutorial, there will be links to point you to resources that will help with that.

For learning purpose, we will be building an e-commerce platform. This is not a full-blown e-commerce site, our application will have only two basic features; creating products and making orders from the admin’s view.

This article will guide you through understanding Django’s pre-built commands, files and basics. It is targeted at developers who have used Django or intend to use it and want to know what happens under the hood. While it is not compulsory that you must have used Django, having experience with the basics of Django before continuing with this article will give you an advantage. You need to have a working knowledge of Python to fully grasp what will be covered in this piece.

Installing Django

If you do not have Django installed already, here are the steps to do that.

First, create a virtual environment, named djangodev. You need this to isolate your Django workspace and its dependent packages.

python3 -m venv ~/.virtualenvs/djangodev

Now to get into your virtual environment, you need to get it activated;

source ~/.virtualenvs/djangodev/bin/activate

If you get any error running with source you can make use of this alternative command,

. ~/.virtualenvs/djangodev/bin/activate

For Windows users, make use of this instead,

...\> %HOMEPATH%\.virtualenvs\djangodev\Scripts\activate.bat

Note: You need to activate the virtual environment anytime you want to use Django.

Now that you’re in your virtual env, install Django:

python -m pip install Django

To check if Django was properly installed, run;

python -m django --version

Shakaboom! Now you’re set for some magic, get your wands ready!

The method of creating files and folders at the go might be simple and straightforward. However, it is not ideal when you have to create a medium or large project and a deadline to beat. We always have a deadline to beat, even for personal projects.

Following this method when creating a new large project, you’ll have to create multiple files and folders and make multiple settings, which could lead to the creation of avoidable bugs and a lot of wasted time. startproject and startapp commands available to us through Django aim to solve this problem. These two commands create files, folders and carry out lots of configuration for you.

Let’s get started by generating a new application using the startproject command.

Scaffolding An Application

We’ll generate our application and take a look at the files that are generated, as well as few commands we’ll use. Run this command in your terminal to get started;

django-admin startproject ecommerce_site

When installing Django, django-admin is added to your path to give it access to perform its actions. It’s Django’s command-line utility for administrative responsibilities. Learn more django-admin uses here; it is a little beyond the scope of this article.

startproject is a Django command that helps generate the project. Here we pass to it the name of our project ecommerce_site. It then goes on to create the project in a directory called ecommerce_site. The directory should look like this,

shows directory after startproject.
Showing folder after running startproject. (Large preview)

We’ll need to navigate into the newly created directory and run the command to generate the app.

cd ecommerce_site
python manage.py startapp trading

startapp is a command executed by manage.py in the project directory, it creates multiple files, and a folder named using the name specified in the command, in this case, what’s specified is trading. The app folder consists of simple files that should be needed for creating features of an application. Now your directory should be looking like this:

shows directory after startapp.
Showing folder after running startapp. (Large preview)

If you’re wondering the difference between a project and an app. A project is a Django web application, it can consist of one or more apps. It’s the folder holding manage.py and the other module that includes the settings.py and other files. An app is a python package that does a certain feature, includes files like models.py, the migration directory and more. You can check out this answer on Stack Overflow for more.

The startproject will create the main project directory, while the startapp will create the app directory. Both are also been passed a name to be used in generation. The startproject is the first command run when creating a new project, while the startapp is run inside the new project directory.

The current layout is a great mapping you can use for whatever application you are building. It’s scalable and consists of files you will be needing. There is a chance to create, rename, edit and move files within the project.

Django’s Configuration

Django provides different settings and configurations for you, after running the two commands in different files, let’s run through the generated files to learn what each does.

settings.py

Most web applications need configurations like; authentication to verify users, permissions to allow certain users with certain abilities and set security standards. All these are needed to give your users the best experience needed. It will take a long time for you as a developer to begin to roll each of these on your own, for every application you work on.

Django provides you with these needed configurations and more — such that you can opt for the ones you want and plug them in. These are done in settings.py, there are already laid settings created to provide basic functionalities for you.

When Django tries to run a project, there are certain variables it looks for. The settings.py is the file holding those variables that lead to other files or information. Django is directed to this file from the manage.py file and takes information or loads other files it is led to from here.

These configurations include:

  • DEBUG
    The DEBUG functionality is set to True to enable reading of errors and debugging code in development, it should be set to False during production (i.e when you are deploying). This setting allows you to be able to debug your code better with the help of Django when it tries running your code.
  • INSTALLED_APPS
    This is a list of all apps performing a certain feature in Django. It comes with some defaults apps like the 'django.contrib.auth' which is used for user authentication, django.contrib.admin' for admin functionality, and 'django.contrib.messages' needed in sending notification or info to users. Any other app you create using the startapp command will have to be in here before it can be run by Django.
  • MIDDLEWARE is a lightweight framework for processing inputs and outputs going through Django requests and responses. Each middleware does a specific function with an app, like the 'django.contrib.auth.middleware.AuthenticationMiddleware' works with the 'django.contrib.sessions' to associate users with requests. You should check out further features of each middleware on the docs.
  • ROOT_URLCONF is a variable to a path where Django looks for your urlpatterns when a request is passed to your Django application. Whenever a request is made in a Django application, Django searches this variable and loads the leading file and loops though the urlpatterns list in search for the matching path.
  • TEMPLATES is a setting to allow rendering of HTML files to represent a view. It communicates with the request, auth and messages apps. The 'BACKEND' value and the 'APP_DIRS' set to True enables Django to search for HTML files within /templates folder. The 'context_processors' in the OPTIONS are callables, that take in the request as an argument and merge it with the context when a template is been rendered, these callables work to help with debugging, authentication, and handling of requests generally.
  • WSGI_APPLICATION is a path leading to the application variable in wsgi.py file.
  • DATABASE is a dictionary that holds access to an external database(or internal like in the case of the default sqlite) like PostgresSQL, MySQL and MongoDB. Here is an example of a Postgres database I will be using for our example:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'db_name',
        'USER': 'db_user',
        'PASSWORD': 'db_password',
        'HOST': 'localhost',
        'PORT': '',
    }
}

You can decide to use the default sqlite database, this doesn’t work great for production. You can set up a Postgres database like above, you will have to create the database first and pass the user, password with write permission to the database.

Note: For the purpose of this tutorial you can use the default sqlite database set already. The above is a demonstration on how you can set SQL and NO-SQL database connection in Django.

  • AUTH_PASSWORD_VALIDATORS these are functions that are called for password validations. They are called when creating users (and admins too) records, resetting and changing passwords. You can learn more about them from the official documentation.

More documentation on settings can be found here.

manage.py

Most web projects need an entry point where commands start from. An entry point acting as a gateway into the application. In every Django project, it is usually the manage.py file.

This file is needed as a starting point in your application. From here, all commands are run and everything starts up here.

manage.py does the same function as django-admin. It also tells Django the location for the configurations you have in your application. This is set by default and does not need to be changed.

It uses def main() function to handle the default settings module to our settings.py file. It tries to import the execute function, and if it runs into error it throws the ImportError. Otherwise, it takes in whatever argument is passed by the sys.argv from the command line and executes.

sys.argv is a list that takes in the command passed in via the terminal. When we run python manage.py runserver in the command line, sys.argv gets set to ["manage.py", "runserver"] and this is passed to the execute() function.

Arguments like python manage.py startapp trading or python manage.py makemigrations are set to [ "manage.py", "startapp", "trading"] and ["manage.py", "makemigrations"] respectively for execution.

The if statement is set to run if the command given set to manage.py.

Aside from running django-admin functions, you will be using it in running server, handle migrations, and other commands your project will be using. You will also need it when deploying, testing and debugging your projects.

Model Layout

Django provides a simple modelling layout for you. You configure your models in the models.py file in the trading directory. Your classes (or models) are layouts your database tables will follow.

You define your classes based on the data types you want to get from the user(or the admin) for each table. Our models create a migration file that works with the DATABASE variable in the settings.py.

Let’s create two models we’ll need, for products and orders:

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=50)
    image = models.ImageField(upload_to='products', default='python.png')
    price = models.IntegerField()
    description = models.TextField()

    def __str__(self):
        return self.name

class Order(models.Model):
    product =  models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.IntegerField()
    date = models.DateField(auto_now_add=True)
    user = models.CharField(max_length=50)

    def __str__(self):
        return self.user

The product model has a name, price, description and an image (which when saved will be uploaded to a products folder. This gets created if it folder doesn’t exist) columns. The order has a product (linked to the products table), the quantity, date and user columns.

With this information, Django creates a database schema for the app. Also, creates a Python database-access API for accessing Product and Order objects. Django has a built migration tool so you don’t have to use external packages for migrations.

Next step is to run the migration command and migrate to the database. But before we do that, we have to register trading as an app in our project directory.

First off, we have to configure the trading directory as an app in Django. Django has that done for you in the app.py file. This file registers trading as an app and will be further used in the settings.py file.

Now, in settings.py add trading in INSTALLED_APP. It should look like this:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'trading.apps.TradingConf',
]

On the terminal, run:

$ python manage.py makemigrations trading
$ python manage.py migrate

Note: Your virtual environment must be activated and you should be inside the project directory.

python manage.py makemigrations trading takes note of changes made in the trading module and creates a file in the migration folder of changes in models.py and python manage.py migrate then updates the changes.

You can find the generated migration file from the python manage.py makemigrations trading command in the migration directory named 0001_initial.py. You can see the classes and columns as commands for creation inside the file. As more changes in models.py are made, more files will be generated here.

Admin Features

In our current application, we’ll need admin features to manage the products and orders that will be created in the application. Django provides us with an in-built admin functionality already at our disposal. The admin app(feature) has also been registered in our INSTALLED_APP list; 'django.contrib.admin'.

Also, the URL for the admin has also been registered in the urlpatterns list our URL configuration file urls.py; path('admin/', admin.site.urls),. The admin.py file makes it possible for you to register models and the CRUD actions that are to be performed on the models.

To set up the admin, run this on the terminal:

$ python manage.py createsuperuser

You’ll be prompted to enter a username, email and password. After that, you’ve successfully created an admin. To get started with the admin functionality, run the server:

$ python manage.py runserver

Visiting http://127.0.0.1:8000/admin/ will lead to a login session, when you log in (with username and password you created) you are directed to admin dashboard:

this shows admin dashboard.
Admin dashboard provided by Django. (Large preview)

The groups and users are default configurations that allow admin to access user management and permission. Now let’s register our models.

In the admin.py, add the following lines:

from django.contrib import admin

# Register your models here.
from .models import Product, Order

admin.site.register(Product)
admin.site.register(Order)

from django.contrib import admin imports the admin functionality from Django, and then we imported the two classes from our models.py and registered them so an admin can perform CRUD actions on products and order from the dashboard.

After registering the models, your dashboard should look like this:

showing admin dashboard with products and order model.
Product and Order model on Admin Dashboard. (Large preview)

Adding products:

this shows admin admin adding a product to the site.
Admin adding a product(shoe) to site. (Large preview)

Making orders from admin dashboard:

Image showing admin making orders.
Admin adding/making orders. (Large preview)

Easy Routing

Every site needs route or URLs leading to specific pages with certain information for the end-user. Collections of similar information or application are accessed in a particular route. There is a need for grouping routes together for accessibility and communication within files. Django has that done for you in the urls.py file.

The urls.py is a file leading from the ROOT_CONF variable in the settings.py. This is where our main URL configuration is done. When we create views in different files or folders, or even in the urls.py file, they have to be configured in the urlpatterns list.

Django expects a list named urlpatterns in the file. You can change the file in the ROOT_CONF variable to any other file which you placed the urlpatterns list.

urlpatterns = [
    path('admin/', admin.site.urls),
]

The list consists of objects that are instances of path or re-path. Each instance has two compulsory parameters, the pattern 'admin/', and a view or URL file, admin.site.urls.

The instances could also be leading to another file with more URL configurations. This is done for readability.

views.py

An important need for a backend application is the views which each route maps to. In Django, you write your function or class based views for an app in the views.py file. A view is a class or function that processes a request and sends back a response to your user.

Edit your views.py file to this:

from django.http import HttpResponse

def home(request):
    return HttpResponse("This is a shopping site for products")

def order(request):
    return HttpResponse("Hello, welcome to our store, browse to our products and order!")

Here we imported HTTPResponse to use it in defining two views (function views) to return sentence when called on. def home should be called when you visit the primary address and def order when you access the order URL.

After creating our views we need to assign it to different routes(or urlpatterns). That can be done in several ways, we can create a urlpatterns list in the same file, or we could import trading.views into ecommerce_site.urls file and create the path.

The preferred way to do so is creating a sub URL configuration file (inside trading), and including it in ecommerce_site.urls. Create a urls.py file in the trading directory. Your directory should look like:

trading/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
        0001_initial.py
    models.py
    tests.py
    urls.py
    views.py

Add the following code to your new file (urls.py)

from django.urls import path

from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('order/', views.order, name='order'),
]

Let’s register the trading URL configuration file(urls.py) in the project URLs configuration file,

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('trading.urls'))
]

To be able to access the urlpatterns we will use the include class from django.urls in line 2. Then chose a pattern and attached the urls.py file in the trading directory.

What we did here was to import the path class from django, and the views.py file. Then our list consists of two path instances for each view. So def home is called on http://127.0.0.1:8000/.

image showing when you visit the site home.
Site when you visit home page. (Large preview)

And def order is called on http://127.0.0.1:8000/order/.

shows site when you visit order URL.
Order URL visited. (Large preview)

Note: The process of running startproject and startapp is not compulsory but highly encouraged by Django. And you can create/move files and folders after running each command to your working convenience.

Dependency Tree

Here is the process in which Django processes requests from URLs coming:

  1. Django searches for the root location (path) for your URLs in the ROOT_CONF variable.
  2. Django loads the python file given in the path provided. And locates the urlpatterns variable, this is a list containing all instances of django.urls.path() and/or django.urls.re_path().
  3. In the list, Django goes in order and looks for a matching URL.
  4. Python, imports and calls the view (either function-based or class-based view). Which is furthered passed with the HTTP request.
  5. The view processes the request and information passed and either returns a message/template or redirects to another view.
  6. If no URL pattern matches, or if an exception is raised during any point in this process, Django invokes an appropriate error-handling view.
Tree showing how Django handles requests.
Django request handling. (Large preview)

Conclusion

We have learnt of the possibility of creating files for Django without the command line. Also we have learnt the advantages and the building block of a Django Project. Django is an amazing tool in building backend projects with the goal to create simplicity.

You can check out the code for this tutorial on GitHub.

Resources

Smashing Editorial
(ks, ra, yk, il)

from Tumblr https://ift.tt/2QKUlPn

Thursday, 27 August 2020

SmashingConf Live! Is A Wrap

SmashingConf Live! Is A Wrap

Rachel Andrew

Last week, we ran our very first SmashingConf Live! event, the first in a series of online events taking us through to the end of 2020. We had an amazing two days and we hope that all of our speakers and attendees did too. In this post, I’ll round up some of the key moments and feedback we’ve had.

A Team Spread Around The World

Here at Smashing, we take remote, distributed working to the extreme, and are very used to dealing with all of our different timezones. However, the conferences are the one time when most of us are together in one place. With all of us in our home locations and timezones, things were very different this time. We shared pictures of our setups in the Slack for the event, and lots of attendees joined in the fun and showed us how they were attending the conference themselves.

Some of the desks that brought you SmashingConf Live!
Top row (left to right): Amanda, Charis and Jarijn, Rachel. Bottom row (left to right): Phil, Vitaly, Tobi

It takes a lot of people to bring you an online multi-track conference, so the full team taking care of everything and everyone behind the scenes on the day were:

  • Andrea de Souza (Volunteer): Canada
  • Amanda Annandale (Head of Events): Bristol, UK
  • Bash Choudhry (Volunteer): USA
  • Bethany Andrew (Event Assistant): London, UK
  • Charis Rooda (Marketing Coordinator): Hong Kong
  • Esther Fernandez (Partnerships Coordinator): Barcelona, Spain
  • Jan Constantin (Smashing Team): Freiburg, Germany
  • Jarijn Nijkamp (Membership Lead): Hong Kong
  • Marc Thiele (Board Member): Dusseldorf, Germany
  • Mariona Ciller (Partnerships Manager): Barcelona, Spain
  • Rachel Andrew (Editor-in-Chief): Bristol, UK
  • Raffaella Isidori (Volunteer): Milan, Italy
  • Ricardo Gimenes (Illustrator): Malmö, Sweden
  • Vitaly Friedman (Co-Founder): Dusseldorf, Germany

Our Conference Platform

When selecting a conference platform it was important to us to have something that would enable the fun and interactivity of an in-person SmashingConf. We wanted to have sidetracks, games, places to ask questions of our speakers, all along with main stage content. While we use Zoom for workshops, we didn’t feel that asking you all to sit through two days of Zoom meetings would be very Smashing at all.

The platform mid-session
We’re running our conferences on Hopin, a friendly, inclusive platform, with Smashing branding and plenty of cats. With interactive, live sessions and live captioning. Watch a video preview. (Large preview)

Amanda and the rest of the team looked at a number of options and we ultimately chose to use Hopin. We trialed the platform for our Smashing Meets events, but this was the first time we would be running at such a scale. Everything worked really well, and speakers and attendees seemed to like the setup. As a speaker, I found it felt far more interactive than the usual online conference solutions, and less like I was presenting to my office wall!

A Lot Of Fun, And A Lot Of Learning

With multiple sessions happening at once we had a lot of speakers sharing their knowledge with us. As with our in-person events, everyone created shared Google Docs of takeaways over the two days — Day One, Day Two. MC Phil Hawksworth kept everything on track on the main stage.

Some amazing sketchnotes were created by Ximena which give you a snapshot of the key takeaways from many of the talks and sessions.

We even had our conference DJ Tobi playing some tunes between the mainstage talks — just like at our in-person events.

Badges

We felt that a virtual conference should have badges too. So, for SmashingConf Live we had badges featuring a variety of cats. Attendees tried to find all of the different cats — all 96 of them!

A preview of some of the badges used at SmashingConf Live! of Topple the Cat in a variety of disguises
Friendly SmashingConf badges for cat collectors! Every attendee gets their own badge and can trade them when meeting new people. Illustrated by our cherished illustrator, Ricardo Gimenes.

It really did feel like an event, rather than a webinar, and it was great to see so many people — and to meet their cats! That’s something we don’t get to do at our usual events.

Wishing You Were There?

If you wish you could have joined us then you have three more chances for some SmashingConf online fun! We’ve taken all of our 2020 events online, which means that between now and the end of the year you have three to choose from.

SmashingConf Freiburg Online (Sep 7–8)

SmashingConf Freiburg Online 2020The SmashingConf Freiburg is moving online on the original dates: September 7th–8th. One track, two days and 13 speakers, with all of the actionable insights you expect from SmashingConf. We’ll be running the event tied to the timezone in Germany — making this a great event for Europeans. Check out the schedule, and buy tickets here.

SmashingConf Austin/NY Online (Oct 13–14)

SmashingConf Austin Online 2020We have combined the programming for New York and Austin as these two events were so close together and similar to each other. We’ll be running this event in Central time, just as if we were all in Austin. Check out the schedule, and buy tickets here. We’d love to see you in October!

SmashingConf SF Online (Nov 10–11)

SmashingConf San Francisco Online 2020In PST, join us for a SmashingConf San Francisco on November 10th–11th. The schedule and tickets are online for you to take a look at. We’ll be sure to have a great celebration for our final event of 2020!

Can’t wait to virtually see you there!

Smashing Editorial
(il)

from Tumblr https://ift.tt/34CV4df

Autonomy Online: A Case For The IndieWeb

Autonomy Online: A Case For The IndieWeb

Ana Rodrigues

Web 2.0 celebrated the idea of everyone being able to contribute to the web regardless of their technical skill and knowledge. Its major features include self-publishing platforms, social networking websites, “tagging”, “liking”, and bookmarking.

Many individuals and companies began creating these platforms so that anyone could contribute to the Web, and not just people who had the privilege to learn to code. In fact, to recognize our contributions to the web, “we” were Time magazine’s Person of the Year in 2006.

Cover of TIME magazine presenting the person of the year as “You”
Simpler times. (Image source: TIME USA)(Large preview)

Nowadays whether you’re consuming or sharing content on the web, it is likely to be via a big website. Twitter, Youtube, or a Facebook-owned service are popular examples. Whilst this gives us the advantage of being able to participate in a larger conversation at almost no monetary cost, there is also the downside of potentially losing all our content if a company closes, as has happened in the past.

In the past few years, I began to notice I was losing control of online life. What follows is a case for why the IndieWeb is a great opportunity for personal development, taking ownership of your content, and learning by building personal websites.

Learning On The “Corporate Web”

After years of seemingly endless growth and acquisitions, we have ended up with a handful of big websites that control our whole online identity, data, and privacy. The main mode of participation on the web, for many people, is through major web corporations that need to own data to sell to advertisers. This has become what many people call the corporate web, where users are the product and engagement is king.

The corporate web allows our family and friends and anyone with lower-tech skills to develop their web presence and have access to the digital world. Anyone can sign up to a handful of social media websites and see and interact with what people are sharing, especially at times of physical distance.

However, nothing online is truly free. Many of these websites rely on advertising revenue for income. Consequently, these websites need to change a lot to keep the engagement up so that the users don’t leave. This is not always in the best interest of the people who use it.

Exploring The Corporate Web

Social media websites allowed me to find and connect with industry peers. When I first started working as a web developer, one of the first things I did was to sign up to popular social media websites and subscribe to updates of people who also worked in the industry. Some of them I personally knew but others were recommended to me by the algorithm itself and throughout the years I would adjust my subscription list.

Regardless if it was shared via an article or a social media post, lots of things I learned were because someone wrote about it and I was able to read it for free. And when I engaged I was potentially building a professional network from my home. All this for free! How cool is that?

However, as time went by I began to lose control of what I wanted to see and when. In order to increase engagement, many social media websites began to use algorithms to dictate what they thought I wanted to see and they also started to show me things I didn’t actually subscribe to. While now I can rationalize this, at the time I was just entering the industry so I thought I was the one who needed to catch up on everything.

Social media doesn’t take breaks, but at some point in my life, I needed a break from it, which made me realize that my personal development was going to suffer. I began to experience strange anxiety of missing out because I also knew that I couldn’t scroll through my whole timeline to see everything that was shared while I was offline. It became really hard to search and find anything I had a glimpse of some weeks ago.

Making Stuff On The Corporate Web

So far I’ve been talking about consuming content, but I also wanted to share. While one may always be keen to continuously improve their craft, I was feeling an intense pressure to follow trends and build things using the latest shiny thing for the sake of being employable and impress people I’ve never met. Even sharing stuff that immediately reaches many people, would come with its own limitations as I would be using a platform not built by me.

Most importantly, it was doing a disservice to a whole group of people who can’t even join certain corporate websites because of the geopolitical restrictions of where they live. There is always the possibility of having your account (and your content) removed at any time if the corporation decides you’re breaking a rule.

Whether it would be accessibility, character limits, moderation, or even the option of not receiving feedback, many times it felt unwelcoming and intimidating. Often I felt like an impostor and as if I was running a never-ending marathon.

I began to ask myself, “who am I doing this for?” Is the “corporate web” bringing to the surface “corporate values” that get in the way of personal development?

What Is The IndieWeb?

Do you ever wonder what would happen if your social identity was stolen or reassigned by the corporation to someone else? Or, as I mentioned before, if these big websites close down, and all the content you created is gone? Corporate websites control who, when, if, and where the content created by its users can be accessed.

I didn’t wonder about these things until 2017. It was in ViewSource that I saw a talk by Jeremy Keith that introduced me to the IndieWeb called “Building blocks of the IndieWeb”. The IndieWeb is a community of individual personal websites connected by principles that lead to an alternative to the corporate web.

A photo of Ana Rodrigues at a previous IndieWebCamp working on their blog with other participants in the background
(Large preview)

IndieWebCamps are an opportunity to work on my personal website blog and to ask for help. Photograph by Julie Anne Noyingurce.

The IndieWeb community is about creating or improving your personal website while also helping others to build theirs, either by documenting or creating tools. To help create an alternative to the corporate web, members of the IndieWeb community have built tools that anyone can use on their personal website that helps create the interaction and community building between personal websites.

One of the principles of the IndieWeb is that you own your content and that principle alone solves one of the main problems I mentioned above. Other tenets include:

  • Ownership of your identity.
    I didn’t realize until this point how much it made sense to have a “one true version” of yourself online instead of multiple accounts spread on many websites;
  • Using tools you’ve built yourself.
    At some point, I thought the worth of the things I built were related to the number of people who can use it. IndieWeb promotes the idea of building something for me and actively using it;
  • Documenting your journey.
    I used to be an active blogger and I had stopped when I began to work as a developer. At the time I was afraid of writing beginner-friendly content and this principle helped me embrace every bit that I wanted to share;
  • Contributing to open-source.
    Before joining the IndieWeb community I felt that I had nothing to contribute anywhere. For the first time in my life, I began to edit wiki pages, create issues in GitHub, organize meetups, and give talks. There are all examples of not only contributing to open source but also contributing to a community;

As I learned more about the IndieWeb, I found support and encouragement, especially as I read about the principles of plurality and using what one makes. That’s when I found a sense of freedom and permission to build something for myself — even if it only serves me and even if it has already been built by someone else too.

Creating A Personal Website And Learning From It

How many times does one have the opportunity to build a website from scratch at work? When you have a job in a really big company it is an unbelievably bureaucratic process to change anything we consider “base code”, especially how to choose a particular flavor of framework. I couldn’t believe I was so excited to write every cool thing inside an <head> tag! I’ve lost count of how many “Hello worlds” I’ve created and binned in my lifetime when I had a real “product” to build: me.

When I began my quest to have an IndieWeb blog I chose to build almost everything from scratch but it isn’t necessarily the only option. If someone wants a full-fledged Indie Website without coding, there are services that support IndieWeb (Micro.blog for example) as well as some known CMS such as WordPress.

At the time, on my daily job, I was mostly writing JavaScript so I felt that this was an opportunity to do something a little bit different. I started to follow a couple of IndieWeb websites that were using static website generators and right now I am using Eleventy. My decision was based on visiting IndieWeb blogs that I liked that were also using this particular static website generator and looking up their code in Github. There isn’t a right or wrong answer here.

Building my personal website and blog from scratch forced me to refresh my HTML, accessibility, and CSS knowledge (with the bonus of no one telling me I wasn’t allowed to use the latest CSS cool things). As I began to IndieWebify myself, I learned so many new things! For example:

  • Jamstack (a stack that generates static code that doesn’t depend on a web server);
  • Microformats (extensions to HTML represent commonly published things like people, locations, blog posts and more. They provide an API to the information on your website);
  • Micropub (which is a standard API for creating content on a website);
  • Microsub (provides a standardized way for reader apps to interact with feeds);
  • Webmentions (a standard that allows you to notify another site that you’ve interacted with them);
  • Web Sign In / IndieAuth (a federated login protocol for Web sign-in that allows you to use your own domain to sign in to other sites and services);

Owning my content made me want to connect to APIs of existing “corporate websites” and also, where possible, automating the process of syndicating to them when I share something (also known as POSSE).

Now, the IndieWeb doesn’t require one to automate this process. You’re already adhering to the idea by publishing on your own domain and sharing the link to the original manually, for example, on Twitter! But the possibility to automate this process exists too and it is a great experiment. Similar to “what should you use to build your own website”, there is no right answer — as long as it works.

Exploring how this could work, led me to experiment using services like IFTTT to connect my RSS feed to my Twitter account. Other times, it made me navigate for hours in GitHub to see how other people built their own services to automatically publish on social media from their websites.

There are still many things I want to build and learn. For example, when I was able to bring my content from a corporate website into my server I grew the desire to optimize that output, so I began to make changes on my deployment build. This is something that would likely not happen at work or maybe I wouldn’t find the inspiration or need to build for anything else.

A flow showing some examples of types of IndieWeb posts and how the interactions that an article has on social media and other blogs can appear on the original blog post
(Large preview)

A snapshot of POSSE and IndieWeb posts. The flow begins on a personal website, syndicated to social media where interactions are backfeed to the original blog post. The original blog post can also receive and show interactions from other blogs via Webmentions.

Building my personal website and blog into my playground has been the place where I’ve learned the most. It is where I can experiment, write, build, try, and learn without censorship or limitations.

An unexpected consequence is that I felt more confident in writing on my blog compared to social media. Social media feels like a tiny stage with a massive audience compared to my blog that allows me to have a massive stage production but only perform to those who want to be there. I have control of who can interact with it (by not having comments available) and plenty of room to express myself without having to censor what I do.

So I also began to blog more and after I blog, I share on social media because we can then have the best of both worlds. My content may be buried by an algorithm in social media but that can never happen on my own personal website.

With Webmentions and publisher services, I can see what interactions my blog posts had on some social media websites. In order to receive Webmentions, you must have a Webmention endpoint. Luckily, lots of people have shared ways of how you can build one. While I still haven’t dared to create mine from scratch, I’ve been using a service called Webmentio.io to create and host my endpoint so that I can receive Webmentions. As for sending them, sometimes I do it manually using Telegraph but I’ve recently had a go at automating that process as well using Webmention.app.

Other great services, like Bridgy, send Webmentions for comments/replies, likes, and reposts on some social media websites like Twitter which also helps the process of “backfeeding” the interactions back to the original post. I recommend experimenting with existing services as it may be a bit overwhelming to build everything from scratch.

By slowly creating an alternative to the corporate web, one can have one place to document and share — a fixed place that anyone at any time can go back to whenever they need. All this while keeping the door open for all the good things that corporate web offers with the bonus of a very personalized touch.

My current website is a constant work in progress but I have a lot of joy when I scroll through my archives. I am always excited to improve it and try new things, I can break it and fix it at my own pace and I don’t have a deadline on it. It is my safe space.

Where To Begin

The IndieWeb community is open for everyone. You can start today by buying your domain name and building a homepage. With this single step alone, you will already have one place that anyone in the world can visit to be in touch with you.

Ever since joining the community, I participated and organized events, met great creators, and challenged myself with not only code but also in topics like privacy and ethics. I discovered new and fantastic personal websites and blogs that I probably wouldn’t find via social media and felt less alone in this constant journey of learning in our industry.

If you relate to anything I’ve said above and would like to get started there is a page that goes into more detail. We have an online chat room and weekly community meet-ups where you can connect with other members of the IndieWeb community who are happy to share their experiences and answer questions.

Dive straight into some welcoming guides built by community members (that anyone can contribute to) like IndieWebify.me and the IndieWeb Guides. I also recommend looking out for blog posts with IndieWeb introductions on personal websites as they all have different voices that may match your way of learning.

The wonderful thing about the IndieWeb community is that you’re welcome to do what works for you. It isn’t about following trends and there isn’t only one ‘right way’ to build things — just your way.

Smashing Editorial
(fb, ra, il)

from Tumblr https://ift.tt/3b2X3Jd

Wednesday, 26 August 2020

Using Mobx As A State Manager In React Native Applications

Using Mobx As A State Manager In React Native Applications

Fortune Ikechi

State management is an integral part of developing JavaScript applications especially React and React Native applications. In this tutorial, we are going to learn how to use the MobX library for state management; understand the core concepts, some use cases and build a simple example.

Note: Basic knowledge of Javascript and React Native will be of great benefit as you work through this tutorial.

Using MobX In React Applications

State is the data that your component(s) is working with — it holds the data that a component requires and it dictates what a component renders. State management is the process of managing how the state gets updated and passed from one component to another. Monitoring and working with data in an application can be difficult and that’s the need for state management libraries. Handling all the data for your application can be a little daunting especially when your application grows in size and complexity, building your own state management tool is not just time-consuming but difficult, This is why you might want to use a state management library.

However, it is important to know that state isn’t the only data that a component renders, components can also render props passed down to it.

Options For State Management

State management libraries for React Native applications include; React Context API, Redux, MobX and Unstated Next.

Although these state managers each have their advantages and disadvantages, I personally recommend MobX because of its simplicity, minimal boilerplate code — it doesn’t require you change your code, this is because in its core, MobX is and looks like JavaScript; you don’t need a change of architecture to support it (unlike Redux and to a lesser extent Context).

In fact it’s such an invisible abstraction that in many cases if you take out all of the MobX code — the @observable, @computed, @action and observer decorators, your code will work exactly the same (though it’ll have some performance issues) and it’s not limited to a global state. These are some reasons to go forward with MobX as a state manager of choice for your React Native applications.

Although it’s also important to note some issues with using MobX as a state manager, some of which include its avoidance of rules on how to implement it and MobX can be difficult to debug especially when you change state directly in a component without using the @actions parameter.

What Is MobX?

According to the official documentation, MobX is a battle-tested library that makes state management simple and scalable by transparently applying functional reactive programming. MobX treats your application like a spreadsheet. The logic is that Anything that can be derived from the application state, should be done automatically.

MobX state architecture
MobX state architecture. (Large preview)

Core Principles And Concept Of MobX

MobX differentiates itself from other state managers with the following concepts.

1. State

State is the data your application holds — it’s roughly the entire contents of its memory. This also applies to your components.

2. Derivations

In MobX, anything that can be derived from the state without interactions is a derivation. Examples of derivations include:

  • User interface,
  • Backend add-ons such as changes to a server.

MobX has two mains types of derivations:

  • Computed values
    Computed values are mostly values that can be derived from a current state using pure functions.
  • Reactions
    Reactions in derivations are side effects that happen as a results of changes in your application state. They are similar to a computed value, but instead of producing a new value, a reaction produces a side effect for things like printing to the console, making network requests, incrementally updating the React component tree to patch the DOM, and so on.

A golden rule when using MobX is that when creating a value based on the current state, use a computed value.

3. Actions

Unlike derivations, actions are code that cause changes to an application state — code that changes the state. They are anything that modifies the state. With MobX you can make it explicit in your code, Actions are mostly user events such as inputs, backend data pushes or even scheduled events.

To better understand Actions, let’s look at an example from the MobX documentation.

class Ticker {
    @observable tick = 0

    @action
    increment() {
        this.tick++ // 'this' will always be correct
    }
}

const ticker = new Ticker()
setInterval(ticker.increment, 1000)

Here, we set an @observable tick with an initial value of 0. Next, we created a function increment that is also an action that updates the initial value once a tick is made every second.

Observables In MobX

Observables or observable values in MobX are mostly JavaScript primitives, plain objects, classes, arrays and maps. They’re mostly used by first declaring an observable and adding a value to it and then calling it by adding an @observable as shown below:

  observable(value)
 @observable classProperty = value

Store Architecture Approach In MobX

MobX principal architecture includes parts and ideas such as services, store, view models and containers — some of which are explained below.

  • Service
    This is usually a function called from a container; they can be used to get data from APIs and be added to the store.
  • Store
    As the name implies, this is the central place of the state used by an application. Usually in MobX, these include the observables, variables, actions and computed properties.
  • Container
    This calls service and puts data from View Model to View Component as React props (should be marked with @observer decorator).

MobX In React And Native Applications

For learning purposes, in this tutorial, we are going to build a simple list app that will allow a user to add, view, and delete list items. We will be using MobX as a state manager in this application to add lists, update and delete them from the app state. However, it’s important to note that you already understand the basic concepts of JavaScript and React.

Without further ado, let’s start!

Setting Up Your Environment

Now that we know how what MobX is and how it works, let me walk you through setting up your project.

First, let’s create a project with the following, write the following code on your terminal to initialise a project:

npx create-react-app listapp

The above code will create a bare React application using the create-react-app package. Move into the project directory:

cd listapp

For this app, we will need three components:

  • TitleInput
    This will contain the title for our project and an input form for adding lists.
  • List
    This will be an input form that would allow a user to add a list. It will have an add button to add our list items.
  • ListsDisplay
    This component will display all of the user list items and also a delete button that’s automatically generated when a user adds a list item.

We will use a Store.js to contain the app state and methods to modify it similar to Redux. Let’s outline what they will be used for.

  • mobx
    This is the state manager we will be using for this project.
  • mobx-react
    This is the official React bindings for MobX.
  • bootstrap
    We will be using bootstrap version 4.5 to style our project.
  • uuid
    This is used to automatically create keys for deleting lists.

Having done that, let’s go ahead and install these packages. I will be installing them with an npm alternative done in yarn:

yarn add mobx mobx-react bootstrap@4.5.0 uuid

Once the packages are installed, we will start our app in development mode by running the code below in our terminal:

yarn start

Setting Up Our App Store

Let’s create a store for our project. First, create a file in the root directory of our project called ListStore, this will be the central location of our app state.

For this app, we will need to create a ListStore in order not to repeat ourselves when we use it in other app components.

/*** src/Store.js ***/

import { observable, action, computed } from "mobx";
import { v4 } from "uuid";

export class List {
  @observable value
  @observable done

  constructor (value) {
    this.id = v4()
    this.value = value
  }
}

export class ListStore {
  @observable lists = []
  @observable filter = ""
  @action addList = (value) => {
    this.lists.push(new List(value))
  }
 
  @action deleteList = (list) => {
    this.lists = this.lists.filter(t => t !== list)
  }
  @computed get filteredLists () {
    const matchCase = new RegExp(this.filter, "i")
    return this.lists.filter(list=> !this.filter || matchCase.test(list.value))
  }
}

In the code above, we imported three functions from mobx.

  • observable
    This holds a variable which can be updated in the event of a change in state.
  • action
    Used to modify the application state.
  • computed
    Values that can be derived from the existing state or other computed values, it changes after a state gets modified.

The class List has two object values which are done and value which will hold the initial state of the app and the modification in the case of changes.

We want our new list to automatically create a key so that we can automatically get a delete button once a list is created, Here uuid is used to automatically create keys in our application.

Next, we added an addList function that will add lists when clicked by using the .push() method to push the list in the array we already created in the @observable lists array.

The deleteList function accepts List as a property which is supposed to be the item the user wants to remove. Then we set the value of this.Lists to a new array after we have removed the selected item.

Both addLists and deleteList are actions because they modify the state of our app when changes are made.

Initializing The MobX Store

Next on our list is to import our store in our App.js and use it in our project.

import React from 'react';
import Navbar from "./components/navbar";
import ListDisplay from "./components/ListDisplay";
import {ListStore} from './ListStore';
function App() {
  const store = new ListStore()
  return (
    <div>
      <Navbar store={store}/>
      <ListDisplay store={store}/>
    </div>
  );
}
export default App;

Here we imported the TitleInput and ListDisplay components. Then we initialized the store in our App.js in order to be able to pass it as props to the TitleInput and ListDisplay components.

Normally this will throw an error because we’ve not worked on the other components, so let’s do that. Let’s build out the ListDisplay component.

ListDisplay

This component displays all of our added lists and also automatically generates a delete button once a new list is added.

import React from 'react'

import List from "./List";
import { observer } from 'mobx-react';

function ListDisplay(props) {
  const { deleteList, filteredLists } = props.store

  return (
    <div>
        <div className="container">
          {filteredLists.map(list => (
            <List key={list.id} 
              list={list}  
                deleteList={deleteList} 
            />
          ))}
        </div>
    </div>
  )
}
export default observer(ListDisplay)

For this component, we created a function ListDisplay and made it an observer, we also destructure the list and deletelist functions from the store, by doing this, we made it easier to pass then as object props.

Next, we map through filteredLists to return the lists, which we then use in building the individual list by passing the returned item as props to the List component.

Once done, our component should look like this with lists added:

The list display component
Lists displayed by `ListDisplay` component. (Large preview)

Next is to add a List and TitleInput components.

List Component

Just like our other components, our List component will export the list as an observer in order to help the store watch it for changes.

import React from 'react'
import { observer } from 'mobx-react'
function List(props) {
  return (
    <div className="card">
      <div className="card-body">
          <div className="d-flex justify-content-between 
          align-items-center">
            <p className={`title ${props.list.done 
              ? "text-secondary" : ""}`}>
              {props.list.value}
              </p>
            <div>
            <button 
              onClick={props.deleteList.bind(this, props.list)} 
                className="btn btn-danger 
                  font-weight-bold py-2 px-5 ml-2">
                Delete
              </button>
            </div>
          </div>
      </div>
    </div>
  )
}
export default observer(List)

I used the bootstrap to create cards in the first set of divs and also align the delete icon to move towards the right-hand side of the app. First, we created a card component to handle our list and then we created a button tag for the delete button that will accept two objects of this and pass a prop to the list, this will on click, will remove the selected list item from the lists in the page.

The list component
A single list component with the delete button. (Large preview)

Next is to our TitleInput which will contain our input form for adding lists and the title for the project.

TitleInput

Similar to our other projects, we will be adding an @observer function so that the component will be able to accept props from the app Store.


import React, { useState } from 'react'
import { observer } from 'mobx-react'
function Navbar(props) {
  const [value, setValue] = useState("")
  
  const {addList} = props.store
  const prepareAddList = (e) => {
    e.preventDefault()
    addList(value)
    setValue("")
  }
  return (
    <div className="container mt-3">
      <h1 className="title">List App</h1>
      <form onSubmit={prepareAddList} className="form-group">
          <div className="row ml-lg-2">
            <input className="form-control-lg col-12 col-lg-9 
              col-sm-12 mr-3 border border-secondary" 
                value={value} type="text" onChange={(e) => 
                  setValue(e.target.value)} placeholder="Enter list"
                  />
                   <button className="col-lg-2 col-5 col-sm-5 mt-2 
                  mt-lg-0 mt-sm-2 btn btn-lg btn-success 
                font-weight-bold">
              Add to List
            </button>
          </div>
      </form>
     </div>
  )
}
export default observer(Navbar)

First, we initialized an initial state. Using React Hooks, we added an initial state called values which we set to an empty string. We use this to hold the value of what is entered in the input field. To know more about React Hooks, you can check out this article by David Abiodun.

Then we called an object for adding lists to the store addList and passed it as props from the app store.

Next we created a function preparedAddList to accept an event object for the input forms, we also added a button for adding the lists manually on click.

Almost done, we need to restart our project server by running:

yarn start

And our TitleInput should look like this:

A title input
Title and input component. (Large preview)

We are now done with all of our app components, so let’s assemble it in our App.js. To do that, we need to import our components titleInput and ListDisplay. We also need to import our store from the Store component.

In order for MobX to work in our App, we need to pass the MobX store as props in our App and individual components so that they get the properties and functions in the store.

import React from 'react';
import Navbar from "./components/navbar";
import ListDisplay from "./components/ListDisplay";
import {ListStore} from './ListStore';
function App() {
  const store = new ListStore()
  return (
    <div>
      <Navbar store={store}/>
      <ListDisplay store={store}/>
    </div>
  );
}
export default App;

Our app should look like this when completed:

Completed list app
(Large preview)

Conclusion

MobX is a great state manager especially for React-based applications, building our list app, we’ve learned the basic concepts of MobX, state, derivations, and actions. A working version of this app can be found here:

You can take this further by using MobX in the next application you build that involves the management of state. I’d love to see what new things you come up with. You can read more on MobX and state management applications in the references below.

Resources And References

Smashing Editorial
(ks, ra, yk, il)

from Tumblr https://ift.tt/2QqdKET