tastyigniter/ti-ext-frontend
Frontend extension for TastyIgniter adding banners, hero sliders, MailChimp subscribe form, contact form API, and optional Google reCAPTCHA. Manage and place content across front-end pages to boost engagement and improve form security.
Installation:
composer require tastyigniter/ti-ext-frontend
php artisan vendor:publish --provider="TastyIgniter\Frontend\FrontendServiceProvider"
Database Setup:
php artisan migrate
sliders, banners, newsletter_subscribers, and contact_messages.Basic Blade Integration:
@component('frontend::slider', ['slides' => \App\Models\Slider::active()->get()])
@endcomponent
@component('frontend::banner', ['banner' => \App\Models\Banner::find(1)])
@endcomponent
Form Setup:
@component('frontend::newsletter')
@endcomponent
.env:
MAILCHIMP_API_KEY=your_key
MAILCHIMP_LIST_ID=your_list_id
@component('frontend::contact-form')
@endcomponent
config/frontend.php:
'recaptcha' => [
'site_key' => 'your_site_key',
'secret_key' => 'your_secret_key',
],
Admin Access:
// Controller
public function showHomepage()
{
$slides = \App\Models\Slider::active()->orderBy('position')->get();
return view('home', compact('slides'));
}
<!-- View -->
@foreach($slides as $slide)
<div class="slide">
<img src="{{ $slide->image_url }}" alt="{{ $slide->title }}">
<h2>{{ $slide->title }}</h2>
</div>
@endforeach
$slides = Cache::remember('homepage_slides', now()->addHours(1), function () {
return \App\Models\Slider::active()->orderBy('position')->get();
});
@if($showPromoBanner)
@component('frontend::banner', [
'banner' => \App\Models\Banner::where('type', 'promo')->first()
])
@endcomponent
@endif
// Route parameter or query string
$banner = \App\Models\Banner::where('slug', request('banner_slug'))->firstOrFail();
// In a controller or service
$subscriber = new \App\Models\NewsletterSubscriber([
'email' => $request->email,
'status' => 'subscribed'
]);
$subscriber->subscribeToMailchimp(); // Uses package's MailchimpService
use TastyIgniter\Frontend\Services\ContactFormService;
$contactService = new ContactFormService();
$contactService->handle($request, function ($data) {
// Custom logic (e.g., log to database, send Slack notification)
\Log::info('New contact form submission', $data);
});
$validator = Validator::make($request->all(), [
'g-recaptcha-response' => 'required|captcha',
]);
config/frontend.php has reCAPTCHA keys:
'recaptcha' => [
'enabled' => env('RECAPTCHA_ENABLED', true),
'site_key' => env('RECAPTCHA_SITE_KEY'),
'secret_key' => env('RECAPTCHA_SECRET_KEY'),
],
php artisan vendor:publish --tag=frontend-assets --force
resources/assets/frontend/ and compile with Laravel Mix.Service Container Binding: If using Laravel’s service container, bind the package’s services:
$this->app->bind(
\TastyIgniter\Frontend\Services\MailchimpService::class,
function ($app) {
return new \TastyIgniter\Frontend\Services\MailchimpService(
config('services.mailchimp.key'),
config('services.mailchimp.list')
);
}
);
Event Listeners: Extend form submission events:
// Listen to newsletter subscription
\App\Models\NewsletterSubscriber::created(function ($subscriber) {
event(new \App\Events\NewsletterSubscribed($subscriber));
});
Middleware: Protect admin routes for managing frontend components:
Route::middleware(['auth', 'can:manage-frontend'])->group(function () {
// Admin routes for sliders, banners, etc.
});
document.addEventListener('DOMContentLoaded', function() {
const slider = document.getElementById('hero-slider');
if (slider) {
// Load slider content via AJAX or fetch
}
});
Schema::table('sliders', function (Blueprint $table) {
$table->index('is_active');
$table->index('position');
});
public function test_contact_form_submission()
{
$request = new \Illuminate\Http\Request([
'name' => 'Test User',
'email' => 'test@example.com',
'message' => 'Hello!',
]);
$this->mock(\TastyIgniter\Frontend\Services\Mailer::class)
->shouldReceive('send')
->once();
$this->post('/contact', $request->all());
}
public function test_slider_component()
{
$slider = \App\Models\Slider::factory()->create(['is_active' => true]);
$response = $this->get('/')
->assertSee($slider->title)
->assertSee($slider->image_url);
}
TastyIgniter Dependencies:
class LaravelMailchimpService extends \TastyIgniter\Frontend\Services\MailchimpService
{
public function __construct()
{
parent::__construct(
config('services.mailchimp.key'),
config('services.mailchimp.list')
);
}
}
reCAPTCHA Misconfiguration:
if (!config('frontend.recaptcha.site_key') || !config('frontend.recaptcha.secret_key')) {
throw new \RuntimeException('reCAPTCHA keys are not configured.');
}
MailChimp Integration:
MAILCHIMP_API_KEY or MAILCHIMP_LIST_ID are incorrect.config/caching to avoid repeated API calls:
$mailchimp = Cache::remember('mailchimp_service', now()->addHours(1), function () {
return new \TastyIgn
How can I help you explore Laravel packages today?