Check it out: custom block creator!

Permalink 7 users found helpful
*** This package is now available on the marketplace:http://www.concrete5.org/marketplace/addons/designer-content/... ***

I've made a "custom block creator" which aims to solve the problem of allowing you (as the site designer) to specify exactly how some content should look. For example, imagine you're building a site for a client, and the design calls for each portion of content in the main area to have an <h2> heading, followed by some text, with a small image thumbnail floated to the left. Unfortunately, there's no easy way to ensure that the content gets inputted by client in the proper way without creating your own custom block -- but that can be a hassle (especially if you're not a developer), and there are a lot of glitches in getting the TinyMCE editor to work well with image controls.

This package solves that problem by creating the blocks for you! All you have to do is install this package, go to its dashboard page (it's called "Designer Content"), enter some info and add fields. Currently, you can add textboxes, image fields, and a TinyMCE/WYSIWYG Editor. Also, you can enter HTML that surrounds each field. For example, if you want users to add content with an <h2> heading, you can create a block with one textbox field (wrapped in "<h2>" and "</h2>" tags), and then a WYSIWYG field. Or if you want images to always show up at a specific size, you can set thumbnail widths and heights on each image field.

I've tested this out a little bit and it seems to be working ok. But it has not been thoroughly tested yet so you probably don't want to use it on a production system!

I will be placing this on the marketplace soon, but wanted to get some feedback from the community (and some additional testing) first. If you try this out, please post back here with your thoughts on what is useful and what is confusing, and of course if you run into any bugs please let me know. Also, if someone with more artistic skills than me wants to create an icon for the package, that would be much appreciated.

Enjoy!

-Jordan

jordanlev
 
kino replied on at Permalink Reply 1 Attachment
kino
Great!

but few messages none t() .

1) /packages/designer_content/single_pages/dashboard/designer_content.php
2) /packages/designer_content/generator_templates/controller.php
kino replied on at Permalink Reply 1 Attachment
kino
I make messages.po .
kino replied on at Permalink Reply 1 Attachment
kino
made a Japanese translation by member of Usagi-project(concrete5-japan).

Thanks @tao_s @HissyNC .

Translation is completed in about 10 minutes because 'kino's quick localization' using.

http://www.concrete5.org/community/forums/internationalization/andq...
jordanlev replied on at Permalink Reply
jordanlev
Thank you Kino for the translation! I will add this before it goes to the marketplace.

1) I did not use t() for the intro text in "/packages/designer_content/single_pages/dashboard/designer_content.php" because I am going to change it after people test it and tell me what is confusing and needs more explanation.

2) I think you are wrong about "/packages/designer_content/generator_templates/controller.php" -- there are no messages in there. When you create your own block you can type in any language for the field labels so you can make a block in Japanese and this will come through (I think). Please correct me if I am wrong about this.

-Jordan
kino replied on at Permalink Reply
kino
1) OK.

2) Sure, no problem is so even without.
Tao replied on at Permalink Reply 1 Attachment
Tao
I had not updated to translate a bit part.
12345j replied on at Permalink Reply
12345j
this looks great! is there a way to use it in themes (to require an h2 tag or something like that?)
jordanlev replied on at Permalink Reply
jordanlev
Yes, that's the whole point of it -- add a textbox field and put "<h2>" in the prefix HTML, and "</h2>" in the suffix html. Now when the user edits your block, they will just get a textbox to type in some text, but whenever it is displayed on the site, that text will always have the h2 tag around it.

Or am I misunderstanding your question?
12345j replied on at Permalink Reply
12345j
Badly phrased qUestion: wondering how o call it in themes
jordanlev replied on at Permalink Reply
jordanlev
Still not understanding the question. The blocks that this package creates are exactly like any block you would create or download from the marketplace -- they are not tied to the package at all (the package is just a dashboard page with a bunch of code that writes out files to your blocks directory -- but once the files have been written they are no different than any other block you would make or install).

So you don't call it in themes, but rather your users add the block to areas in your themes.

I suppose you could "hard-code" the block into your theme template just like any other block, but that doesn't really make sense because you could just hardcode the HTML into the theme (since it's not editable by the user anyway).
12345j replied on at Permalink Reply
12345j
I was understanding concept worng, freeing Andrews post it mad sense.
kirkroberts replied on at Permalink Reply
kirkroberts
Jordan, your myriad contributions to this community make me wanna cry with happiness. I'm really looking forward to checking this out soon.
michaelfm replied on at Permalink Reply
michaelfm
Wow! This is a huge speed up. Thanks a lot Jordan.

Found a litte spelling mistake: "Mising required text:"

If I define an image field to be required, I can insert that new block even when there is no image selected.
jordanlev replied on at Permalink Reply
jordanlev
Thank you for the bug reports -- both items have been fixed.
Tao replied on at Permalink Reply
Tao
Wow!
This block can be made even if PHP is not good people!
andrew replied on at Permalink Reply
andrew
This is really, really cool. Definite time saver when you're using simple blocks to make a nicely designed site. For example we built a custom contact block that had a bio image, name fields, text field and a rich text editor. This would be perfect for that. Very nicely done. I can't find too much wrong with it, to be honest with you - although I'm not sure why there's a limit on TinyMCE fields (unless you were finding bugs with including multiple ones.)

Very nifty work.
jordanlev replied on at Permalink Reply
jordanlev
Thanks Andrew. Your use case is a perfect example, I will definitely mention something like that in the marketplace description.

The TinyMCE limitation is because I assumed I couldn't put two on the same page. The way it's set up is super-duper complicated (especially with all of the C5 tie-ins). It took me so long just to figure out how to avoid conflicts between TinyMCE and the Asset Library image control that by the time I was done with that my brain was melted and couldn't think about going back into the trenches. (I do have some fixes for this now though -- will try to submit a patch soon).

Once I accepted this limitation, though, I realized it actually might be good from a user point of view. I can't really think of a situation where you need more than 1 WYSIWYG editor per block, other than abusing the system and making all of the content on your page a single block (which I obviously do not want to encourage)!
Mnkras replied on at Permalink Reply
Mnkras
I think making it more modular would be a lot nicer.
like in the Libraries colder having a block_generator folder, that has image.php wysiwyg.php etc so updates are easier (don't lose customizations)
jordanlev replied on at Permalink Reply
jordanlev
That's an interesting idea Mike. There were a lot of things I had on the list of possible features, but wanted to keep it as simple as possible for the first version. Also, I'm going to put this up on github soon which will facilitate much easier modifications by other programmers such as yourself.

When you say "updates are easier", do you mean updates to the generator package and templates, or updates to blocks after they've been generated?

On the other hand, I was also thinking that this package could be useful as a skeleton block creator (just generate a block with one textbox and modify it from there). Looking at it in these terms, you almost don't need custom generator templates because you can just modify the outputted view.php file after you've created the block (of course you'd have to do this for every block you made, so I see how your idea can have benefits).
Mnkras replied on at Permalink Reply
Mnkras
well i was thinking for more when you update the package, so if you just made modifications to lets say image.php and only wysiwyg.php was updated you don't have to make modifications again, compared to 1 file
Mnkras replied on at Permalink Reply
Mnkras
also, you can install the block after its created,
(maybe make a checkbox)

$bt = Loader::model('block_types');
$bt->installBlockType($handle);
jordanlev replied on at Permalink Reply
jordanlev
This was definitely on my "phase 2" list. Although the one downside to automatic block installation is that it hides the fact that the generated block is just like any other normal block. I feel like going through the installation process makes it very clear that this is a block that is not tied to the original generator package, that it can be modified or uninstalled at any time, etc.

I actually think the most useful additions to this package would revolve around adding new control types -- like a "link to internal page" (with a sitemap selector in the edit.php file), adding a lightbox to the image, or just a plain old "text area" field (not TinyMCE).

Maybe adding generator templates (and sub-templates for each control type that would feed into the the generator dashboard, edit.php, and view.php templates) would help this as well.

But really I just didn't want to overcomplicate things. The ideal user of this is designers who understand why they want it but aren't necessarily technical enough to build their own block -- and hence I want to make sure things stay as simple and straightforward as possible.
andrew replied on at Permalink Reply
andrew
I would agree with your assessment, Jordan. I think this is most useful to developers, actually: people like me and you and others here who already can build blocks, but want something to jumpstart them for a client project. A time-saver, basically.

To that end, I think adding more control types is more important than a template language for output, or automatically installing the block. To me, I think the add/edit interface that you're generating is perfectly acceptable, but the view layer is probably never going to work without some customization (which is fine – that's the point of these blocks, after all. Otherwise, just use a Content or HTML block.). So for me it's mostly useful as a tool that helps me get something done more quickly: if I know a client needs a special block that contains three files and a link to a page (for who knows what reason) I can quickly create that block, and then customize the view layer. When I'm done I install it and make sure it works, and then keep it. This saves me from having to create that entire block from scratch.
imran replied on at Permalink Reply
Hi,
I have Created a block on this package which have a text field, and a WYSIWYG Editor, which work perfectly in creating. But when i want to edit this block it will create new record in database instead of edit/updating the old one. So is this a bug or not have the functionality of editing, please give me some clue to fix this problem.

Thanks....
Mnkras replied on at Permalink Reply
Mnkras
That is not a bug, each block edit gives in a new bID
imran replied on at Permalink Reply
Hi Mnkras,
Thanks for your reply, But i want to only edit the record, and not to create new one, because i have function which display those records from table, so repeat those edited records..
jordanlev replied on at Permalink Reply
jordanlev
This is the way Concrete5 works and unless you want to rewrite the system there is nothing you can do about it.

There is probably a better way to achieve this using the API to get the block from the page. Can you explain what it is you're trying to do exactly?
imran replied on at Permalink Reply
Hi, actually i have created a custom blocks, which work is to display inner-pages, in a page, i.e the block can store two fields a "tab name" and a content text area. which is working perfectly on creating new block and storing.
Then to display the inner pages i create a method to retrieve all the block which is related to this page, and display on page. But the concrete core functionality on editing and deleting is a little bit confuse for me, i.e: there is multiple record exist which i have deleted or edited..

Now how to do this, by deleting delete the record from table and by editing updated the old one, simply.
jordanlev replied on at Permalink Reply
jordanlev
There are better ways to do this. If you delete block records from the table you are seriously messing with the system and will probably create lots of errors in other places.

Are you familiar with the Page List block? The Page List block is made for this kind of thing -- showing other blocks on another page. You can customize its template to show different attributes and even content from other pages -- I have a sample custom template for this with lots of examples of how to pull out page content here:
https://raw.github.com/jordanlev/c5_clean_block_templates/master/pag...

If you don't know how custom templates work, search the forums about it -- it is a vey common thing to do when building a Concrete5 site so there is plenty of explanation out there.
jordanlev replied on at Permalink Reply
jordanlev
Why do you care what the bID is? What are you doing in your code that is relying on this?
Quaro replied on at Permalink Reply
This looks really useful.

I'd almost want to go one step further and have a little mini template language for the output of this thing, but as it stands it is pretty awesome.
jordanlev replied on at Permalink Reply
jordanlev
Thanks!

I think this is an interesting idea, and it would certainly make the dashboard interface a lot easier to code (just provide some %%template_tags%% for each control type and the whole thing is entered into a big text field). But I also think it might over-complicate things for the user.
Of course on the other hand, it might actually be easier to understand what the output will be like in terms of a template (as opposed to having to wrap your head around the "prefix" and "suffix" html concept).

Definitely something to think about.

If you could post back some more details about how you think this templating language would work (in terms of how the end-user would use it to generate blocks, not the technical implementation), that would be much appreciated.
RadiantWeb replied on at Permalink Reply
RadiantWeb
I think the UI could really use some help, but this is a really great idea Jordan. Good job man.

C
jordanlev replied on at Permalink Reply
jordanlev
Thanks Chad!

Can you please tell me how you think the UI could be improved? I definitely took the approach of "what can I implement as easily as possible while still being somewhat usable", so I'd love to hear your thoughts about how it could be better.

(And of course if you'd be willing to help, that would be great too -- but even if not, just hearing your ideas about it would be useful).
RadiantWeb replied on at Permalink Reply
RadiantWeb
most notably, when creating your block and adding fields. using something that straightens that out like the search table formatting. And then using the assets library for images such as add/delete/edit, and then also the move up or down can have arrows. and you can use the assets library for that. example:
<img src="<?=ASSETS_URL_IMAGES?>/icons/add.png" width="16" height="16"/>


C
adamjohnson replied on at Permalink Reply
adamjohnson
Very neat idea. Seems like the perfect tool for less PHP savvy people (designers, myself included) to "force" end users to enter the correct fields (I'm thinking things like a Q&A block, or really anything that would require the use of typography.css for custom styles on an element--something end users would struggle with).

This is one of the nicer things that I've seen with Drupal but done in an in-context C5 way. Idiot-proofing custom styled content for end users. Nice!
ThemeGoodness replied on at Permalink Reply
ThemeGoodness
I like this. This saves time in custom template work can just build the blocks themselves and style it. How much will it be in the marketplace?

Stephanie
jordanlev replied on at Permalink Reply
jordanlev
Free :)
triplei replied on at Permalink Reply
triplei
Wow, this is great and certainly saves a chunk of time when scaffolding out a custom block type. I was tempted to write a bash script to do something similar, but makes it even more straight forward.

Thanks again for putting this out there!
triplebox replied on at Permalink Reply
triplebox
This block is huge for Concrete5!! - But not so much in its present form I think as in the concept. I believe that it really deserves to be further developed by the community and perhaps put into the core or at least put into a "Developer's Core" status. I'm pretty sure that Drupal also has a very similar kind of plugin that developed along those lines.

All that being said, I installed this plugin, tested it, and had these thoughts instantly:

1. First: Awesome idea!
2. Need to add radio, select, textarea, email field options
3. Some basic options for the add/edit interface would be great:
A. Display: ie. Width for a textbox input, etc.
B. Validation: ie. Check to make sure is valid email address, etc.
4. It'd be nice to have an html/code input field (that's only used during the initial block-creation phase) for inserting code into view.php that's not tied to one particular field. For example, I wanted to do something like this:

<div class='outside_wrapper'> <--code input field output
  {input field #1 output}
  <div class='inside_wrapper'> <--code input field output
    {input field #2 output}
    {input field #3 output}
  </div> <--code input field output
  {input field #4 output}
  {input field #5 output}
</div> <--code input field output


5. Have an edit custom block mode (in addition to the creation mode that exists now) so that one could make minor modifications to previously created custom blocks without having to A. hack into them or B. making a new block from scratch and deleting the old one

Ok, so 2 last things:

1. I wish I was a Concrete5 guru already so I could take these suggestions and code them into reality. I'm trying to get there and I'll attempt to do what I can, but since I've already seen these type of functions in other blocks, I'm guessing that it wouldn't take too much for a true guru to pull off. This fully-functional block would be huge for the community!

2. Jordan: please don't think because of all my suggestions I'm unsatisfied with your work, rather it's because your idea is so innovative, that it has inspired alot of other ideas!
jordanlev replied on at Permalink Reply
jordanlev
Hi Joe,
Thank you for your comments -- I do appreciate them (and don't take offense at all).

That being said... I think you may be misunderstanding the purpose of this. It is not a form generator (there are already a few of those -- the built-in C5 "form" block, the "Extended Form" addon in the marketplace, and a couple of other ones floating around in the forums). So items 2, 3A, and 3B are not really applicable.

As for item 4, it already has that (the "prefix HTML" and "suffix HTML" for each field). In your example, you can just add "<div class='outside_wrapper'>" as the prefix for the first field, add "<div class='inside_wrapper'>" as either the suffix of the first field or the prefix of the 2nd field, etc. etc.
It's true that this might be a bit clunky (and I think that's what one of the earlier commenters had in mind when he suggested using a template language instead of structured fields), but it's only clunky for the 5 minutes you're configuring the block in the dashboard -- once it's made, the outputted HTML will look perfectly fine and "balanced".

Item 5 was definitely on my long-term list of "nice-to-have" features, but I didn't include it at first because of complications involving overwriting existing data (if the generated block has already been placed on a page). I'm not really sure how useful it would be anyway -- this thing should really only be used when you're first building out a site, before it's actually being used for entering content (the primary use case is that you already have a design and know exactly what you want certain pieces of content to look like, this just makes it easier to facilitate the entry of that content). Hence, I don't really see how re-creating the block and replacing the first one is that much of a burden. But those are just my thoughts -- please explain the use cases you had in mind if you disagree.

Thanks again.

-Jordan
kirkroberts replied on at Permalink Reply
kirkroberts
First of all (and again), I'm in awe of this undertaking. Jordan for President!

This may be presumptuous, but I disagree that this is not a form creator. In fact, I think that's *exactly* what it is. It creates a form that also happens to hook into the c5 block architecture.

Making a little block to structure data entry is all about the form. Otherwise we'd just let the client use the Content block and Layout tools. Perhaps that's an oversimplification, but I hope you see the point.

So I have to agree that I'd love to see the ability to add:
- textarea
- checkboxes
- radio
- select (dropdown)

With checkboxes, radio, and select, maybe the generator just sets it up with one default option, and it's up to the developer to go in and copy/paste options to build it out. That way the block creator wouldn't have to do the data wrangling. Just getting the starting code is the hard part, anyway!

Past those data types I think it gets dicey in terms of broad appeal and return-on-your-very-generous-investment.
jordanlev replied on at Permalink Reply
jordanlev
Oh, okay, I understand what you (and @triplebox) mean now by the form fields -- yes I wasn't thinking about the add/edit dialog (although I still don't understand how an email field would be useful in the edit dialog).

I actually had the idea for a dropdown menu in my original plans, but when I thought it through I realized a problem... what exactly would the dropdown DO? I mean, sure, there's a dropdown in the add/edit dialog (or a radio button or a checkbox), but how could you possibly tell the generator during the block creation process what each selection means / what action should be taken / etc.?
kirkroberts replied on at Permalink Reply
kirkroberts
> what exactly would the dropdown DO?

That's exactly why I think it would just be "I want a dropdown here" and that's it. The editor puts in a dropdown with one option with foo/bar as the key/value pair and sets up the dependencies with db.xml, etc... maybe prints the value in the view so the developer knows what code to use. Then it's up to the developer to add the options and any actions that happen depending on what values are selected.

So it isn't like the form block where you can input your options on separate lines. Although it could be, I guess... but I diverge from triplebox on the 92% / 7% +-1 ... I don't think it's up to the editor block to finish out these details. It's just a jumpstart.

In this case I think nailing it down will have sharply diminishing returns. This is a developer tool. Let the developers do the refining.
jordanlev replied on at Permalink Reply
jordanlev
Hmm... I feel like if someone knows what to do with the entered dropdown data then they know how to add a line to db.xml and add "<?php echo $form->select(...) ?>" to the edit.php file, so the benefit isn't that great (in my opinion -- I could be wrong though).
Also consider that having a dropdown (for example) in the dashboard UI comes at a cost of confusing people who don't know what to do with it -- they'll generate the block and then be like "what the heck does this thing do??".

Just my 2 cents.
kirkroberts replied on at Permalink Reply
kirkroberts
No matter what it will never be exactly right for everyone, so I guess you should do what makes sense to you and people can choose to use it or not. Otherwise you'll be bloating this thing out for eternity!

Even if you never touch it again it's still an incredibly valuable contribution, so thank you!
triplebox replied on at Permalink Reply
triplebox
I think kirkroberts already did a good job explaining about its role as a form creator, so I won't touch that again.

Concerning item #4, my whole point is that the code is tied to one specific field. What if field #1 & #2 are optional and there's no info inputted? Then what should be:

<div class='outside_wrapper'> 
  {input field #1 output}
  <div class='inside_wrapper'>
    {input field #2 output}
    {input field #3 output}
  </div>
  {input field #4 output}
  {input field #5 output}
</div>


ends up outputting just as:

{input field #3 output}
  </div>
  {input field #4 output}
  {input field #5 output}
</div>


That could really mess things up. So I think that having "prefix HTML" and "suffix HTML" for each field is awesome and shouldn't be replaced, but rather be complemented by an independent, code-input-field.

Really, the spirit of this plugin has such far-reaching implications, my view is why stop at 92% and then leave the last 7%? Might as well bring it that last stretch to perfection.

I know I speak as if coding all this added functionality is easy and quick - I really respect all the work you've done!
jordanlev replied on at Permalink Reply
jordanlev
Aha! Good point about #4 (I didn't think about that).

Not sure how that could be addressed cleanly in the UI... the straightforward method would be having 2 prefix/suffix boxes, one that is always shown and another that is only shown when the field is being outputted. But that would be so ugly. Or maybe text fields for entering HTML "in between" each of the field rows in the dashboard? I dunno, do you have any thoughts on how the dashboard UI could be structured to allow for this "in between" HTML?

In regards to "why stop at 92% and then leave the last 7%" -- please see the "90/90 Rule":http://en.wikipedia.org/wiki/Ninety-ninety_rule...
hursey013 replied on at Permalink Reply
hursey013
Hey all, keeping tabs on this thread too as it seems it could have a lot of potential. One clarification though, how is what you're trying to accomplish different than the data display block? That allows you to use a bunch of different form elements to input data that can be added as a block to a page - how does you approach differ?
Mnkras replied on at Permalink Reply
Mnkras
This literally makes a block... its not like editing a block it makes a brand new one
jordanlev replied on at Permalink Reply
jordanlev
Yeah, this is for facilitating better content entry for the people editing and maintaining the site -- it has nothing to do with normal site visitors (normal site visitors just see the resulting HTML).
hursey013 replied on at Permalink Reply
hursey013
Ok, just to clarify though, thats exactly what data display does. It allows site administrators to input a page's content into predefined inputs in the Dashboard, which in turn populate preformatted frontend pages that the end user will see.
jordanlev replied on at Permalink Reply
jordanlev
Interesting... Well I've never used the data display block before, but my understanding is that it's more for "database"-like data (kind of how Drupal's Views/CCK works).
Another difference (I think) is that the blocks created by this tool allow site administrators to edit content from the front-end just like any other block (as opposed to going to a dashboard page to edit content).

Good to know, though -- I'm still trying to formulate a decent marketplace description that makes it clear what this does and doesn't do, so that helps to have a point of comparison.
triplebox replied on at Permalink Reply
triplebox
I just demo'd Data Display and though I guess it can theoretically do the same thing, I had 2 reactions:

1. Data Display is not intuitive at all. When I used this Custom Block Builder, I instantly knew what to do. It's scope is focused (compared to Data Display) and very good at what it does.

2. Plugins that require paying $150 to use (you also need to buy the Advanced Forms for it to work) are not going to grow this community. I applaud Jordan for making something both awesome AND free. I'm inspired to contribute in like manner as soon as I get my concrete5-developing chops up.
triplebox replied on at Permalink Reply
triplebox
"Any thoughts on how the dashboard UI could be structured to allow for this "in between" HTML?"

-->I'm thinking it be an input field option among the others. so you would see:

[Textbox] [Image] [WYSIWYG Editor] [Code]

So in the dashboard UI they would behave like the other fields (can add, delete, move up/down etc.) but just w/out the prefix/suffix boxes of course.

The big difference would be how these these code fields are treated after the block is created. They wouldn't be displayed in the add/edit block UI, but rather just get printed as is in view.php. I don't think it'd be that complex to implement - that's what makes sense to me anyway. Perhaps an * after [Code] w/ a note would be in order for the dashboard UI.

Concerning the "92% / 7%":

1. I'm an idiot - I can't believe I left out 1% :-)
2. I get the concept of diminishing returns - I was just trying to express the feeling I had when I tested it of: "Man, it's almost there...but just not quite"
jordanlev replied on at Permalink Reply
jordanlev
That is a brilliant solution! I will definitely add that in.
Might even be able to get rid of the prefix/suffix HTML with that in there, which would greatly streamline the interface.

1. You didn't leave out 1%, you left out 81% :)
2. I feel the same way -- that's why I posted it here before the marketplace, so I could get some feedback and good ideas like this one.

Thanks.
Quaro replied on at Permalink Reply
Handing these cases is not a problem if you replace the suffix/prefix stuff with something that looks like the pseudo-output people are using as examples. I think the fact that everyone is already typing out pseudo-template output suggests that it is a natural fit.

<div class='outside_wrapper'> 
  {input field #1 output}
  <div class='inside_wrapper'>
    {input field #2 output}
    {input field #3 output}
  </div>
  {input field #4 output}
  {input field #5 output}
</div>


If Concrete were in Ruby I'd plug in a little template language, probably this one:http://www.liquidmarkup.org/ -- My PHP knowledge is very weak though -- anyone have a suggestion for a lightweight templaty thing like this in PHP?


Is one template field more complicated than a series of non-template fields? Judgement call I guess. My feelings is that typically I'll be pasting in some HTML into a field and then swapping out the content into little template variables. Easier to do in a text field than breaking the output into little pieces.
jordanlev replied on at Permalink Reply
jordanlev
Good points. I will think about this.

BTW, what I meant by "more complication" was that it would be more complicated to code up all of the validation in the back-end of the generator UI itself -- yes, separate fields are a little more annoying, but they guarantee consistent data entry.

As for templating languages, I don't think bringing in another dependency is needed -- it would just be simple token replacement.
jordanlev replied on at Permalink Reply
jordanlev
I've put the code up on github:
https://github.com/jordanlev/c5_designer_content...

(If you want to contribute but don't know how to use git, that's fine -- you can just send me updated code and I can roll it in).
Tao replied on at Permalink Reply
Tao
Thank you.
I will check now.
Tao replied on at Permalink Reply
Tao
"/language" Please add.
All Japanese users is waiting for it.
jordanlev replied on at Permalink Reply
jordanlev
Sorry for the delay, I haven't had time to work on this again much (just responding to forum threads here and there).

I promise that it will include the Japanese translation before I submit it to the marketplace.
Tao replied on at Permalink Reply
Tao
Thank you.
This would be translated into other languages ​​should be.
richardbrowning replied on at Permalink Reply
Message withdrawn, will experiment more before submitting some new queries.
jordanlev replied on at Permalink Reply
jordanlev
Glad you figured it out. Just for future reference:
This is currently not in a complete or final version. I *will* be submitting it to the marketplace sooner or later, where it will have translations and better instructions and be easier to install and have some examples of how to use it.

If you're not familiar enough yet with Concrete5 to know how to install a package or have an idea of how blocks are made, it's probably best to just wait a little bit until it's available on the marketplace (maybe a week or two?).

-Jordan
jordanlev replied on at Permalink Reply
jordanlev
[EDIT: I remove the attachements and have a new, single .po file available, see further down in this thread]

Okay, I have updated the package to the point where I'm about ready to submit it to the marketplace.

I am attaching 2 files for translations:
1) dashboard_messages.zip contains messages for the package dashboard interface
2) generated_block_messages.zip contains messages that will need to be included in the blocks that you create.

Post back any translations you want to provide.

Thank you.

PS - My heart goes out to members of the Japanese Concrete5 community. I am sorry to hear about the terrible ordeals you are having there. I hope that you (and your friends and families) are okay.
jordanlev replied on at Permalink Reply
jordanlev
Questions for anyone who knows how translations work in C5 (because I don't really):

How C5 handles these language files when it's a block that's just in the blocks directory (not inside a package)? Can I just include a languages subdirectory in the blocks directory, or will it only pick them up from the site's top-level languages directory?

Also, how can I determine what the current language being used is? Seems like it would be a waste to include all translation files with every generated block -- might be more efficient to only include the one that corresponds to the "current" language that's being used when the block is generated from the dashboard.

Thank you.

-Jordan
Tao replied on at Permalink Reply
Tao
I think a great idea.

Language directory should be language directory in package directory.

exsample:
packages
-languages
--en
--ja_JP.UTF8

A block created by this add-on be translated from global language file.
So you don't worry how translate a block created by this addon.

You can find in svn what language files exist.
http://svn.concrete5.org/svn/concrete5-i18n/...

And, A member of japanese user use this add-on and created "Google Person Finder Block" for earthquake in Japan. (Thank you build1024)
http://c5life.my-sv.net/customize/person_finder/...
cgrauer replied on at Permalink Reply 1 Attachment
cgrauer
First of all: great job! I love this addon, it's virtualizing c5's functions and opens up a new level of functionality! I missed such thing already several times and was forced to manually create blocktypes just for two or three fields to display. Thanks!

One comment to the terminology: on reading your description I didn't understand what designer_content does. As I installed it I knew why: it doesn't really create blocks but rather block-types! Perhaps you should make this clear...

Localization works only on a per package-level. But I think this is no problem:
1. Whoever uses designer_content to create blocktypes individually, uses his/her language and will not need translation.
2. If you need to have some general things beeing translated for the blocks (let's say you write some thing like "blocktype created with designer_content" on the add/edit-dialog of each blocktype created with d_c ...), you can put these phrases into your package and they will used also with blocks outside the package (all translation data will be used everywhere! It's loaded all together on startup...)

The current Language is stored in the global variable LOCALE (a string like "de_DE" or "en_US"...). But you don't have to integrate anything. However, only the current language files are loaded!

As a contribution you find attached a german translation for your package.
cgrauer replied on at Permalink Reply 1 Attachment
cgrauer
Sorry, take this one (language file...), it's cleaned up. The other file was messed from some testing I did with it...
jordanlev replied on at Permalink Reply
jordanlev
Hi Christian,
Thank you for your answers and the German translation -- much appreciated!

I'm curious about translated phrases being used outside the package -- how does this work when there are conflicts? For example, what if the same phrase is defined in C5 core and also in 2 other packages? Which version is used?

Can you also please provide a german translation for the other .po file I have ("generated block messages"). There is a little bit of translation needed for the add.php and edit.php forms -- not the labels (because those are entered by you in the dashboard), but for some of the controls and validation messages. For example, when you include an image selection control in add.php or edit.php, there is a box that you click to bring up the file manager, and that box says something like "Click here to select an image".

One more question: what is the ".mo" file for? Is this something that I need to give to you BEFORE translation, or is it something I generate from your .po file AFTER you have translated it?

Thanks again for your great help!

-Jordan
Mnkras replied on at Permalink Reply
Mnkras
I believe the Package and Core translations are totally separate, the po file is editable where the mo file is the compiled po file that is not editable and is used by gettext
jordanlev replied on at Permalink Reply
jordanlev
Thanks Mike, but unfortunately that knowledge doesn't address my actual problem. If you could provide a little more info, that would be great. Specifically...

So package and core translations are separate -- what does that mean if I have a block that is NOT in a package and it requires a string translation? Does it look to core or to all of the packages?

And do I need to generate the .mo file before handing off the .po file to the translators or do I generate the .mo file from the .po that I get back from the translators? The reason I ask is because when I use the PoEdit program to generate the empty messages files for my package, it gives me both a .po and a .mo file -- so I'm wondering if that's just a useless .mo file at this point and I should trash it, or if it's something I need to send to the translators (BEFORE translation) along with the .po file?

Thanks!

-Jordan
Mnkras replied on at Permalink Reply
Mnkras
im not totally sure, gettext blows my mind,

what you do is it will look for a function that you specify (normal gettext is _ so _() but concrete5 uses t, t())

so after you have put t() around all your strings, you can generate a po file
so as an example
// are comments made by me
#: somefile.php:36 //file and line number
msgid "My name is %s.\n" //in concrete5 this would be t('My name is %s.\n', $name);
msgstr "Mi nombre es %s.\n" //if a language is specified this string is loaded in this example its spanish


you would distribute the po file to people to edit, as they can't read or edit the mo file making it useless to translate.

Hope i made this a bit clearer.

Mike
jordanlev replied on at Permalink Reply
jordanlev
No, my specific question is how you specify translations for a block that exists in the /blocks/ directory (NOT inside a package) -- does just the mere existence of a translation in the package make it available to anything in the whole system (like a block that is in the site's top-level blocks directory but not in that package's directory), or are package translations only available to files within that package itself?
cgrauer replied on at Permalink Reply
cgrauer
Hi Jordan,

this is how you can imagine the "black box" that does translation (its not this simple in reality, but this is what you need to understand the way it works...):

on startup (i.e. on every page request) c5 loads all language files for the configured language (say it's german 'de_DE'). First the one of the system, later those of all packages. Language files are just lists with two colums: 1. english text, 2. german text. Entries in later files overwrite existing ones! Now, an object is created containing those lists and providing the function t() that converts input text from english to german, searching the text in colum 1 and retrieving the text from colum 2. Thats all.

The language files are the so called "mo-Files" (e.g. messages.mo), containing the translation list described above in a special encoding. They reside in the path languages/de_DE/LC_MESSAGES/ for the system translation and in /package/packagename/languages/de_DE/LC_MESSAGES/ for the package translation. languages is the convention by c5. de_DE is the region code (here german_Germany), LC_MESSAGE refers to the type of localization objects that php konws (see setlocale() for more info, for c5 just memorize this path...).
Attention: in the system language path, c5 takes every *.mo-File it can find, no matter what filename it has!! in the package language paths it reads only the file called messages.mo!!

The translation, as I already told, works all over the whole system. The different files are combined to one single datapool and every message created using t() is translated with this data, no matter if it's in a package, in a blocktype, in a theme or in a core file!

The .po file is the original, text based, unencoded version of the mo-file, the one being edited. You may edit it manually or with an appropriate editor (I use Poedit, it's very popular). C5 does not need the po-file, it uses only the mo-file. But I always put both in the packages to have them all where they belong to. Also Poedit stores them together.

So if you want to make your package translatable, it's mandatory that you use t() for text outputs. Poedit has a function to automatically search for all t() statements, extract the phrases and build the po-file. You may do this your self and publish this po-file with your package. Translators will translate the phrases and store it as po and optionally as mo file. Take the mo file (and the po file) and put it in your package or just offer it for download if you want.

This is what you need to know about translation to make your packages ready for globalization ;-)

Now to your "generated block messages" - you say you have a po-file for it?? Where do I find it? To get generated block messages translated you may just generate the t()-statements (e.g. like this:
$code .= '<?php echo t("block message"); ?>';
So it will not be translated on generation, but on using the blocktype. Poedit will find it all the same and put it in the mo file. As all mo files are merged in c5 the block will display the translation. And the block will be translated also if the language is changed after it is generated! And finally you need only one po/mo-file.
cgrauer replied on at Permalink Reply
cgrauer
To get things translated for later use, you may also define a function that just calls t() with anything you want to be translated. Although this function will never be called, Poedit will find the phrases and put them into the po/mo-files.
jordanlev replied on at Permalink Reply
jordanlev
Christian,
This is an EXCELLENT explanation -- thank you so much! So all of the messages are global and I don't need to worry about creating the .mo file until after I get the translated .po files back. Perfect, makes my job a lot easier!

I will post another updated .po file that contains ALL of the messages (both for the dashboard and for the generated blocks) below -- so it's the same as the last one except for a few new strings at the bottom. If you could be so kind as to provide german translations for this, that would be great.

Thank you again.

-Jordan
jordanlev replied on at Permalink Reply
jordanlev
[translation file removed -- out of date]
cgrauer replied on at Permalink Reply
cgrauer
You'll get the translation tomorrow!

One detail is missing in my explanation: besides mo and po there is also a pot file. It is somehow a po-template, i.e. a po file containing only the original phrases, independantly from any specific destination language. But it's in the same format as the po files. So what you posted here would be a pot file: essentially the po-file without translations.

This is important if you update your package and need more phrases. You just update the pot-file, give it to your translators and they merge the new phrases into the existing po-files and only have to translate the new phrases.
cgrauer replied on at Permalink Reply 1 Attachment
cgrauer
Ok, here we are. In Germany it's already tomorrow... ;-)
jordanlev replied on at Permalink Reply
jordanlev
You're the man! I realized I left a string out -- you don't need to redo the file, I can put it in if you can just reply with a translation for the following phrase:
Are you sure?
kino replied on at Permalink Reply
kino
If you do not need multi-lingual sites
If I use slightly modified versions of add-on below.

http://www.concrete5.org/community/forums/internationalization/andq...
cgrauer replied on at Permalink Reply 1 Attachment
cgrauer
Sind Sie sicher?
jordanlev replied on at Permalink Reply
jordanlev
This package is now available in the marketplace:
http://www.concrete5.org/marketplace/addons/designer-content/...
Tony replied on at Permalink Reply
Tony
wow, blows my mind some of the cool packages people are coming up with lately. thanks Jordan!
Resonate replied on at Permalink Reply
Hi.
is it possible to add a picture gallery in some way?
jordanlev replied on at Permalink Reply
jordanlev
No, but I have some code and an explanatory blog post that show you how to do that:http://c5blog.jordanlev.com/blog/2011/12/build-a-slideshow-block/...

In the future, note that it's best to post questions about Designer Content to its marketplace forum page (go to the marketplace page and click "Forums" in the sidebar) -- this post here was really for discussion of the pre-release version last year.

Good luck with your gallery!

-Jordan
nesoor replied on at Permalink Reply
nesoor
Thank you for sharing this addon!