Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lucasweaver's avatar

This feels dirty...

Hi folks, I have an online language school where users go through lessons in a course, but each lesson has multiple components.

There's a sidebar to the right and if that component has been completed, an SVG for a checkmark is visible to the right, and the route goes to the view that shows the completed component with their answers and the grade.

If they haven't completed it, it goes to the view to actually complete the exercise.

Here is the implementation, which at the moment is functional:

<div class="relative flex items-center">
       <div class="min-w-0 flex-1 text-sm"> 
                          @php $gpRouteEnding = ($lesson->progress->guided_practice_completed) ? '.results' : '.show'; @endphp
                          <a href="{{ route('dashboard.lessons.guided-practice' . $gpRouteEnding, 
                            ['locale' => session('locale'), 'courseId' => $course->id, 'lessonId' => $lesson->id]) }}" class="text-black hover:text-gray-600 group flex items-center px-2 py-2 text-sm font-medium rounded-md">            
                              Guided Practice
                          </a>
                        </div>
                        <div class="flex items-center">
                          @if($lesson->progress->guided_practice_completed)
                            <svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
                              <path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                            </svg>
                          @endif
      </div>
</div>

However, it feels really dirty and I'm a bit embarrassed by it 😬.

Does anyone have any guidance or advice on how a good developer would actually handle this situation?

Thank you in advance šŸ™‚.

0 likes
1 reply
LaryAI's avatar
Level 58

One possible solution to make the code cleaner and more readable is to extract the logic for generating the route and SVG icon into separate methods or functions. This can make the main code block more concise and easier to understand.

For example, we can define a function called getGuidedPracticeRoute that takes the lesson object as input and returns the appropriate route based on whether the guided practice has been completed or not. Similarly, we can define a function called getGuidedPracticeIcon that takes the same lesson object and returns the SVG icon if the guided practice has been completed.

Here's an example implementation:

@php
function getGuidedPracticeRoute($lesson) {
    $routeEnding = ($lesson->progress->guided_practice_completed) ? '.results' : '.show';
    return route('dashboard.lessons.guided-practice' . $routeEnding, [
        'locale' => session('locale'),
        'courseId' => $lesson->course->id,
        'lessonId' => $lesson->id,
    ]);
}

function getGuidedPracticeIcon($lesson) {
    if ($lesson->progress->guided_practice_completed) {
        return '<svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>';
    } else {
        return '';
    }
}
@endphp

<div class="relative flex items-center">
    <div class="min-w-0 flex-1 text-sm">
        <a href="{{ getGuidedPracticeRoute($lesson) }}" class="text-black hover:text-gray-600 group flex items-center px-2 py-2 text-sm font-medium rounded-md">
            Guided Practice
        </a>
    </div>
    <div class="flex items-center">
        {!! getGuidedPracticeIcon($lesson) !!}
    </div>
</div>

In this implementation, we define the getGuidedPracticeRoute and getGuidedPracticeIcon functions using PHP's @php directive. These functions take the $lesson object as input and return the appropriate route and SVG icon based on the completion status of the guided practice.

In the main code block, we use these functions to generate the route and icon, respectively. This makes the code more readable and easier to maintain, since the logic for generating the route and icon is now encapsulated in separate functions.

Please or to participate in this conversation.