So, for my template, I'm creating a block of code that runs custom "Modules". Basically, they are a custom post type, with fields built in ACF. Each of these modules has their own Blade template (e.g. /resources/views/modules/brandwindow.blade.php).
I've also created a Blade template for a custom post type called "Modular Page". On this template, I handle all the calls for each and any module called in a loop. I want to be able to handle this login in a controller, however. So, I created a Controller called "LoadModules" that will handle that request.
I'm having some difficulty calling a Blade template from a Controller, though. In a function GetModules(), I loop through the ACF repeater to see which module I need to load, and then supply all the relevant fields with another Controller specific to that Module (e.g. if module = 'bwindow', Call BrandWindow->BrandWindowFields). This returns an array which I can then pass into a View.
I've added the View class to the top of the Controller (like you would in Laravel), but I'm pretty sure I'm doing something wrong here. I'm getting the following error:
Class 'View' not found in ..\app\Controllers\LoadModules.php on line 25
Here's my Controller code:
public static function GetModules()
{
$brand_window_loader = new BrandWindow;
$module_array = get_sub_field('content_type');
if ($module_array == 'bwindow') {
// Do Brand Window Stuff
$windows = $brand_window_loader->GetBrandWindows();
$output = '';
foreach ( $windows as $window ){
$feild_array = $brand_window_loader->BrandWindowFields($window);
$output .= View::make('modules.brandwindow', $feild_array);
}
return $output;
} elseif ($module_array == 'blogfeed') {
// Do Blog Feed Stuff
return $module_array;
}
}
Line 25, is throwing the error which is:
$output .= View::make('modules.brandwindow', $feild_array);
The $brand_window_loader->BrandWindowFields($window) is just an array of keyed values it pulls from ACF using the ID of the post.
'title' => 'Title',
'sub_text' => 'Sub Text',
'url' => 'http://example.com'
ETC.
The error is obviously related to the "View" class not existing, so I'm wondering if I've namespaced or the View class does not exist with Sage 9/Bedrock. If that's true, what is the best way to include a Blade template from a Controller?
Thanks
You can try :
$output .= App\template('modules.brandwindow', $feild_array)
Related
Is posible to save SS template variable in database from CMS and after execute it in template?
Okay lets see example:
In CMS i have settings where i put social media links and contact informatios.
Also in CMS i have module where i create HTML block-s which after that i loop in website.
In that html block i want to put existing $SiteConfig.Email variable.
I Try that but that is rendered in template like $SiteConfig.Email not show real email?
Is this posible to do or i need some extra modification?
Check photo
The question you have written makes no sense to me, but I understand the screenshot.
So, SilverStripe renders .ss files with a class called SSViewer. Basically it reads the file as string and then runs it through SSViewer to generate the HTML output.
But, as you saw, the output of variables is not processed.
I can think of 3 ways to get what you want:
Run the variables through SSViewer aswell (in this example, use $RenderedHTMLContent in the template)
class MyDataObject extends DataObject {
private static array $db = [
'Title' => DBVarchar::class,
'HTMLContent' => DBText::class,
];
public function Foobar() { return "hello from foobar"; }
public function RenderedHTMLContent() {
$template = \SilverStripe\View\SSViewer::fromString($this->HTMLContent);
// using $this->renderWith() will allow you access to all things of $this in the template. so eg $ID, $Title or $Foobar. Probably also $SiteConfig because it's global
return $this->renderWith($template);
// if you want to add extra variables that are not part of $this, you can also do:
return $this->renderWith($template, ["ExtraVariable" => "Hello from extra variable"]);
// if you do not want $this, you can do:
return (new ArrayData(["MyVariable" => "my value"]))->renderWith($template);
}
}
Please be aware of the security implications this thing brings. SilverStripe is purposely built to not allow content authors to write template files. A content author can not only call the currently scoped object but also all global template variables. This includes $SiteConfig, $List, .... Therefore a "bad" content author can write a template like <% loop $List('SilverStripe\Security\Member') %>$ID $FirstName $LastName $Email $Salt $Password<% end_loop %> or perhaps might access methods that have file access. So only do this if you trust your content authors
Use shortcodes instead of variables. But I never liked shortcodes, so I don't remember how they work. You'll have to lookup the docs for that.
Build your own mini template system with str_replace.
class MyDataObject extends DataObject {
private static array $db = [
'Title' => DBVarchar::class,
'HTMLContent' => DBText::class,
];
public function Foobar() { return "hello from foobar"; }
public function RenderedHTMLContent() {
return str_replace(
[
'$SiteConfig.Title',
'$SiteConfig.Tagline',
'$Title',
'$Foobar',
],
[
SiteConfig::current_site_config()->Title,
SiteConfig::current_site_config()->Tagline,
$this->Title,
$this->Foobar(),
],
$this->HTMLContent
);
}
}
I've encounter this issue during the develop of my plugin.
I've to loop through all the pages of the website and print the titles and the IDs of them.
When I do the simply loop it just don't print anything.
Is there a way for do a loop inside options of my plugin?
Found the solution.
I don't know if there's some kind of block inside the plugin options page but we can loop through every custom post type with a little portion of code:
<?php
//Search only for custom post type which is public.
$args = array('public'=>true);
//Get all custom post type name
$allMyCustomPostTypes = get_post_types($args);
foreach ($allMyCustomPostTypes as $myCustomPostType) {
//Create a filter for get_posts with every custom post type
$filter = array('numberposts' => 5, 'post_type' => $myCustomPostType);
//Pass the value to *get_posts*
$theposts = get_posts($filter);
foreach ($theposts as $thepost) {
//Easy print the name of the current post of the current custom post type
echo $thepost->post_title;
};
};
?>
Here we are, hope this helps somebody.
I am learning and developing a project in laravel 5.3. So I stucked at a point that, to every view in this project I am passing variables to views like following.
public function index()
{
$page_title = 'Page Title';
return view('home', ['title' => $page_title]);
}
so in login and register controllers there are no methods to return views. And I want to pass same variables with different string values to login and registration form. so how can i do that. And secong thing I want to ask is, that how can I add a 404 error page in my project for undefined routes. and third question is that can I set 404 page to register route (www.myproject.com/register) after adding some users in my project. looking forword for reply..
The methods to return the views are in traits, if you want to add you own logic for these methods you can simply override them by adding your own methods the class that uses the trait e.g.
RegisterController
public function showRegistrationForm()
{
$title = 'Register';
return view('auth.register', compact('register'));
}
LoginController
public function showLoginForm()
{
$title = 'Login';
return view('auth.login', compact('title'));
}
If you want to add a custom 404 error page then you just need to create that a file at resources/views/errors/404.blade.php as shown in the docs https://laravel.com/docs/5.4/errors#custom-http-error-pages
Laravel comes with a RedirectIfAuthenticated middleware that will (as the name suggests) rediect the user away from a route if they are already logged in. By default, the login and register routes already have this. If you want to change this behaviour just edit your App\Http\Middleware\RedirectIfAuthenticated class.
Hope this helps!
In the login controller > AuthenticatesUsers trait you can type your variables here.
Default path: app/Http/Controllers/Auth/LoginController.php
public function showLoginForm()
{
$test = 'test';
return view('auth.login', compact('test'));
}
Optimized this could save your 'arss'
LoginController.php
public function showLoginForm()
{
$title = 'Login';
$css = array(
asset('sign-up-in/css/index.css'),
);
$js = array(
asset('sign-up-in/js/index.js'),
);
return view('auth.login', compact('title','css','js'));
}
Do the same for RegisterController.php +(bonus) every other controller
Now slay it all with this
app.blade.php
#if(isset($js))
#foreach($js as $key => $value)
<script src="{{$value}}"></script>
#endforeach
#endif
#if(isset($css))
#foreach($css as $key => $value)
<link href="{{$value}}" rel="stylesheet">
#endforeach
#endif
I have correctly created a custom widget, evreything is translating well with a correct .po file, except the title.
Here is my code :
$concert_widget_name = __('Tour Dates', 'concerts');
wp_register_sidebar_widget (
'tourdates', // your unique widget id
$concert_widget_name, // widget name
'tourdates_widget_display', // callback function to display widget
array( // options
'description' => 'Displaying upcoming tour dates'
)
);
Is there an error ? An other way to translate the widget name ?
I usually register my widgets using the register_widget function. In the constructor of the widget class I place the following code:
class TourDates extends WP_Widget
{
public function __construct()
{
$options = array('classname' => 'tour-dates', 'description' => __('Display upcoming tour dates'));
parent::__construct('tour_dates', __('Tour Dates'), $options);
}
}
You can also check out the Widgets API on the WordPress Codex site. Hopefully this helps you in creating your custom widget.
Also what I usually do is merge my translations with the default ones loaded from WordPress, like so:
function loadTextDomain() {
$locale = get_locale();
$languageDir = dirname(__FILE__) . '/languages';
$domain = 'default';
$mofile = $languageDir . '/theme.' . $locale . '.mo';
global $l10n;
$mo = new MO();
if (!$mo->import_from_file($mofile)) {
return false;
}
if (isset($l10n[$domain]) && !empty($l10n[$domain]->entries)) {
$l10n[$domain]->merge_with($mo);
} else {
$l10n[$domain] = $mo;
}
}
add_action('init', 'loadTextDomain');
This code looks similar to the load_textdomain function from WordPress but it avoids all the filters that do exist in the original function, which helps in avoiding any WordPress hook from altering your $domain and $mofile variables.
But I will leave that up to you. Maybe the load_textdomain() function from WordPress will work just as fine, but in case it doesn't this function should do the trick.
Now if your using the loadTextDomain() function I pasted above you can just place a languages folder in the same folder as your functions.php resides, in that new folder you could place theme.nl_NL.mo or theme.de_DE.mo files depending on the language your using. This should allow translation of your website and also the admin area.
I am trying to create a back-end interface for silverstripe that gives the CMS user the option to choose between a set of Post Types (like tumblr) in Silverstripe3. So they can choose to create a News Post, Video Post, Gallery Post, etc.
I initially started off giving all Posts the necessary fields for each Type and adding an enum field that allowed the user to choose the Post Type. I then used the forTemplate method to set the template dependent upon which Post Type was chosen.
class Post extends DataObject {
static $db = array(
'Title' => 'Varchar(255),
'Entry' => 'HTMLText',
'Type' => 'enum('Video, Photo, Gallery, Music')
);
static $many_many = array(
'Videos' => 'SiteVideo',
'Photos' => 'SitePhoto,
'Songs' => 'SiteMp3'
);
public function forTemplate() {
switch ($this->Type) {
case 'Video':
return $this->renderWith('VideoPost');
break;
case 'Photo':
return $this->renderWith('ImagePost');
break;
etc...
}
function getCMSFields($params=null) {
$fields = parent::getCMSFields($params);
...
$videosField = new GridField(
'Videos',
'Videos',
$this->Videos()->sort('SortOrder'),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Videos', $photosField);
$photosField = new GridField(
'Photos',
'Photos',
$this->Photos()->sort('SortOrder'),
$gridFieldConfig
);
$fields->addFieldToTab('Root.Videos', $photosField);
return $fields;
}
}
I would rather the user be able to choose the Post Type in the backend and only the appropriate tabs show up. So if you choose Video, only the Video GridField tab would show up. If you choose Photo Type only the Photo's GridField would show.Then I would like to be able to call something like
public function PostList() {
Posts::get()
}
and be able to output all PostTypes sorted by date.
Does anyone know how this might be accomplished? Thanks.
Well the first part can be accomplished using javascript. Check out this tutorial and the docs let me know if you have questions on it.
The second part would be trickier but I think you could do something with the page controller. Include a method that outputs a different template based on the enum value but you would have to set links somewhere.
I managed this with DataObjectManager in 2.4.7 as I had numerous DataObjects and all were included in one page but I'm not sure if that is feasible in SS3.
return $this->renderWith(array('CustomTemplate'));
This line of code will output the page using a different template. You need to include it in a method and then call that method when the appropriate link is clicked.