#Is this over kill?

7 messages · Page 1 of 1 (latest)

sinful socket
#

My end goal: I am building a "portfolio" section, and there are 4 different filters [all, software, art, strategy]. Depending on the filter applied different App\Models\Project will show, and depending on the 'context' the way the Project is rendered will be completely different. And, I didn't want to have a ton of the conditional logic repeated. Am I thinking about this right? Or am I over complicating this? Appreciate any feedback. You can see this in action here: http://joshteam.com/portfolio

//controller
    public function index(Request $request)
    {
        $portfolio = Section::create($request);

        return view('portfolio', [
            'portfolio' => $portfolio,
        ]);
    }

//main blade
<x-site.section :title="$title" :sub-title="$section->getSubTitle()">
@foreach($projects as $project)
    {!! $section->renderProject($project) !!}
@endforeach
</x-site.section>
royal sluice
#

Wait you're creating a new session model every time someone visits the index page?

oblique talon
#

Yeah, just like 36864 I have no clue what's going on here 😅 what's the use-case for an "all" section? That would just be all other sections combined, not a separate table/model? 🤨

sinful socket
#

@royal sluice and @oblique talon:
First, I'm very appreciative you took the time to look at it and provide feedback. Let me first say, I am not trying to defend the code, but only explaining why I did what I did as to maybe allow you to give me better constructive feedback. Here was my thought process:

The end result is I wanted to basically show App\Models\Project in different 'Contexts'. So for instance if you are looking at "All" projects, then it may just be a bunch of thumbnails with titles and the date next to it. But if you filter it to just art, it would grab all Project::where('type', 'art') and show it in a different context - for instance the large version of the image whereas type => strategy would show a lot more text and maybe the problem I was trying to solve.

Since, the rendering logic would need to change based on what you were looking at I decided to create the "Section" object which holds the logic of how to render the section in the portfolio. And the first thing the Controller does is just pass a Request to the Section for the Section to figure out which type of Section to return "All, Software, Image, Strategy, etc."

//The Controller
$portfolio = Section::create($request);

//Section is the abstract class behind All/Software/Art etc sections
abstract class Section
{
    private string $title;
    private string $slug;
    private Collection $projects;

    const allSlug = 'all';

    //the main magic happens here
    static private array $sections = [
        self::allSlug   => All::class,
        Software::slug  => Software::class,
        Art::slug       => Art::class,
        Strategy::slug  => Strategy::class,
    ];

    //.. base utility I want all different sections to have ..

    static public function create(Request $request) : Section
    {
        if($request->route()->getName() === PortfolioController::route) {
            $filter = $request->route()->parameter('filter') ?: self::allSlug;
            return new self::$sections[$filter]($request);
        }
        throw new \Exception('Invalid route for portfolio section');
    }
}

//Portfolio/All.php
class All extends Section
{
    public function getTitle(): string
    {
        return 'All My Work';
    }

    public function getSubTitle(): string
    {
        return 'A collection of all my work over 20 years';
    }

    public function renderProject(Project $project) : string
    {
        return view('components.portfolio.project.all', ['project' => $project]);
    }

}

//Portfolio/Art.php
class Art extends Section
{
    const slug = 'art';

    public function getTitle(): string
    {
        return 'Digital Art';
    }

    public function getSubTitle(): string
    {
        return 'A collection of my digital art infused with AI';
    }

    public function renderProject(Project $project): string
    {
        return view('components.portfolio.project.art', ['project' => $project]);
    }
}

//Then inside my portfolio.blade I just have this one line
<x-portfolio.projects :section="$portfolio" />

//And my portfolio.projects component
<x-site.section :title="$title" :sub-title="$section->getSubTitle()">
@foreach($projects as $project)
    {!! $section->renderProject($project) !!}
@endforeach
</x-site.section>

//The Project blade Component
class Projects extends Component
{

    public Section $section;
    public string $title;
    public Collection $projects;

    public function __construct(Section $section)
    {
        $this->section  = $section;
        $this->title    = $section->getTitle();
        $this->subTitle = $section->getSubTitle();
    }
}
royal sluice
#

I don't know this all seems very complicated when you could just have a single component decide which view to return based on context or type of object or whatever

sinful socket
# royal sluice I don't know this all seems very complicated when you could just have a single c...

You are probably right. Here's the problem I couldn't get my head around:

I didn't want to show a project based on the project type. I wanted to show the projects in the context you were looking at them in. So for instance all projects would show a thumbnail and title regardless if it's a software, art, or strategy. But then when you are viewing just strategy, the same projects render completley different.

royal sluice
#

Well, initially I thought Section was a model, and it would be very weird to be creating a new model when someone visits the view. But if it's just what amounts to a component class, I guess it's fine? I don't quite understand the separation of "things that inherit from Section and "things that are Components