loading...

Rocket — becoming a known developer… and building an app to help make it happen — Part 5

mattkingshott profile image Matt Kingshott 👨🏻‍💻 Originally published at itnext.io on ・5 min read

Rocket — becoming a known (Laravel) developer… and building an application to help make it happen — Part 5

In this series, we will be reviewing the steps that we as developers need to take in order to create a suitable web presence and build an audience that we can communicate ideas, projects and commercial offerings with.

In addition to theory articles discussing marketing, presentation and methods of engagement, we will also be building Rocket — a Laravel application that will allow you and other developers to create a personal site and grow an audience through social media and article publishing… let’s dive in!

Today’s agenda

Now that the basic underpinnings of Rocket are in place, we can begin adding some meat to the application. We’ll start with “projects”, which will allow the developer to publicise their portfolio of commercial and open-source apps.

Step #1 — Setup the database

Of course, we’ll need to create a new database table for our projects so we can easily manage them. You could also do this with a configuration file if you so desired, however that would require a re-deploy whenever you wanted to add or change something, so we’ll stick with a database:

php artisan make:model Project -mf

This will give us a model, a migration and a factory. Next, let’s add the fields to the migration and setup faker for the factory:

// MIGRATION

Schema::create('projects', function(Blueprint $table) {
    $table->id();
    $table->enum('type', ['Commercial', 'Open Source']);
    $table->string('name', 100);
    $table->string('summary', 255);
    $table->string('platforms', 100);
    $table->string('url', 255);
    $table->timestamps();
});

// FACTORY

$factory->define(Project::class, function(Faker $faker) {
    $types = ['Commercial', 'Open Source'];
    $platforms = ['PHP', 'Laravel', 'Vue', 'CSS'];

    return [
        'type' => $faker->randomElement($types),
        'name' => $faker->word,
        'summary' => $faker->realText(200),
        'platforms' => $faker->randomElement($platforms),
        'url' => $faker->url,
    ];
});

There’s nothing particularly special here. We’re defining an enum for the type so that we have to provide either ‘Commercial’ or ‘Open Source’. We could also go with a boolean here, however there are other models available such as ‘Sponsorware’. Using an enum allows us to add those later if want.

We also have a name and summary for the project, as well as a URL, which can link to a Github repo, a wiki, custom domain etc. Finally, we have a field for platforms, where we can include a list of languages e.g. PHP, CSS etc.

Step #2 — Routes and controllers

Next, we’ll need to add an entry-point to our application so that we can view the projects. Let’s add a single route for now:

Route::get('/projects', 'ProjectController@index');

We’ll then need to create a controller for this route:

php artisan make:controller ProjectController

For the time being, the ProjectController will only require a single index method to display the list of projects:

use App\Models\Project;
use App\Types\Controller;
use Illuminate\View\View;

class ProjectController extends Controller
{
    /**
     * Show the list of projects.
     *
     */
    public function index() : View
    {
        $projects = Project::query()
            ->orderBy('type', 'asc')
            ->orderBy('name', 'asc')
            ->simplePaginate(10);

        return view('pages.projects.view.index')
            ->with('projects', $projects);
    }
}

Let’s examine what’s happening here… we’re running a database query to retrieve the projects. We then order them by type (so commercial will appear first), and then by name. Finally, we paginate the results so that we don’t put too much strain on the database if there are many projects.

Once we have the results, we inform Laravel that we want it to render a view, and we then pass the results to that view. Nice!

Extra credit

One final thing we can do, although it isn’t technically necessary at this stage, is to set the middleware for the controller. When we add methods to enable management of the projects, these will need to be secured.

As such, visitors to the site should only be able to access the index method. We can enforce this restriction in the controller within its contructor:

class ProjectController extends Controller
{
    /**
     * Constructor.
     *
     */
    public function \_\_construct()
    {
        $this->middleware('auth')->except('index');
    }
}

Step #3 — Displaying the projects

Now that we’ve taken care of the back-end, let’s move on to the front-end and create the view responsible for rendering the projects:

{{-- Projects --}}
@forelse ($projects as $project)

    {{-- Project --}}
    <div class="bg-gray-100 shadow-md rounded-lg p-6 mb-6">

        {{-- Name --}}
        <h2 class="flex items-center font-bold text-teal-700 mb-4">

            {{-- Text --}}
            {{ Str::ucfirst($project->name) }}

            {{-- Type --}}
            <span class="ml-4 px-3 py-1 uppercase text-white
                         {{ $project->type === 'Commercial'
                            ? 'bg-orange-600' : 'bg-green-600' 
                         }}">
                {{ $project->type}}
            </span>

        </h2>

        {{-- Summary --}}
        <p class="mb-4 leading-normal text-gray-700">
            {{ $project->summary }}
        </p>

        {{-- Platforms --}}
        <p class="mb-1 text-gray-500 text-md">
            {{ $project->platforms }}
        </p>

        {{-- Link --}}
        <a target="\_blank"
           href="{{ $project->url }}"
           class="text-blue-500 hover:text-red-800 text-md">
            {{ Str::limit($project->url, 100) }}
        </a>

    </div>

@empty

    {{-- No Projects --}}
    <div class="bg-gray-100 shadow-md rounded-lg p-6 mb-6">
        <p class="text-center text-gray-600 uppercase text-sm">
            No projects have been added yet
        </p>
    </div>

@endforelse

We’re mostly just iterating through the projects and dumping out the relevant fields as HTML, however there are a few things worth noting:

  1. We’re using a @forelse loop instead of @foreach . Both loop types are the same, however @forelse also provides an @empty directive, which Laravel will render if there are no results. Since a developer may have no projects, we can use this to display a more friendly ‘no projects yet’ message.
  2. We’re automatically capitalising the first letter of the project name, just in case the user forgets to do so.
  3. We’re adding a coloured pill next to the project name. This pill will help to separate commercial from open-source projects.
  4. Finally, we’re limiting the length of the displayed project URL. This will help to make things a little cleaner on small devices.

Here’s how it looks in the browser:

Step #4 — Testing that it works

Our final task, it to write tests to ensure that our code is functioning correctly. Since we don’t have anything that the user will interact with e.g. a form, we can use a server-side test to confirm what we’ve written:

class ProjectTest extends ServerTest
{
    /** @test */
    public function a_user_can_see_the_projects() : void
    {
        $project = factory(Project::class, 1)->create()->first();

        $this->get('/projects')
            ->assertSuccessful()
            ->assertSee('Projects')
            ->assertSee(Str::ucfirst($project->name))
            ->assertSee($project->type)
            ->assertSee($project->summary)
            ->assertSee($project->platforms)
            ->assertSee($project->url);
    }
}

Let’s break this down… first, we create a fake project. Next, we visit the main projects page and check that we didn’t get an error. Finally, we confirm that the project’s name, summary, type etc. are all present on the page.

Wrapping up

We now have the basics of ‘projects’ set up within Rocket. Visitors can view what we’ve made and visit the associated sites. However, we still don’t have a means to create, edit or delete projects.

That’s our next job in part #6. I hope you’re excited for it!

To ensure you’re notified when it comes out, why not go ahead and follow me here on Medium, or better yet, on Twitter, where I’ll also be posting additional updates as well as links to new articles.

Thanks, and have a great day! 😎

Posted on Apr 8 '19 by:

mattkingshott profile

Matt Kingshott 👨🏻‍💻

@mattkingshott

Founder. Developer. Writer. Lunatic. Created Pulse, IodineJS, Axiom, and more. #PHP #Laravel #Vue #TailwindCSS

Discussion

markdown guide