Block Creation Tutorial

I had a look at the stickied thread, but I noticed that even the updated Block tutorial link is dead again.

I'm interested in getting started with writing a C5 Block, but have nowhere to really get started.

Lifecycle, accessing existing functionality like image-pickers, how or what exactly I'm defining... Lots of questions.

Any help is appreciated!

View Replies:
jbx replied on at Permalink Reply
There's a whole section on blocks here:

C5Omega replied on at Permalink Reply
The items found there serve nicely as a kind of introduction. But I'm having a difficult time wrapping my head around the various lifecycles of a Block and how to make use of Concrete5's built in functionality (images, rich text editor).

I've been crawling over existing Blocks (content, slideshow, etc...) and it really isn't sinking in with me how I should architect my Block.

I understand the overall premise going on here, it's quite sensible. But it's the actual act of prompting and saving all the data that is involved with a block that seems to be confusing me.
jordanlev replied on at Permalink Reply
What kind of block do you want to make?

The general lifecycle of the add/edit stuff is that whatever fields you have declared for the main table in db.xml will automatically be available to your add/edit.php files by their name. For example, if you have a field called "description" in your db.xml file, it will be available as the variable "$description" (without the quotes) in the add/edit.php files. You put these values into various form fields, depending on the type of data it is -- so if it's a VARCHAR field in the database, you use a text field. If it's TEXT in the database, use a textarea field, etc. You can automatically output these fields using the form helpers. For example:
<?php echo $form->text('description', $description); ?>

As for saving the data, as long as the field is defined in the main table of db.xml (btYourBlockName), then concrete5 will automatically save that form field to the database for you when it's submitted.

Things get a little more complicated when you have different kinds of data, or if you want to save data to another table besides the main block table. For more complicated situations you need to put your own code into the block controller's save() function to save the data to the database -- see this post for some sample code:

Hope that helps, and feel free to post back with more questions.

C5Omega replied on at Permalink Reply
Alright, so I'm getting a bit of progress here. But I'll bounce what I'd like to do here and get the best approach from you...

I basically want to take in multiple content sections and store them for each instance of the Block I'm creating.

I was thinking some kind of ajaxy input where I have the regular Content block input up top and then a list of each of the blocks so that they can be clicked and edited. Or a new and add button to append one to the bottom of the list.

Aside from the textarea input which I've got going now, does C5 have any standard controls to help me out there? Lists with drag and drop sorting? Or am I basically building this myself the rest of the way?
jordanlev replied on at Permalink Reply
C5 only provides the application structure (add/edit/view/save), basic HTML form controls (textbox, textarea, dropdown, etc.) and a few advanced controls (TinyMCE WYSIWYG editor, file selector).

Other than that, you're on your own (for example, you need to implement drag and drop list sorting yourself -- although you can and should use the jquery library that's included by default -- but you need to handle the serialization of the sort order and saving it to the database yourself).

As for what you're trying to do specifically, it sounds like something that is going to be very complicated and maybe not the best approach -- can you provide a little more detail about what you're aiming for? Is there a reason you need several blocks inside one block? Why can't you just use a normal content area in your template? Putting blocks in an area is "the concrete5 way", and trying to work around that is going to be challenging (it's not impossible, but will probably require a decent amount of work, and is definitely not a good learning project if you're new to the system).
C5Omega replied on at Permalink Reply
Hm, I think you misunderstand how I'm using the multiple blocks.

I'm creating a slideshow using a different javascript slideshow engine. So I want to have multiple content sections that it can run through. The output is going to be pretty simple actually.

Just one content section after another. Only that I want to wrap it up nicely in a block and have the libraries included by it, etc...
jordanlev replied on at Permalink Reply
Is this slideshow for images or for any kind of content?
And when you say "multiple sections", do you mean each section is a slide, or there will be different groups of slides?

If you are only wanting to display images, the easiest thing to do is use file sets from the file manager (there are many examples of how this works in both the built-in "slideshow" block, as well as some of the free image galleries on the marketplace).

But it sounds like you want to show content from a WYSIWYG editor. I think you will need to let the user add one at a time -- look at how the built-in slideshow block works when you create a custom gallery -- it lets you add new images and each one you add gives you another file selection control. You could do something like this except instead of showing a file selection control, show the WYSIWYG editor control.

There are some other ways to achieve this, though -- I've done this in the past, and the way it worked was that each piece of content was a sub-page beneath the page that has the slider, so users could just add a new page from the slider page, choose the "slider content" page type, and put in any kind of blocks and arrange them with area layouts. Then the slider uses a PageList object in its controller to retrieve all sub-pages of the appropriate page type and load them into the slider via ajax (jquery load() method).

Another way to do it would be to let the user choose other pages in the site, and you could retrieve the content from a specific area on those pages. This would be a bit more complicated but if the content you're showing in the slider is also going to exist elsewhere on the site, it would make it easier to manage for the site owner.

Hope this makes sense -- feel free to reply with further questions if you'd like more assistance.
aubin replied on at Permalink Reply
sorry for bumping an ancient (by internet standards) thread, but i'm in the same boat c5omega was and am hoping jordanlev or some other kind soul will have some advice for me...

here's the thing. I'm working on a website for a practitioner who essentially sells her time and knowledge of her craft. think like massage therapy for the purposes of discussion, though that's not even close to what she actually does.

Ultimate goal is to have customer come to website and book a block of time right there, and pay via paypal. the 'pay' part is going to (eventually, when i can afford it, this is a personal/friend project i'm paying for out of pocket) be done through the standard c5 commerce plugin. It's the "book a block of time" we're focusing on at the moment.

My vision is that the customer comes to the site, clicks on some calendar widget on the day he wants, which shows him the remaining available times, chooses one to add to his cart and checks out. for this to work we need, essentially, three things.

first, a way in the admin interface, or perhaps simply when editing the block? to say 'these are the times she is actually available' - and it needs to be pretty easy to specify, as her schedule is pretty fluid and changes rapidly - so i can't have her spending a ton of time updating her availability on this thing or she'll never use it. Ultimately I might (future future) think about pulling this piece from a google calendar or something somehow if i can train her to use one. but for now, let's just say the widget needs a way to specify, for each day of the week, what hours are available for practice, in an easily editable/changeable/usable format.

then, when the user comes to the site and on this page sees the calendar widget, if there are lessons booked on a particular day, he should see them on the calendar - and be able to pick from any of the remaining one hour blocks of time for that day. when he picks an empty block and enters his contact information, it is essentially a product which goes into his cart and is paid for at check out.

and thirdly, since each hour (maybe the granularity of block size should be specifiable come to think of it...) is essentially a product, we need some way to add and remove them on the fly when the schedule is changed and, essentially, to interface all these bookings with the c5 commerce machinery without anyone wanting to die. ;-)

the user should also be allowed to cancel previous bookings up to 24 hours in advance, and the editor which allows the booking availability schedule to be changed should scream loudly if she's got a client booked during a time she is trying to set to unavailable.

ambitious vision, i know. some basic ideas/vague notions of where to start, but some more experienced folks who can help me simply/point me in the right direction would be AWESOME...

Thanks everyone for reading!
jordanlev replied on at Permalink Reply
What you're asking for is (as far as I can tell) a fairly complex custom module. Are you a programmer looking for some guidance on how to architecture this kind of module within the context of Concrete5? Or do you not have much programming experience and are looking at this as a learning project?
Or do you not really want to dive into programming at all? If this is the case, I think the ProEvents addon will get you part of the way there:
...and I would contact the author of that addon (ChadStrat) and ask if he'd be able to give you a quote for doing the custom work you've outlined in this post.

Best of luck,
aubin replied on at Permalink Reply

I am actually a programmer, so am capable of probably doing this and was looking for architectural guidance, yes. HOWEVER, I am not an expert php programmer and I've never written anything custom for c5, so there would DEFINITELY be a learning project AND I have been a PM before so I recognize the value of buy vs build and so was really just trying to estimate the man hours involved and overall project direction. So, in short...all of the above? LOL. I really like pro events so far, so I'll track down ChadStrat, but in the meantime if you have suggestions on architecture i am all ears because I have a feeling sir ChadStrat is too expensive for me.

Thanks for your time and response,

ScottSandbakken replied on at Permalink Reply
You could do something like this by creating a form where the user fills out their name, email, and selects a desired date and desired time slot (I would use a select box for this) using a standard C5 form. If the time slot is not available, your client would need to email them for a different time, so the viability of this option depends on the number of conflicts you client would have to deal with, but it could be a quick compromise while you wait for a better solution to be built. You could even add Pro Events to list your client's schedule below the form so the user can see your client's availability before they select a time slot.
jordanlev replied on at Permalink Reply
I think that's great that you're wanting to use this as a learning experience. I don't want to dissuade you from that, but I will caution you that the functionality you're describing is really way more complex than you seem to be envisioning (especially the part about doing it for free for a friend). If I were bidding this for a client, I'd probably say something like 80-120 hours (and keep in mind I've been programming professionally for over 10 years now). Calendar UI's are a tough nut to crack -- most people don't get it right. And that's just the design side of things (not the coding of it, which would require a lot of javascript to make work properly). All the other stuff about product management and payment integration and whatnot is also a lot of work.

What I'd suggest is breaking this down into smaller pieces. Think of what the most basic functionality that accomplishes the business goal is (for example, the contact form that @NetJunky279 suggested). Then work on improving one piece at a time.

I really can't give you much more guidance than that, because what you're describing is a *huge* swath of features. I wouldn't even worry about using Concrete5 for this -- if you really do want to attempt it, just build it as HTML/CSS/Javascript first. Then add a simple PHP/MySQL backend to save data. Then once you have all that working, bring it into C5.

Uhh... good luck?
mnakalay replied on at Permalink Reply
I'm really surprised Jordanlev didn't mention that (modesty maybe) but as far as I'm concerned, the best place to learn something about building blocks with C5 is to install his Designer Content add-on, create a block with it and have a look at the code.

I pillage his code regularly (no shame whatsoever here ;) and I would advise anybody wanting to learn about C5 coding to do it too.
jordanlev replied on at Permalink Reply
Thanks for the shout-out @mnakalay.
The reason I didn't mention it in this convo is because the scope of what Designer Content does is very limited compared to what the OP is asking for. So you're correct that it would give him a good idea of how to learn to integrate his working functionality into the Concrete5 system, but that's probably 5% of the overall work that will be involved for what he's talking about (in my opinion, of course, which very well may be wrong -- just the impression I get off the top of my head).