Best solution for managing navigation (and marking currently active item) in CakePHP - list

So I have been looking around for a couple hours for a solid solution to handling site navigation in CakePHP. Over the course of a dozen projects, I have rigged together something that works for each one, but what I'm looking for is ideally a CakePHP plugin that handles the following:
Navigation Model
Component for handing off to the view
Element View Helper for displaying the navigation (with control over sublevels displayed and automatically determining the "active" item based on URL and/or controller/model/slug
Admin pages for managing a tree of navigation
Any suggestions for an all-in-one solution or even the individual components would be very appreciated! Or even suggestions on how you have handled it in the past

We had this issue at work recently and i ended up whiping up a helper that would take query from the contents table and convert that into a menu. As it needed to become more flexible the code got worse and worse up to the point where i am currently rewriting it.
Don't hold your breath though as i will be taking my time to make it work right as it needs to be very flexible but it cant be confusing to use.

Related

testing a component with complex angular components nested inside using PageObjects

Our Application has components which consume components with consume components of varying complexity. So i just want the input on the page, to validate when an object is set that the text is correct. The issue is that it is one of these subcomponents.
My colleague told me that there is 2 ways to do this, The first is to use Page Objects, and Chaining annotation to find it on my page, and then find the next id etc until my input is found. It requires me to look through another teams' Component Markup to narrow it down to the input i want to leverage. I dont believe I should have to go into another component definition, or a definition of a definition to get the appropriate chain to get this arbitrary input. It starts to create issues where if a lateral team creates changes unbeknownst to me, my PO will be broken.
The other option my friend asked was to use fixture.query to find the component. This would be as simple as:
fixture.query((el)=> el.attribute["id"] == "description",
(comp){
expect(comp.value, value);
});`
Using Query looks at the markup but then will automatically componentize it as the appropriate SubComponent. In this case, comp.value is the value stored in the HTML. So, if i did something like:
fixture.update((MainComponent comp) {
comp.myinput.value = new Foo();
});
Then I am setting and getting this programmatically, so i am a bit unsure if it properly would reflect what is on the screen.
Whats the best course of action? It seems PO would be better, but im not sure if there is a way around having to deep query for input boxes outside of the component i am testing.
Thanks
I don't think I have a definitive answer for you but I can tell you how we do it at Google. For pretty much any component we provide the page object alongside the component. This is twofold it is for testing that widget, and also so we can have this as a shareable resource for other tests.
For leaf widgets the page objects are a little less fleshed out and are really just there for the local test. For components that are shared heavily the page object is a bit more flushed out for reusability. Without this much of the API for the widget (html, css, etc) we would need to consider public and changes to them would be very hard (person responsible for making the public breaking change needs to fix all associated code.) With it we can have a contract to only support the page object API and html structure changes are not considered breaking changes. At times we have even gone so far as to have two page objects for a widget. One for the local test, and one to share. Sometimes the API you want to expose for a local test is much more than you want people to use themselves.
We can then compose these page objects into higher level page objects that represent the widget. Good page objects support a higher level of abstraction for that widget. For example a calendar widget would let you go to the next/previous month, get the current selected date, etc. rather than directly exposing the buttons/inputs that accomplish those actions.
We plan to expose these page objects for angular_components eventually, but we are currently working on how to expose these. Our internal package structure is different than what we have externally. We have many packages per individual widget (page_objects, examples, widget itself) and we need to reconcile this externally before we expose them.
Here is an example:
import 'package:pageloader/objects.dart';
import 'material_button_po.dart';
/// Webdriver page object for `material-yes-no-buttons` component.
#EnsureTag('material-yes-no-buttons')
class MaterialYesNoButtonsPO {
#ByClass('btn-yes')
#optional
MaterialButtonPO yesButton;
#ByClass('btn-no')
#optional
MaterialButtonPO noButton;
}

Converting an admin UI design into Ember components

I'm wondering if their is a tutorial on how to convert an admin UI into Ember components? What are the best practices? For example, the following UI framework: http://egemem.com/theme/kode/v1.1/blank.html
Has a main navigation, two sidebar menus, a content body and a footer. What would the best approach be to converting this into components? My initial thoughts, with very little Ember experience and based on the scattering of documents I've been able to find, I get the sense that creating unique components for everything would be the best approach. By everything I mean, everything that is unique. For example, if we take the navigation bar, there would be a parent component for the navigation as a whole and then child components for the sidebar collapse/expand buttons, the search, the drop down menus, notification indicator, etc. There would also be additional parent components for the right hand sidebar, left hand sidebar, and footer.
Looking at one of the sidebars, for example the left one, could that be one component or would child components be required here as well?
The right hand sidebar is more complex with tabs. In this example, would it make sense to break this sidebar into child components for the 3 different tabs? Would you want to go as far as a unique component for different elements of the tabs themselves. For example, each notification type would be a component?
Thank you in advance for your assistance send I look forward to understanding how best to handle this type of scenario.
Cheers,
Dan
Yes, your idea makes sense. It is a good practice to create components (or handlebars) for everything that repeats several times. I would not create different components for different tabs if they are not re-used.
Do not forget to not re-invent wheel. There are a lot of available components, take a look at Ember Observer or other similar resources.
Components are great but some the things you mentioned, like sidebars, might make more sense as nested routes, depending on what's in the sidebars.
Rock 'n Roll with Ember is a fantastic book that takes you all the way through the process of building an Ember application. It's the book I always recommend to people just getting started with the framework. http://balinterdi.com/rock-and-roll-with-emberjs/

What is the best way to fin and use a template in cakephp 3

i'm new in cakephp and I have started with version 3. I want to build a beautifull app and because I'm not good in design, I would really like to use a free template or buy one that I can use within cakephp.
So, I would really appreciate all your propositions and ideas or best practises. The easy way will be the best because I don't have a lot of time with this project. Thank you in advance.
If you don't have a lot of time like you mentioned, the easiest way to go ahead and get started is to paste a lot of the code in your default.ctp layout inside of src/Template/Layout/default.ctp.
You'll notice there are some lines of PHP already in there that are relevant to fetching blocks of css, meta tags, and other bits of code that could potentially exist throughout your project.
Find the main layout of the theme your trying to use - the one that will be consistent across most of the pages. That's the one you'll use for default.ctp. Compare what's already in default.ctp and make the comparable adjustments around the HTML in that document while keeping the important lines of PHP there as well.
For other important pages like a login or registration page, just create a new document for those, like 'login.ctp', then inside the function that loads the page (maybe 'login' inside of UsersController'), change the default layout with this line of code:
$this->viewBuilder()->layout('login'); // without the .ctp ending
This way you can create one-off layouts that don't really match any other page.

How to handle a 'signed in' versus a 'default' homepage in Sitecore

I am building a brand new website in Sitecore and I am looking for advice on the following scenario:
My site has 2 version of its homepage. Both are quite different. The layout is the same, but most of the components and sublayouts on it will change depending on whether the user is logged in or not.
Does anybody has a suggestion of a good practice, or way to do that in Sitecore? My basic requirements are, have a single URL for both (the website root, it is a homepage) and do not harm the content author experience.
My thought so far was:
Use of personalization to control the components to be displayed (Concerns: performance and the content author experience he woudnt have to change component by component to see both versions)
Use of two item in the tree and intercept a pipeline to resolve the right item at the right time (Concerns: the content author would have two home items to maintain *not actually a big problem)
Does anybody has any other approach or considerations on those I listed?
Thanks
An alternative solution would be to make use of devices, and use a pipeline to switch devices if the user is logged in.
Set up your Device in Sitecore to use the default layout as a fallback so it does not affect other pages in your site (and they continue to work as expected). You are then able to set different sublayouts and components for that Item (directly or in Standard Values for the template) for each device. You can make use the VaryByDevice caching option to make better use of the Cache.
Your content editors can also switch between the devices easily in the Page Editor from the ribbon. Any further customization you need in other areas of the site, such has switching out a single component, can be run using a Personlization Rule taking advantage of "where the current device compares to value".
It does sound like you have the need for personalization based on authenticated status, so I would recommend staying with the built-in personalization interface to avoid confusion. Authors will have been trained during Sitecore training on how to use personalization, and introducing an alternative method for accomplishing the same thing could lead to a less-than-optimal experience for the author.
To address your concern of the author needing to view components by toggling each one, I would recommend installing the Experience Explorer module. You can create presets that meet your rules on your presentation and then the author can preview the site for different 'experiences'.
If you have a single URL for the home page, it is more straight-forward to go with a single item, so I would definitely advise against having two home page items that are being resolved by the same URL.
You mentioned a concern for performance, so I would recommend you making sure that you enable your sublayout caching settings. In your case, varying by Data may be the way to go, given you would personalize with two sets of datasources.
In the past I have used the following crude technique:
Make two components, one for "logged in" and the other for anonymous.
Each rendering has just one line, a single placeholder, either:
<sc:placeholder key="logged-in" runat="server" />
or
<sc:placeholder key="anonymous" runat="server" />
For "logged in" I make a personalisation rule which hides the component if anonymous, and for the anonymous component I make a personalisation rule which hides the component if the user is logged in.
I then nest all the components under the correct placeholder key.

Sitecore Content Tree Architecture

Let's say there exists a presentational component in a project that renders an unordered list (called ListRenderer, perhaps.) We have a couple options of supplying data to any given ListRenderer on a page:
Have a TreeList (or TreeListEx) field on the content item, and have ListRenderer read from it.
Supply a DataSource (or other Parameter) to the ListRenderer via the presentation details.
I usually avoid #1 in my projects because it binds Sublayouts to templates, which gets quite messy. If you go down that path, eventually you'll have fields to support every potential sublayout in your project.
So my solutions tend toward option #2, which gets rid of that problem. It does, however, come with its own bag of questions. Where do I put these various "Lists" for a given ListRenderer to use? To maximize reuse and sharing, I usually create a components directory near the site root that contains all these types of things, if I predict the Lists will be shared. This seems less findable and harder to use for the content author, who suddenly have no idea where the source for their ListRenderer is unless they know how to crack open the presentation details (which is slightly advanced for my average user).
If I feel like Lists won't be shared, and are very specific to the page, I'll put them directly underneath the item in question. This has a tendency to muddle up the content tree, though, and any dynamically generated navigation sublayout then has to check for whether or not an item is an actual page before it generates the link to it. The more I work in Sitecore, the less I use this approach, but it seems easier for the content author. There is much easier access to information when you use this approach.
Is there any industry-accepted way of approaching this problem? It happens in projects all the time, and in my head I struggle to balance technical and content authorship concerns in situations like these.
Great question. I've used all the techniques you mentioned, depending on the audience and specifics of the project. The problem is that, as with all things Sitecore, they are all valid ways of achieving the same goal and you will struggle to find one answer that will work in every situation.
I almost always use #2 as well, but some content author retraining maybe necessary and make sure you add in restrictions to what the content author is able to select as a target. I have (within the same project) structured the items near the root (in a shared content folder) and under the item in question, depending on what I felt would provide the best context.
Also, if other child pages would exist below the item as well as the list items, then I would put the list items in a separate folder (with a common "list items" icon") and re-order it to be the first item for separation and clarity.
If you want to use any kind of personalization and DMS then you will need the ability to switch out the datasource anyway so you shouldn't hard code locations.
You might also (if you have not already) want to consider using:
Convert Data Source Paths to IDs Using the Sitecore ASP.NET CMS
- Useful if you need to restructure your content at a later date
Queryable Datasource Locations
- Useful for multi-site situations when you need to make clones, or setting as the default datasource value in Standard Values when the lists are directly below the item but gives you the flexibility to change it.
I prefer using querable datasources personally, I find the xpath syntax more logical.
As Mark has commented, there is no real industry standard.
I feel like this is something that needs improvement.
Especially when you are using the DataSource option, things become less transparent to the editors and as the size of the site grows, so does the complexity.
All I can tell you is how I would do it, which is most likely much like how you are doing it.
1) For overview pages like news, events and faq items, I will put the items underneath the overview item and use the NewsMover shared source module to auto-create a hierarchy.
2) I will create a Global site that contains items that are shared across sites or pages. DataSource items for components will be put in here.
3) For components that are present on the standard values, I will add a list field to the template (for example, when you display related items on a content page)
Most often it's a logical choice and sometimes it's just a matter of taste.
I'd like to add that I've written a blog post on how to have datasource items created automatically for components that are set on standard values. That might help you if you are using those.
Edit:
"I usually avoid #1 in my projects because it binds Sublayouts to templates, which gets quite messy. If you go down that path, eventually you'll have fields to support every potential sublayout in your project."
Today I've blogged about a method of hiding fields and sections in the content editor if there is no sublayout set on the item that requires those fields, which helps to prevent the mess of having a lot of unused fields on your items.