How do I use includes in a laravel blade macro? - macros

I am designing a back end for a site in Laravel 4. It will have a number of data entry forms, some of which will be broken up into tabbed pages.
For an individual view it looks like this:
<ul>
<li id='menu0' class='menu active'>Main</li>
<li id='menu1' class='menu'>Secondary</li>
<li id='menu2' class='menu'>Advanced</li>
</ul>
<div id='tab0' class='tab active'>
#include('_mainfields')
</div>
<div id='tab1' class='tab'>
#include('_secondfields')
</div>
<div id='tab2' class='tab'>
#include('_advancedfields')
</div>
Ideally, I want to convert this to a macro:
Form::tabify(['Main','Secondary','Advanced'],'_mainfields','_secondfields','_advancedfields'])
A typical #include file would contain blade code like this:
<div class='formfield'>
{{ Form::label('dress_description','Description') }}
{{ Form::input('text','dress_description') }}
</div>
Writing a macro to generate the UL portion is trivial. However, I hit a wall when it comes to the includes. I can't see how I can extract that out to the macro. The macro itself can't contain an #include, as its written in PHP. A php include wouldn't work, as the blade code in the include wouldn't get processed.
So is there another way?

You can render them directly:
View::make('your-included-template');

Related

remove tag and add additional css class to data-sly-resource

Here's my code and I want to add another css class toggleable-content to the existing code:
<sly data-sly-resource="${'item' # resourceType='components/header'}"></sly>
This code would look something like this:
<section aria-label="aria label">
<ul class="row">
<li class="col">
<div class="body px-3">
<h2 class="h3">
body
</h2>
<p>body text</p>
</div>
</li>
</ul>
</section>
I want to remove section tag and add another css class toggleable-content to the <ul> tag. Below is what I'd like to achieve:
<ul class="row toggleable-content">
<li class="col">
<div class="body px-3">
<h2 class="h3">
body
</h2>
<p>body text</p>
</div>
</li>
</ul>
I was wondering how to use slightly to achieve the above? I tried something below but it doesn't work:
<sly data-sly-resource="${'item' # resourceType='components/header', cssClassName='toggleable-content'}"></sly>
Assuming the section markup is managed by the included resource (components/header) then you cannot do it directly. Indirectly, with AEM, you can pass a parameter (through request attributes) and retrieve it in the components/header model, then add the section conditionally (using data-sly-unwrap for example).
Or you re-organize your code and switch from resource inclusion to template calling and pass the parameter directly using data-sly-call.

How to locate multiple text element within class in Protractor?

For on my test i need to verify highlighted text (Lexington, KY) using my protractor test.
<li id="address" class="list">
<div class="content">
<small class="mb-1">
<span>
Suite # 278
<br>
</span>
**Lexington, KY**
</small>
</li>
How to verify highlighted text using css OR cssContainingText locator?
Actually Protractor creators have put great documentation in place , and pls read it thoroughly to gain good knowledge on usage of css & cssContainingText. I will answer your question in short here - Use element(by.cssContainingText('.content','Lexington'))
UPDATE 1:
In case you want to add an assertion .. do this - expect(element(by.cssContainingText('.content','Lexington'))).toContain('Lexington, KY')
For one I am confused because it seems like you are never closing the content div...is it closed after the li is closed?
Anyway...I would simply change the HTML so that you don't need some crazy convoluted mess of a selector. I would do it like this:
<li id="address" class="list">
<div class="content">
<small class="mb-1">
<span>
Suite # 278
<br>
</span>
<cityState>Lexington, KY</cityState>
</small>
</li>
function checkCityState(){
return element(by.tagName('cityState')).getText();
}
expect(checkCityState()).toBe('Lexington, KY');

Dashing - dynamically delete widgets

how can i dynamically delete widgets from a job(rb) in Dashing?
I am building the dashboard dynamically by sending a data to the erb file:
<div class="gridster">
<ul>
<% settings.servers.each do |data| %>
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
<div data-id="<%=data['webHost']%>" data-title="<%=data['name']%>" data-version="<%=data['Version']%>" >
</li>
<% end %>
</div>
Yes. I wrote a simple example job that can do just that here:
http://www.mapledyne.com/ideas/2015/6/30/delete-a-dashing-dashboard-widget
You basically just want to manipulate the Sinatra::Application.settings.history variable, but the code in that link should get you most of the way to where you want to be.
Or skip the post and go right to the gist file:
https://gist.github.com/mapledyne/6fb671c17c3f865309f3#file-delete-widget-rb
You can also generate parts of the erb dynamically if you don't know the widgets in the first place (more complicated), but it starts with the same - leveraging that same history variable.

Microdata (schema.org) - Event - empty startDate

Could anyone tell me what if the EducationEvent has not got startDate and endDate, because it is not known yet? If I set an empty value for it ($startIso is an empty string):
<meta itemprop="startDate" content="{{ $startIso }}" />
I get:
Error: Missing required field "dtstart".` error message in validator.
Here’s the code:
<div itemscope itemtype="http://schema.org/EducationEvent">
<h1 class="columns">
<span itemprop="name">{{ $courseTypesDescription->course_type_name }}</span>
</h1>
<div class="dates columns">
<div class="row">
<div class="large-5 medium-6 columns">
#if ($start != "")
<meta itemprop="startDate" content="{{ $startIso }}" />
#endif
<i class="fa fa-calendar"></i>
<span class="text">Start: </span>
<span class="data"> #if ($start != "") {{ $start }} #else N/A #endif</span>
</div>
<div class="large-5 medium-6 columns end">
#if ($exam != "")
<meta itemprop="endDate" content="{{ $examIso }}" />
#endif
<i class="fa fa-pencil-square-o"></i>
<span class="text">Exam: </span>
<span class="data"> #if ($exam != "") {{ $exam }} #else N/A #endif </span>
</div>
</div>
</div>
<article class="description columns" itemprop="description">
{{ $courseTypesDescription->course_type_desc }}
</article>
</div>
I agree with unor's answer but I would recommend you to use http://schema.org/Event rather than using http://schema.org/EducationEvent because Google is currently showing rich snippets on organic search for only those categories which are their in the Help Center document-
https://support.google.com/webmasters/answer/99170?hl=en
What you are implementing is a sub category of Event schema. You are correct in your way as you must be trying to specify the kind of events you have on your website. But as per my experience Google is not showing snippets for all available sub categories present on schema.org like schema.org/EducationEvent
Schema.org is format(syntax) of rich snippet markup implementation and apart from that schema.org has long list of Structured Data categories and Sub Categories. For all of those categories(http://schema.org/docs/full.html) Google doesn't show snippets. Only those appear with rich snippets on Google which are present in their official help center document as mentioned above.
This will increase the possibility to earn rich snippets for your website.
Your usage of Microdata with the Schema.org vocabulary is correct (if you make sure to remove the properties with empty values). Schema.org doesn’t define any required properties.
It’s just that Google Search, according to their documentation, seems to require the startDate property for displaying the Events Rich Snippet (and also location if it’s a single event, and url if your page lists several events).
If you don’t provide it, and if Google’s docs are correct, you won’t get (the chance for displaying) a Rich Snippet for your event. They probably require a future start date because they don’t like to display Rich Snippets for past events.
That doesn’t mean that you should omit the markup. It can be useful for other consumers (even possibly from Google, unrelated to their Rich Snippets), and Google’s Rich Snippets guidelines might change in the future, allowing for other types of Event snippets.

Symfony2 - Customizing buttons out of forms

I have problem with forms and page layouts. I render my page by:
{% block body -%}
{{ form(edit_form, {'style': 'horizontal'}) }}
<ul class="record_actions">
<li>
<a href="{{ path('organization') }}">
<button type="button" class="btn btn-default">Back to the list</button>
</a>
</li>
<li>
{{ form(delete_form) }}
</li>
</ul>
{% endblock %}
I have some style on ul record_actions. It looks like this: http://postimg.org/image/sby8jnojz/
My problem is with update button. I would like to put it into <ul> tags with 2 other buttons. Is there some possibility to put it outside of form? I like, how the form looks with {{ form(edit_form, {'style': 'horizontal'}) }}. So I wouldn't like to customize every part by {{form_widget}}. Or is there possibility to render all form and then render just this button?
Updated answer
Let's take a hypothetical controller method - where I have defined two forms edit_form and delete_form. Don't worry about these too much, they are just proof of concept. The important thing here is that I have two forms that I am sending to the template to be rendered:
// Foo\BarBundle\Controller\BazController
public function editAction()
{
// a placeholder 'edit' form
$editForm = $this->createFormBuilder()
->add('name', 'text')
->add('email', 'email')
->add('send', 'submit')
->getForm();
// a placeholder 'delete' form
$deleteForm = $this->createFormBuilder(['id' => 1])
->add('id', 'hidden')
->getForm();
// assign form views to template
return [
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
];
}
Next the template. We have two forms to render: edit_form and delete_form. There are a couple of issues we need to consider - rendering a form within a form is not allowed so we cannot render delete_form inside edit_form or vice versa.
However we can, as I explained below, with the HTML5 form attribute place form elements outside of a <form> context and still link them to that form (with the aforementioned IE* limitations). So let's do that, and suggest a workaround in due course.
The least invasive thing to do is to render the delete_form after the edit_form but place the edit_form delete button inside edit_form.
I don't know if you are using a CSS framewok to help you with layout - I am assuming Bootstrap 2.* here so you might have to update your markup - either way the idea should be clear enough:
<div class="row">
{{ form_start(edit_form, {'attr': {'id': 'edit-form'}}) }}
<div class="span4">
<ul class="record_actions">
<li>{{ form_widget(edit_form.send)}}</li>
<li><button id="delete-form-submit" form="delete-form">
Delete
</button>
</li>
</ul>
</div>
<div class="span4">
{{ form_rest(edit_form) }}
</div>
{{ form_end(edit_form) }}
</div>
{{ form(delete_form, {'attr': {'id': 'delete-form'}, 'method': 'GET'}) }}
The above HTML yields a layout similar to the following:
A few points of explanation:
I have created a two-column layout for the form. The .record_actions buttons are rendered on the left column - this is essential - but they are floated right using Bootstrap's .pull-right in this case.
Update button: the first thing I want to do is render the submit button in ul.record_actions where I want it: <li>{{ form_widget(edit_form.send)}}</li>
Delete button: I have not defined a submit button on the delete_form because I want to explicitly create it outside of the context of the delete_form, instead placing it where I have. Note that I defined a form attribute on this element called delete-form. This links this element to delete_form instead of edit_form: <li><button id="delete-form-submit" form="delete-form">Delete</button></li>
Remaining fields: in the second column I can dump all the remaining edit_form fields implicitly with {{ form_rest(edit_form) }}, as per #Kix's suggestion!
Delete form Finally, we render the delete_form outside the edit_form with {{ form(delete_form, {'attr': {'id': 'delete-form'}, 'method': 'GET'}) }}. A couple of things to note here - we are explicitly adding an id for the form with {'attr': {'id': 'delete-form'}. This is important as it is the attribute that the delete button refers to. In this case I also added 'method': 'GET' to test on my machine. You will probably want to leave this out (in which case it defaults to POST)
There you have it... This should help you define your preferred layout.
But, we still need to address IE. If you are using jQuery, you could add a click handler to the delete button, which we've assigned the id #delete-form-submit. Note that the following is a suggestion and is not tested:
$(function() {
if ($.browser.msie) { // #see: http://api.jquery.com/jquery.browser/
$('#delete-form-submit').on('click', function(e) {
e.preventDefault();
$('#delete-form').submit();
});
});
});
Now you need to worry about IE users with JS disabled... or not! ;) Hope this helps.
Original answer
I would argue that your issue is possible Symfony agnostic... Let me explain:
Do you create your form's submit button with the form builder? I assume so since you do not explicitly create one in the twig snippet you pasted above.
This is totally fine of course. I usually just define my Twig form templates like so, which I gather is the older way to do it (since the 2.4 docs don't appear to suggest the following):
<form class="form-horizontal" action="{{ path('foo_edit') }}" method="post" {{ form_enctype(edit_form) }}>
{{ form_widget(edit_form) }}
<input type="submit">
</form>
This way is totally acceptable in my view - you just don't define the submit button.
Of course this does not solve your problem, because you want to "break out" of the form. But you can actually do this with HTML5 with the form attribute, which allows you to link disparate tags to a specific tag. A generic example:
<form id="foo">
<label>Username</label>
<input type="text" name="username">
</form>
<ul>
<li><input type="submit" form="foo">
</ul>
Note that the submit button is outside form#foo but the form attribute still links to it.
Obviously its usefulness is restricted to the range of browsers you want to support, as it's a HTML5 feature.
EDIT
I checked - it has pretty wide browser support, except.... drumroll IE. Up to and including IE10 apparently. I would assume that this is a dealbreaker unfortunately.
kix's approach above could work well however, print out the individual form widgets you want explicitly and then use form_rest. I would add to this and say it might not exactly work with the HTML layout you have above - iirc you have to print out any fields explicitly before you call form_rest.
You can always render some widgets in places specific to your layout using
{{ form_widget(delete_form.yourWidgetName) }}
and then let Symfony complete the form with
{{ form_rest(delete_form) }}