Skip to content
Advertisement

Laravel: Passing data into route from database

I have created a theme system and I am trying to make the theme’s route file pull pages from the database and assign a route to it, below is my theme route file. The issue I am having is an Undefined variable: theme from my ThemeSettings::all model request.

Route.php (In theme)

<?php

use IlluminateSupportFacadesRoute;
use IlluminateSupportFacadesDB;
use IlluminateSupportFacadesSchema;
use AppModelsThemeSettings;
use AppModelsPages;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('themes/main/index');
})->name('home');

$theme = ThemeSettings::all();
$pages = Pages::get();

foreach ($pages as $key => $page) {
    Route::get('/' . $page->slug, function () {
        return view($theme->location . $theme->name . '/' . $page->view);
    })->name($page->slug);
}

Route::get('/terms', function () {
    return 'Terms of use';
})->name('termsofuse');
Route::get('/privacy', function () {
    return 'Privacy Policy';
})->name('privacypolicy');

Route::get('posts', 'PostController@index')->name('post.index');
Route::get('post/{slug}', 'PostController@details')->name('post.details');

Route::get('/category/{slug}', 'PostController@postByCategory')->name('category.posts');
Route::get('/tag/{slug}', 'PostController@postByTag')->name('tag.posts');

Route::get('/search', 'SearchController@search')->name('search');

Route::group(['middleware' => ['auth']], function () {
    Route::post('favorite/{post}/add', 'FavoriteController@add')->name('post.favorite');
    Route::post('comment/{post}', 'CommentController@store')->name('comment.store');
});

ThemeSettings Migration

<?php

use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

class CreateThemeSettingsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('theme_settings', function (Blueprint $table) {
            $table->id();
            $table->string('name')->default('main');
            $table->text('description');
            $table->string('author');
            $table->string('location')->default('resources/views/themes');
            $table->string('view_location')->default('themes/');
            $table->timestamps();
            $table->boolean('is_theme')->default(false);
        });

        DB::table('theme_settings')->insert([
            'description' => 'The core theme for Oracle CMS. A custom responsive framework with easy to use controls.',
            'location' => 'resources/views/themes/',
            'view_location' => 'themes/',
            'author' => 'Spencer K Media'
        ]);
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('theme_settings');
    }
}

These settings have worked in other parts of the site including in the admin area without issue, which is why I am confused.

Any help on this would be greatly appreciated! Thank you in advance!

Advertisement

Answer

$theme and $page are not scoped to the closure:

Route::get('/' . $page->slug, function () {
    // $theme and $page are not defined here
    return view($theme->location . $theme->name . '/' . $page->view);
})->name($page->slug);

So, you make them accessible via use()

Route::get('/' . $page->slug, function () use ($theme, $page) {
    // All good now
    return view($theme->location . $theme->name . '/' . $page->view);
})->name($page->slug);

But, you have another problem:

// $theme is a collection instance
$theme = ThemeSettings::all();

Meaning accessing a property like $theme->location will cause an exception, as well.

// You need to limit the result to a single instance.
$theme = ThemeSettings::where('something', 'some_value')->first();
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement