Adding custom grid layouts

Permalink 1 user found helpful
1. In your page theme root, create a page called page_theme.php. You have to namespace the class and extend Theme. Once you've done that add "protected $pThemeGridFrameworkHandle = 'custom_grid_name';". The custom grid name needs to be in lowercase. If your custom grid is called LemonJello.php, then your handle will be "lemonjello".
- concrete\themes\your_theme_name
<?php
namespace Concrete\Theme\YourThemeName;
class PageTheme extends \Concrete\Core\Page\Theme\Theme {
    protected $pThemeGridFrameworkHandle = 'custom_grid_name';
}


2. Your custom grid files are stored in concrete\src\Page\Theme\GridFramework\Type. When you create the custom grid file, the name must be in CamelCase to work - e.g. HushPuppy.php.

Creating the custom grid file is another story. It doesn't look like there is a minimum or maximum number of custom grid classes you can use. There is a restriction on the maximum columns that can be set on a per area basis though - $a->setAreaGridMaximumColumns(X);. I recommend looking at Bootstrap3.php as an example to build your own custom file.


Example:
My theme is called Foetida.
My custom grid file is called Custom15ColGrid.php.
<?php
namespace Concrete\Theme\Foetida;
class PageTheme extends \Concrete\Core\Page\Theme\Theme {
    protected $pThemeGridFrameworkHandle = 'custom15colgrid';
}

MrKDilkington
 
stefancrs replied on at Permalink Reply
stefancrs
Where on disk did you put your own grid class? In application, a package or the core stuff?
rmayhue replied on at Permalink Reply
I didn't want to alter the core so here's what worked for me:

Create these directories: `application/src/page/theme/grid_framework/type`
# from C5 root
$ mkdir -p application/src/page/theme/grid_framework/type


Copy GridFramework.php from the C5 core renaming to grid_framework.php
# from C5 root
$ cp concrete/src/Page/Theme/GridFramework/GridFramework.php \
> application/src/page/theme/grid_framework/grid_framework.php


In the newly copied `grid_framework.php` file on line 2 change the namespace to:
namespace Application\Core\Page\Theme\GridFramework;


Then change line 8 it to this:
$class = '\\Application\\Core\\Page\\Theme\\GridFramework\\Type\\' . camelcase($pThemeGridFrameworkHandle);


Then in your `page_theme.php` file add this to use the `grid_framework.php` file:
// add under the first `use` line
use Application\Core\Page\Theme\GridFramework\GridFramework;
// then add this method farther down
    /**
     * @return GridFramework|null
     */
    public function getThemeGridFrameworkObject()
    {
        if ($this->pThemeGridFrameworkHandle) {
            $pTheme = GridFramework::getByHandle($this->pThemeGridFrameworkHandle);
            return $pTheme;
        }
    }


Now add your own grid types to `/application/src/page/theme/type/`. Just make sure the namespace and use at the top is this:
<?php
namespace Application\Core\Page\Theme\GridFramework\Type;
use Loader;
use Application\Core\Page\Theme\GridFramework\GridFramework;
...


Good luck... I hope I didn't leave something out.

Edit: added `application` to the first code section.
stefancrs replied on at Permalink Reply
stefancrs
Excellent man, thank you, I will try this out!
mesuva replied on at Permalink Reply
mesuva
I didn't find I had to do as much as this to set up my own grid framework, I found I could just include it in the same folder as my page_theme.php file (i.e. my theme directory).

I wanted a grid for my theme called 'Custom Grid', I created a file custom_grid.php in my theme directory and set it up with the following:
<?php
namespace Concrete\Core\Page\Theme\GridFramework\Type;
use Concrete\Core\Page\Theme\GridFramework\GridFramework;
class CustomGrid extends GridFramework
{
// ... all the required functions for a grid framework class
}

Then in my page_theme.php file I specified the theme using somewhere in the PageTheme class the line:
protected $pThemeGridFrameworkHandle = 'CustomGrid';

The final step I needed to do was to address the fact that nothing would be automatically reading my file with my CustomGrid class. I found that there were two solutions, either:
- Include my CustomGrid class _in_ my page_theme.php file. Multiple namespaces can be used within a PHP file, you can just use brackets to contain them. Although permissible, it's not really that recommended though.
- More simply, I could place at the bottom of the page_theme.php a line to include the custom_grid.php file, with a line like:
include_once('custom_grid.php');

As the page_theme.php file is being read, this just makes sure that the custom_grid.php file is read too. The namespacing ensures that concrete5 knows how it fits into the class structure, but it doesn't necessarily mean it has to be at that same folder level.
stefancrs replied on at Permalink Reply
stefancrs
This worked a treat, apart from it seems about impossible to provide a proper Pure grid solution :)
andrew replied on at Permalink Reply
andrew
What about it was causing you trouble?

I've just created a document and screencast about how to do exactly this, for 5.7.2.1. We should have that documentation out tomorrow or early next week.
stefancrs replied on at Permalink Reply
stefancrs
You've done it for Pure or for "a grid system"? Because Pure is special in that you specify the column widths as fractions. The total number of columns in a row is dynamic, which is awesome, because you can have two, three, five etc equal width columns in a row.

<div class="pure-g">
  <div class="pure-u-1-5"> <!-- 20% width -->
  </div>
  <div class="pure-u-4-5"> <!-- 80% width -->
  </div>
</div>
<div class="pure-g">
  <div class="pure-u-1-2"> <!-- 50% width -->
  </div>
  <div class="pure-u-1-4"> <!-- 25% width -->
  </div>
  <div class="pure-u-1-4"> <!-- 25% width -->
  </div>
</div>



How do you implement that as a custom layout? :)
andrew replied on at Permalink Reply
andrew
I've added a screencast here:

http://www.concrete5.org/documentation/developers/5.7/designing-for...

To answer your question, the grid framework's that we have in the core now are using fixed column classes, so all the flexibility of this grid framework wouldn't be possible. However, you could certainly pick a useful sub-set of the grids and make those classes the ones included, and support the grid that way.
TMDesigns replied on at Permalink Reply
TMDesigns
Hi,

inhttp://www.concrete5.org/documentation/developers/5.7/designing-for...

you mention you are adding Foundation in 5.7.2.1 but i have looked and it isn't there. Have you added it? If so how can I activate it?
andrew replied on at Permalink Reply
andrew
Are you using the latest from Github? If so, you may have to re-run the upgrade and force it to complete. If that doesn't work you may just have to wait until we roll out 5.7.2.1 fully.
TMDesigns replied on at Permalink Reply
TMDesigns
Hi,

its just a 5.7.2 from the main site download. I will do it myself then then once its added i can uses it once its updated on the upgrade.

Thanks anyway.

How would you get the small, middle and large working on the same grid?
andrew replied on at Permalink Reply
andrew
This is not something we've put any thought into yet. Honestly the interface on the front-end sounds more difficult than anything on the back-end.
TMDesigns replied on at Permalink Reply
TMDesigns
i now have the newer version installed.

if i put this code into my theme file page_theme.php and reinstall the theme nothing shows up

<?php
namespace Application\Theme\Beechwood;
use Concrete\Core\Page\Theme\Theme;
print 'test';
class PageTheme extends Theme
{
 protected $pThemeGridFrameworkHandle = 'foundation';
}


is my code just not right?
andrew replied on at Permalink Reply
andrew
Make sure your overrides cache is turned off.
TMDesigns replied on at Permalink Reply
TMDesigns
it was on but even when turned off nothing happens.

the print doesn't show but causes this error when i try and uninstall the theme.

Just nothing i do adds the any grid layout.

I have tried copying code from the elemental theme and striping that back = Nothing

i am stumped. If anyone wants to ftp in and take a look please pm me.
1976Ltd replied on at Permalink Reply
1976Ltd
Has anyone else had problems editing container layouts when they are using custom grids?

I've followed the tutorial to add a custom grid layout:http://www.concrete5.org/documentation/developers/5.7/designing-for...

Adding a layout is fine and the new Custom grid shows but if I click on Edit Container Layout, to alter the columns or delete the layout I get the error:

TypeError: n.position(...) is undefined
   ccm_addHeaderItem("/concrete/js/layouts.js", "JAVASCRIPT")
MrKDilkington replied on at Permalink Reply
MrKDilkington
@Andrew

Since core files have changed. Do you have a recommended way to use a custom grid when the theme is in the application directory? How do we override Manager.php and where should we put our custom grid file?

I thought I was going crazy, because adding grid frameworks wasn't working like it did before. So I looked around and found two files that are new as of 5.7.2.1.
Manager.php
ManagerServiceProvider.php
https://github.com/concrete5/concrete5-5.7.0/tree/develop/web/concre...

Manager.php has grid specific driver methods.
https://github.com/concrete5/concrete5-5.7.0/blob/develop/web/concre...
Responsive replied on at Permalink Reply
Responsive
@mesuva , have tried your suggestion in v5.8 but still get Driver [] not supported. this is using a theme in the application directory. Not sure if should be different for version 8 ?
mesuva replied on at Permalink Reply
mesuva
If I comment out my include line that includes the grid file, or I change my $pThemeGridFrameworkHandle value in the page_theme.php file to a grid name I know doesn't exist I get an error message like: Driver [FunkyGrid] not supported.

So it's a little strange your error message is just showing Driver[], as if it doesn't even know a name of a grid to be looking for.

I'm using the exact same code/approach in v8, haven't needed to change anything.
Responsive replied on at Permalink Reply 1 Attachment
Responsive
@mesuva , have tried again using all details you gave but get Driver [CustomGrid] not supported. sorry not sure what happened to last error paste.

I have attached a zip showing the application/theme files used in the hope it may help where I have gone wrong , appreciate your help.

Im using v8.1.0 PHP 5.6.29
mesuva replied on at Permalink Reply
mesuva
I believe that the problem here is you're not registering the grid framework you are creating anyway.

See on the doco here the last section 'Register the Grid Framework in the Package'
https://documentation.concrete5.org/developers/designing-for-concret...

It's the lines in the on_start() function that are need to actually make the new grid framework you've defined available.

So the options are to either wrap this theme into a package and add in this on_start() bit of code, or what I've found is that you can just put these lines at the bottom of your grid framework definition, so they run as soon as the file is read.

I was able to get things to work by putting:
$manager = \Core::make('manager/grid_framework');
$manager->extend('CustomGrid', function($app) {
    return new CustomGrid();
});

At the very bottom of your CustomGrid.php file (so just after the class definition).
MrKDilkington replied on at Permalink Reply
MrKDilkington
@Responsive

In addition to what mesuva said, there is this approach that uses bootstrap.php instead of on_start().

Here is an example that creates a Bootstrap 4 grid:
1. create the grid framework class
application\src\Bootstrap4GridFramework.php
<?php
// v8 autoloading
namespace Application;
use Concrete\Core\Page\Theme\GridFramework\GridFramework;
class Bootstrap4GridFramework extends GridFramework
{
    public function supportsNesting()
    {
        return true;
    }
    public function getPageThemeGridFrameworkName()
    {
        return t('Bootstrap 4');
    }
    public function getPageThemeGridFrameworkRowStartHTML()

2. in your theme page_theme.php set the grid framework handle
protected $pThemeGridFrameworkHandle = 'bootstrap4';

3. in bootstrap.php, you need to setup v8 class autoloading and register the grid framework
application\bootstrap\app.php
// setup v8 class autoloading
$classLoader = new \Symfony\Component\ClassLoader\Psr4ClassLoader();
$classLoader->addPrefix('Application', DIR_APPLICATION . '/' . DIRNAME_CLASSES);
$classLoader->register();
// register the "bootstrap4" grid framework
$manager = Core::make('manager/grid_framework');
$manager->extend('bootstrap4', function($app) {
    return new Application\Bootstrap4GridFramework();
});

The following documentation explains changes to v8 class autoloading:
"Creating Custom Code in the Application Directory"
https://documentation.concrete5.org/developers/extending-concrete5-w...
Responsive replied on at Permalink Reply
Responsive
@mesuva @MrKDilkington , thank you both for your help with this.
pedroserapio replied on at Permalink Reply
pedroserapio
I hope this isn't very off-topic but I tried use the Foundation Grid that it's included in 5.7.3.1 but I got strange results.

Following a clean code I do:
<div class="row">
   <div class ="medium-12 columns"></div>
</div>


But if I add a Layout I get a big mess, not very big, but unnecessary div with strange order classes applied:

<div class="row"><div class="medium-12">    
<div class="row">
      <div class="columns medium-12">
    <p>..     ..</p>
</div>
</div>
</div></div>


Is there any thing I can do to get a clean HTML?
Best Regards.
Steevb replied on at Permalink Reply
Steevb
Try using :
$a->setAreaGridMaximumColumns(12);

Not:
$a->enableGridContainer();
pedroserapio replied on at Permalink Reply
pedroserapio
Thank you very much, worked very well!